/**
  * Test override post date if empty.
  *
  * @covers CustomizeSnapshots\Customize_Snapshot_Manager::override_post_date_default_data()
  */
 public function test_override_post_date_default_data()
 {
     $post_id = $this->factory()->post->create();
     $post = get_post($post_id);
     $post->post_date = $post->post_date_gmt = $post->post_modified = $post->post_modified_gmt = '0000-00-00 00:00:00';
     $this->manager->override_post_date_default_data($post);
     $this->assertNotEquals($post->post_date, '0000-00-00 00:00:00');
     $this->assertNotEquals($post->post_date_gmt, '0000-00-00 00:00:00');
     $this->assertNotEquals($post->post_modified, '0000-00-00 00:00:00');
     $this->assertNotEquals($post->post_modified_gmt, '0000-00-00 00:00:00');
 }
コード例 #2
0
 /**
  * Initial loader.
  *
  * @access public
  *
  * @throws Exception If the UUID is invalid.
  *
  * @param Customize_Snapshot_Manager $snapshot_manager     Customize snapshot bootstrap instance.
  * @param string                     $uuid                 Snapshot unique identifier.
  */
 public function __construct(Customize_Snapshot_Manager $snapshot_manager, $uuid)
 {
     $this->snapshot_manager = $snapshot_manager;
     $this->data = array();
     if (!Customize_Snapshot_Manager::is_valid_uuid($uuid)) {
         throw new Exception(__('You\'ve entered an invalid snapshot UUID.', 'customize-snapshots'));
     }
     $this->uuid = $uuid;
     $post = $this->post();
     if ($post) {
         $this->data = $this->snapshot_manager->post_type->get_post_content($post);
     }
 }
 /**
  * Test create item.
  */
 function test_create_item()
 {
     wp_set_current_user($this->factory()->user->create(array('role' => 'administrator')));
     $request = new \WP_REST_Request('POST', '/wp/v2/customize_snapshots');
     $request->set_param('content', array('blogname' => array('value' => 'test')));
     $request->set_param('slug', Customize_Snapshot_Manager::generate_uuid());
     $response = $this->server->dispatch($request);
     $this->assertErrorResponse('rest_cannot_create', $response);
 }
 /**
  * Helper function to make the Ajax call directy to `Customize_Snapshot_Manager::save_snapshot`.
  *
  * @see Customize_Snapshot_Manager::save_snapshot()
  */
 function make_save_snapshot_ajax_call()
 {
     try {
         ini_set('implicit_flush', false);
         ob_start();
         $manager = new Customize_Snapshot_Manager($this->plugin);
         $manager->publish_snapshot_with_customize_save_after();
         $buffer = ob_get_clean();
         if (!empty($buffer)) {
             $this->_last_response = $buffer;
         }
     } catch (\WPAjaxDieContinueException $e) {
         unset($e);
     }
 }
コード例 #5
0
 /**
  * Initiate the plugin resources.
  *
  * Priority is 8 because \CustomizeWidgetsPlus\Widget_Posts::init() happens
  * at priority 9, and this calls \CustomizeWidgetsPlus\Widget_Posts::add_customize_hooks().
  * So we need priority 8 so that the Customizer will be initialized before Widget Posts
  * initializes.
  *
  * @action after_setup_theme, 8
  */
 public function init()
 {
     $this->customize_snapshot_manager = new Customize_Snapshot_Manager($this);
     $this->customize_snapshot_manager->init();
 }
