+ /**
+ * Add a new `auto-draft` post.
+ *
+ * @access public
+ * @since 4.7.0
+ *
+ * @param array $postarr {
+ * Post array. Note that post_status is overridden to be `auto-draft`.
+ *
+ * @var string $post_title Post title. Required.
+ * @var string $post_type Post type. Required.
+ * @var string $post_name Post name.
+ * @var string $post_content Post content.
+ * }
+ * @return WP_Post|WP_Error Inserted auto-draft post object or error.
+ */
+ public function insert_auto_draft_post( $postarr ) {
+ if ( ! isset( $postarr['post_type'] ) || ! post_type_exists( $postarr['post_type'] ) ) {
+ return new WP_Error( 'unknown_post_type', __( 'Unknown post type' ) );
+ }
+ if ( empty( $postarr['post_title'] ) ) {
+ return new WP_Error( 'empty_title', __( 'Empty title' ) );
+ }
+ if ( ! empty( $postarr['post_status'] ) ) {
+ return new WP_Error( 'status_forbidden', __( 'Status is forbidden' ) );
+ }
+
+ $postarr['post_status'] = 'auto-draft';
+
+ // Auto-drafts are allowed to have empty post_names, so it has to be explicitly set.
+ if ( empty( $postarr['post_name'] ) ) {
+ $postarr['post_name'] = sanitize_title( $postarr['post_title'] );
+ }
+ if ( ! isset( $postarr['meta_input'] ) ) {
+ $postarr['meta_input'] = array();
+ }
+ $postarr['meta_input']['_customize_draft_post_name'] = $postarr['post_name'];
+ unset( $postarr['post_name'] );
+
+ add_filter( 'wp_insert_post_empty_content', '__return_false', 1000 );
+ $r = wp_insert_post( wp_slash( $postarr ), true );
+ remove_filter( 'wp_insert_post_empty_content', '__return_false', 1000 );
+
+ if ( is_wp_error( $r ) ) {
+ return $r;
+ } else {
+ return get_post( $r );
+ }
+ }
+
+ /**
+ * Ajax handler for adding a new auto-draft post.
+ *
+ * @access public
+ * @since 4.7.0
+ */
+ public function ajax_insert_auto_draft_post() {
+ if ( ! check_ajax_referer( 'customize-menus', 'customize-menus-nonce', false ) ) {
+ wp_send_json_error( 'bad_nonce', 400 );
+ }
+
+ if ( ! current_user_can( 'customize' ) ) {
+ wp_send_json_error( 'customize_not_allowed', 403 );
+ }
+
+ if ( empty( $_POST['params'] ) || ! is_array( $_POST['params'] ) ) {
+ wp_send_json_error( 'missing_params', 400 );
+ }
+
+ $params = wp_unslash( $_POST['params'] );
+ $illegal_params = array_diff( array_keys( $params ), array( 'post_type', 'post_title' ) );
+ if ( ! empty( $illegal_params ) ) {
+ wp_send_json_error( 'illegal_params', 400 );
+ }
+
+ $params = array_merge(
+ array(
+ 'post_type' => '',
+ 'post_title' => '',
+ ),
+ $params
+ );
+
+ if ( empty( $params['post_type'] ) || ! post_type_exists( $params['post_type'] ) ) {
+ status_header( 400 );
+ wp_send_json_error( 'missing_post_type_param' );
+ }
+
+ $post_type_object = get_post_type_object( $params['post_type'] );
+ if ( ! current_user_can( $post_type_object->cap->create_posts ) || ! current_user_can( $post_type_object->cap->publish_posts ) ) {
+ status_header( 403 );
+ wp_send_json_error( 'insufficient_post_permissions' );
+ }
+
+ $params['post_title'] = trim( $params['post_title'] );
+ if ( '' === $params['post_title'] ) {
+ status_header( 400 );
+ wp_send_json_error( 'missing_post_title' );
+ }
+
+ $r = $this->insert_auto_draft_post( $params );
+ if ( is_wp_error( $r ) ) {
+ $error = $r;
+ if ( ! empty( $post_type_object->labels->singular_name ) ) {
+ $singular_name = $post_type_object->labels->singular_name;
+ } else {
+ $singular_name = __( 'Post' );
+ }
+
+ $data = array(
+ /* translators: %1$s is the post type name and %2$s is the error message. */
+ 'message' => sprintf( __( '%1$s could not be created: %2$s' ), $singular_name, $error->get_error_message() ),
+ );
+ wp_send_json_error( $data );
+ } else {
+ $post = $r;
+ $data = array(
+ 'post_id' => $post->ID,
+ 'url' => get_permalink( $post->ID ),
+ );
+ wp_send_json_success( $data );
+ }
+ }
+