コード例 #6
0
 /**
  * Publish snapshot changes when snapshot post is being published.
  *
  * The logic in here is the inverse of to publish_snapshot_with_customize_save_after.
  *
  * The meat of the logic that manipulates the post_content and validates the settings
  * needs to be done in wp_insert_post_data filter in like a
  * filter_insert_post_data_to_validate_published_snapshot method? This would
  * have the benefit of reducing one wp_insert_post() call.
  *
  * @todo Consider using wp_insert_post_data to prevent double calls to wp_insert_post().
  * @see Customize_Snapshot_Manager::publish_snapshot_with_customize_save_after()
  *
  * @param string   $new_status New status.
  * @param string   $old_status Old status.
  * @param \WP_Post $post       Post object.
  * @return bool Whether the settings were saved.
  */
 public function save_settings_with_publish_snapshot($new_status, $old_status, $post)
 {
     // Abort if not transitioning a snapshot post to publish from a non-publish status.
     if (Post_Type::SLUG !== $post->post_type || 'publish' !== $new_status || $new_status === $old_status) {
         return false;
     }
     $this->ensure_customize_manager();
     if ($this->doing_customize_save_ajax()) {
         // Short circuit because customize_save ajax call is changing status.
         return false;
     }
     if (!did_action('customize_register')) {
         /*
          * When running from CLI or Cron, we have to remove the action because
          * it will get added with a default priority of 10, after themes and plugins
          * have already done add_action( 'customize_register' ), resulting in them
          * being called first at the priority 10. So we manually call the
          * prerequisite function WP_Customize_Manager::register_controls() and
          * remove it from being called when the customize_register action fires.
          */
         remove_action('customize_register', array($this->customize_manager, 'register_controls'));
         $this->customize_manager->register_controls();
         /*
          * Unfortunate hack to prevent \WP_Customize_Widgets::customize_register()
          * from calling preview() on settings. This needs to be cleaned up in core.
          * It is important for previewing to be prevented because if an option has
          * a filter it will short-circuit when an update is attempted since it
          * detects that there is no change to be put into the DB.
          * See: https://github.com/xwp/wordpress-develop/blob/e8c58c47db1421a1d0b2afa9ad4b9eb9e1e338e0/src/wp-includes/class-wp-customize-widgets.php#L208-L217
          */
         if (!defined('DOING_AJAX')) {
             define('DOING_AJAX', true);
         }
         $_REQUEST['action'] = 'customize_save';
         /** This action is documented in wp-includes/class-wp-customize-manager.php */
         do_action('customize_register', $this->customize_manager);
         // undefine( 'DOING_AJAX' )... just kidding. This is the end of the unfortunate hack and it should be fixed in Core.
         unset($_REQUEST['action']);
     }
     $snapshot_content = $this->post_type->get_post_content($post);
     if (method_exists($this->customize_manager, 'validate_setting_values')) {
         /** This action is documented in wp-includes/class-wp-customize-manager.php */
         do_action('customize_save_validation_before', $this->customize_manager);
     }
     $setting_ids = array_keys($snapshot_content);
     $this->customize_manager->add_dynamic_settings($setting_ids);
     /** This action is documented in wp-includes/class-wp-customize-manager.php */
     do_action('customize_save', $this->customize_manager);
     /**
      * Settings to save.
      *
      * @var \WP_Customize_Setting[]
      */
     $settings = array();
     $publish_error_count = 0;
     foreach ($snapshot_content as $setting_id => &$setting_params) {
         // Missing value error.
         if (!isset($setting_params['value']) || is_null($setting_params['value'])) {
             if (!is_array($setting_params)) {
                 if (!empty($setting_params)) {
                     $setting_params = array('value' => $setting_params);
                 } else {
                     $setting_params = array();
                 }
             }
             $setting_params['publish_error'] = 'null_value';
             $publish_error_count += 1;
             continue;
         }
         // Unrecognized setting error.
         $this->customize_manager->set_post_value($setting_id, $setting_params['value']);
         $setting = $this->customize_manager->get_setting($setting_id);
         if (!$setting instanceof \WP_Customize_Setting) {
             $setting_params['publish_error'] = 'unrecognized_setting';
             $publish_error_count += 1;
             continue;
         }
         // Validate setting value.
         if (method_exists($setting, 'validate')) {
             $validity = $setting->validate($setting_params['value']);
             if (is_wp_error($validity)) {
                 $setting_params['publish_error'] = $validity->get_error_code();
                 $publish_error_count += 1;
                 continue;
             }
         }
         // Validate sanitized setting value.
         $sanitized_value = $setting->sanitize($setting_params['value']);
         if (is_null($sanitized_value) || is_wp_error($sanitized_value)) {
             $setting_params['publish_error'] = is_wp_error($sanitized_value) ? $sanitized_value->get_error_code() : 'invalid_value';
             $publish_error_count += 1;
             continue;
         }
         $settings[] = $setting;
         unset($setting_params['publish_error']);
     }
     // Handle error scenarios.
     if ($publish_error_count > 0) {
         $update_setting_args = array('ID' => $post->ID, 'post_content' => Customize_Snapshot_Manager::encode_json($snapshot_content), 'post_status' => 'pending');
         wp_update_post(wp_slash($update_setting_args));
         update_post_meta($post->ID, 'snapshot_error_on_publish', $publish_error_count);
         add_filter('redirect_post_location', function ($location) {
             $location = add_query_arg('snapshot_error_on_publish', '1', $location);
             return $location;
         });
         return false;
     }
     /*
      * Change all setting capabilities temporarily to 'exist' to allow them to
      * be saved regardless of current user, such as when WP-Cron is publishing
      * the snapshot post if it was scheduled. It is safe to do this because
      * a setting can only be written into a snapshot by users who have the
      * capability, so after it has been added to a snapshot it is good to commit.
      */
     $existing_caps = wp_list_pluck($settings, 'capability');
     foreach ($settings as $setting) {
         $setting->capability = 'exist';
     }
     // Persist the settings in the DB.
     foreach ($settings as $setting) {
         $setting->save();
     }
     // Restore setting capabilities.
     foreach ($existing_caps as $setting_id => $existing_cap) {
         $settings[$setting_id]->capability = $existing_cap;
     }
     /** This action is documented in wp-includes/class-wp-customize-manager.php */
     do_action('customize_save_after', $this->customize_manager);
     // Remove any previous error on setting.
     delete_post_meta($post->ID, 'snapshot_error_on_publish');
     return true;
 }
コード例 #7
0
 /**
  * Test that the snapshot object is passed as the second filter param.
  *
  * @see Customize_Snapshot::save()
  */
 function test_filter_customize_snapshot_save()
 {
     $manager = new Customize_Snapshot_Manager($this->plugin);
     $manager->ensure_customize_manager();
     $manager->init();
     $snapshot = new Customize_Snapshot($manager, self::UUID);
     $that = $this;
     // For PHP 5.3.
     add_filter('customize_snapshot_save', function ($data, $test_snapshot) use($that) {
         $that->filtered_snapshot = $test_snapshot;
         return $data;
     }, 10, 2);
     $snapshot->save(array('uuid' => self::UUID, 'data' => array('foo' => array('value' => 'bar'))));
     $this->assertEquals($snapshot, $this->filtered_snapshot);
 }
コード例 #8
0
 /**
  * Snapshot publish.
  *
  * @see Post_Type::save()
  */
 function test_publish_snapshot()
 {
     $admin_user_id = $this->factory()->user->create(array('role' => 'administrator'));
     wp_set_current_user($admin_user_id);
     $post_type = get_plugin_instance()->customize_snapshot_manager->post_type;
     $post_type->register();
     $tag_line = 'Snapshot blog';
     $data = array('blogdescription' => array('value' => $tag_line), 'foo' => array('value' => 'bar'), 'baz' => array('value' => null));
     $validated_content = array('blogdescription' => array('value' => $tag_line), 'foo' => array('value' => 'bar', 'publish_error' => 'unrecognized_setting'), 'baz' => array('value' => null, 'publish_error' => 'null_value'));
     /*
      * Ensure that directly updating a post succeeds with invalid settings
      * works because the post is a draft. Note that if using
      * Customize_Snapshot::set() this would fail because it does validation.
      */
     $post_id = $post_type->save(array('uuid' => Customize_Snapshot_Manager::generate_uuid(), 'data' => $data, 'status' => 'draft'));
     wp_update_post(array('ID' => $post_id, 'post_status' => 'draft'));
     $content = $post_type->get_post_content(get_post($post_id));
     $this->assertEquals($data, $content);
     /*
      * Ensure that attempting to publish a snapshot with invalid settings
      * will get the publish_errors added as well as kick it back to pending.
      */
     remove_all_filters('redirect_post_location');
     $post_id = $post_type->save(array('uuid' => Customize_Snapshot_Manager::generate_uuid(), 'data' => $data, 'status' => 'draft'));
     wp_publish_post($post_id);
     $snapshot_post = get_post($post_id);
     $content = $post_type->get_post_content($snapshot_post);
     $this->assertEquals('pending', $snapshot_post->post_status);
     $this->assertEquals($validated_content, $content);
     $this->assertContains('snapshot_error_on_publish=1', apply_filters('redirect_post_location', get_edit_post_link($snapshot_post->ID), $snapshot_post->ID));
     /*
      * Remove invalid settings and now attempt publish.
      */
     remove_all_filters('redirect_post_location');
     unset($data['foo']);
     unset($data['baz']);
     $post_id = $post_type->save(array('uuid' => Customize_Snapshot_Manager::generate_uuid(), 'data' => $data, 'status' => 'draft'));
     wp_publish_post($post_id);
     $snapshot_post = get_post($post_id);
     $content = $post_type->get_post_content($snapshot_post);
     $this->assertEquals('publish', $snapshot_post->post_status);
     $this->assertEquals($data, $content);
     $this->assertEquals($tag_line, get_bloginfo('description'));
     $this->assertNotContains('snapshot_error_on_publish=1', apply_filters('redirect_post_location', get_edit_post_link($snapshot_post->ID), $snapshot_post->ID));
 }
コード例 #9
0
 /**
  * Persist the data in the snapshot post content.
  *
  * @param array $args Args.
  * @return int|\WP_Error Post ID for snapshot or WP_Error instance.
  */
 public function save(array $args)
 {
     // @todo Add support for $args['post_id'].
     if (empty($args['uuid']) || !Customize_Snapshot_Manager::is_valid_uuid($args['uuid'])) {
         return new \WP_Error('missing_valid_uuid');
     }
     $post_arr = array('post_name' => $args['uuid'], 'post_title' => $args['uuid'], 'post_type' => static::SLUG, 'meta_input' => array('_snapshot_version' => $this->snapshot_manager->plugin->version));
     if (!empty($args['status'])) {
         if (isset($args['post_date'], $args['edit_date'], $args['post_date_gmt'])) {
             $post_arr['post_date'] = $args['post_date'];
             $post_arr['edit_date'] = $args['edit_date'];
             $post_arr['post_date_gmt'] = $args['post_date_gmt'];
         }
         if (!get_post_status_object($args['status'])) {
             return new \WP_Error('bad_status');
         }
         $post_arr['post_status'] = $args['status'];
     }
     $post_id = $this->find_post($args['uuid']);
     $is_update = !empty($post_id);
     if ($post_id) {
         $post_arr['ID'] = $post_id;
     }
     if (isset($args['data'])) {
         if (!is_array($args['data'])) {
             return new \WP_Error('missing_data');
         }
         foreach ($args['data'] as $setting_id => $setting_params) {
             if (!is_array($setting_params)) {
                 return new \WP_Error('bad_setting_params');
             }
             if (!array_key_exists('value', $setting_params)) {
                 return new \WP_Error('missing_value_param');
             }
         }
         $post_arr['post_content'] = Customize_Snapshot_Manager::encode_json($args['data']);
     } elseif (!$is_update) {
         $post_arr['post_content'] = Customize_Snapshot_Manager::encode_json(array());
     }
     if (!empty($args['theme'])) {
         $post_arr['meta_input']['_snapshot_theme'] = $args['theme'];
     }
     if (!empty($args['author'])) {
         $post_arr['post_author'] = $args['author'];
     }
     if (!empty($args['date_gmt'])) {
         $post_arr['post_date_gmt'] = $args['date_gmt'];
     }
     $this->suspend_kses();
     if ($is_update) {
         $r = wp_update_post(wp_slash($post_arr), true);
     } else {
         $r = wp_insert_post(wp_slash($post_arr), true);
     }
     $this->restore_kses();
     return $r;
 }