Beispiel #1
0
/**
 * Hook into the delete_term action and make sure any meta is also delete
 * @param int $term_id
 */
function delete_term_meta_when_term_is_deleted($term_id)
{
    global $wpdb;
    $term_meta_ids = $wpdb->get_col($wpdb->prepare("SELECT meta_id FROM {$wpdb->termmeta} WHERE term_id = %d ", $term_id));
    foreach ($term_meta_ids as $mid) {
        delete_metadata_by_mid('term', $mid);
    }
}
Beispiel #2
0
 function test_delete_metadata_by_mid()
 {
     // Let's try and delete a non-existing ID, non existing meta
     $this->assertFalse(delete_metadata_by_mid('user', 0));
     $this->assertFalse(delete_metadata_by_mid('non_existing_meta', $this->delete_meta_id));
     // Now let's delete the real meta data
     $this->assertTrue(delete_metadata_by_mid('user', $this->delete_meta_id));
     // And make sure it's been deleted
     $this->assertFalse(get_metadata_by_mid('user', $this->delete_meta_id));
     // Make sure the caches are cleared
     $this->assertFalse((bool) get_user_meta($this->author->ID, 'delete_meta_key'));
 }
Beispiel #3
0
 public function delete()
 {
     global $wpdb;
     //Delete cache
     wp_cache_delete($this->reaction_id, 'post_reactions');
     //Delete meta
     $reaction_meta_ids = $wpdb->get_col($wpdb->prepare("SELECT meta_id FROM {$wpdb->reactionmeta} WHERE reaction_id = %d ", $this->reaction_id));
     foreach ($reaction_meta_ids as $mid) {
         delete_metadata_by_mid('reaction', $mid);
     }
     //Delete db row
     return (bool) $wpdb->delete($wpdb->reactions, array('reaction_id' => $this->reaction_id));
 }
 /**
  * Decrease usage count fo current coupon.
  *
  * @access public
  * @param  string $used_by Either user ID or billing email
  * @return void
  */
 public function dcr_usage_count($used_by = '')
 {
     global $wpdb;
     $this->usage_count--;
     update_post_meta($this->id, 'usage_count', $this->usage_count);
     // Delete 1 used by meta
     $meta_id = $wpdb->get_var($wpdb->prepare("SELECT meta_id FROM {$wpdb->postmeta} WHERE meta_key = '_used_by' AND meta_value = %s AND post_id = %d LIMIT 1;", $used_by, $this->id));
     if ($meta_id) {
         delete_metadata_by_mid('post', $meta_id);
     }
 }
Beispiel #5
0
/**
 * Trash or delete an attachment.
 *
 * When an attachment is permanently deleted, the file will also be removed.
 * Deletion removes all post meta fields, taxonomy, comments, etc. associated
 * with the attachment (except the main post).
 *
 * The attachment is moved to the trash instead of permanently deleted unless trash
 * for media is disabled, item is already in the trash, or $force_delete is true.
 *
 * @since 2.0.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param int  $post_id      Attachment ID.
 * @param bool $force_delete Optional. Whether to bypass trash and force deletion.
 *                           Default false.
 * @return mixed False on failure. Post data on success.
 */
function wp_delete_attachment($post_id, $force_delete = false)
{
    global $wpdb;
    if (!($post = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->posts} WHERE ID = %d", $post_id)))) {
        return $post;
    }
    if ('attachment' != $post->post_type) {
        return false;
    }
    if (!$force_delete && EMPTY_TRASH_DAYS && MEDIA_TRASH && 'trash' != $post->post_status) {
        return wp_trash_post($post_id);
    }
    delete_post_meta($post_id, '_wp_trash_meta_status');
    delete_post_meta($post_id, '_wp_trash_meta_time');
    $meta = wp_get_attachment_metadata($post_id);
    $backup_sizes = get_post_meta($post->ID, '_wp_attachment_backup_sizes', true);
    $file = get_attached_file($post_id);
    if (is_multisite()) {
        delete_transient('dirsize_cache');
    }
    /**
     * Fires before an attachment is deleted, at the start of wp_delete_attachment().
     *
     * @since 2.0.0
     *
     * @param int $post_id Attachment ID.
     */
    do_action('delete_attachment', $post_id);
    wp_delete_object_term_relationships($post_id, array('category', 'post_tag'));
    wp_delete_object_term_relationships($post_id, get_object_taxonomies($post->post_type));
    // Delete all for any posts.
    delete_metadata('post', null, '_thumbnail_id', $post_id, true);
    wp_defer_comment_counting(true);
    $comment_ids = $wpdb->get_col($wpdb->prepare("SELECT comment_ID FROM {$wpdb->comments} WHERE comment_post_ID = %d", $post_id));
    foreach ($comment_ids as $comment_id) {
        wp_delete_comment($comment_id, true);
    }
    wp_defer_comment_counting(false);
    $post_meta_ids = $wpdb->get_col($wpdb->prepare("SELECT meta_id FROM {$wpdb->postmeta} WHERE post_id = %d ", $post_id));
    foreach ($post_meta_ids as $mid) {
        delete_metadata_by_mid('post', $mid);
    }
    /** This action is documented in wp-includes/post.php */
    do_action('delete_post', $post_id);
    $result = $wpdb->delete($wpdb->posts, array('ID' => $post_id));
    if (!$result) {
        return false;
    }
    /** This action is documented in wp-includes/post.php */
    do_action('deleted_post', $post_id);
    $uploadpath = wp_upload_dir();
    if (!empty($meta['thumb'])) {
        // Don't delete the thumb if another attachment uses it.
        if (!$wpdb->get_row($wpdb->prepare("SELECT meta_id FROM {$wpdb->postmeta} WHERE meta_key = '_wp_attachment_metadata' AND meta_value LIKE %s AND post_id <> %d", '%' . $wpdb->esc_like($meta['thumb']) . '%', $post_id))) {
            $thumbfile = str_replace(basename($file), $meta['thumb'], $file);
            /** This filter is documented in wp-includes/functions.php */
            $thumbfile = apply_filters('wp_delete_file', $thumbfile);
            @unlink(path_join($uploadpath['basedir'], $thumbfile));
        }
    }
    // Remove intermediate and backup images if there are any.
    if (isset($meta['sizes']) && is_array($meta['sizes'])) {
        foreach ($meta['sizes'] as $size => $sizeinfo) {
            $intermediate_file = str_replace(basename($file), $sizeinfo['file'], $file);
            /** This filter is documented in wp-includes/functions.php */
            $intermediate_file = apply_filters('wp_delete_file', $intermediate_file);
            @unlink(path_join($uploadpath['basedir'], $intermediate_file));
        }
    }
    if (is_array($backup_sizes)) {
        foreach ($backup_sizes as $size) {
            $del_file = path_join(dirname($meta['file']), $size['file']);
            /** This filter is documented in wp-includes/functions.php */
            $del_file = apply_filters('wp_delete_file', $del_file);
            @unlink(path_join($uploadpath['basedir'], $del_file));
        }
    }
    wp_delete_file($file);
    clean_post_cache($post);
    return $post;
}
/**
 * Perform all pingbacks, enclosures, trackbacks, and send to pingback services.
 *
 * @since 2.1.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 */
function do_all_pings()
{
    global $wpdb;
    // Do pingbacks
    while ($ping = $wpdb->get_row("SELECT ID, post_content, meta_id FROM {$wpdb->posts}, {$wpdb->postmeta} WHERE {$wpdb->posts}.ID = {$wpdb->postmeta}.post_id AND {$wpdb->postmeta}.meta_key = '_pingme' LIMIT 1")) {
        delete_metadata_by_mid('post', $ping->meta_id);
        pingback($ping->post_content, $ping->ID);
    }
    // Do Enclosures
    while ($enclosure = $wpdb->get_row("SELECT ID, post_content, meta_id FROM {$wpdb->posts}, {$wpdb->postmeta} WHERE {$wpdb->posts}.ID = {$wpdb->postmeta}.post_id AND {$wpdb->postmeta}.meta_key = '_encloseme' LIMIT 1")) {
        delete_metadata_by_mid('post', $enclosure->meta_id);
        do_enclose($enclosure->post_content, $enclosure->ID);
    }
    // Do Trackbacks
    $trackbacks = $wpdb->get_col("SELECT ID FROM {$wpdb->posts} WHERE to_ping <> '' AND post_status = 'publish'");
    if (is_array($trackbacks)) {
        foreach ($trackbacks as $trackback) {
            do_trackbacks($trackback);
        }
    }
    //Do Update Services/Generic Pings
    generic_ping();
}
Beispiel #7
0
 function test_get_post_meta_by_id()
 {
     $mid = add_post_meta($this->post_id, 'get_post_meta_by_key', 'get_post_meta_by_key_value', true);
     $this->assertInternalType('integer', $mid);
     $mobj = new stdClass();
     $mobj->meta_id = $mid;
     $mobj->post_id = $this->post_id;
     $mobj->meta_key = 'get_post_meta_by_key';
     $mobj->meta_value = 'get_post_meta_by_key_value';
     $this->assertEquals($mobj, get_post_meta_by_id($mid));
     delete_metadata_by_mid('post', $mid);
     $mid = add_post_meta($this->post_id, 'get_post_meta_by_key', array('foo', 'bar'), true);
     $this->assertInternalType('integer', $mid);
     $mobj->meta_id = $mid;
     $mobj->meta_value = array('foo', 'bar');
     $this->assertEquals($mobj, get_post_meta_by_id($mid));
     delete_metadata_by_mid('post', $mid);
 }
Beispiel #8
0
/**
 * Delete post meta data by meta ID.
 *
 * @since 1.2.0
 *
 * @param int $mid
 * @return bool
 */
function delete_meta($mid)
{
    return delete_metadata_by_mid('post', $mid);
}
Beispiel #9
0
/**
 * Remove user and optionally reassign posts and links to another user.
 *
 * If the $reassign parameter is not assigned to a User ID, then all posts will
 * be deleted of that user. The action 'delete_user' that is passed the User ID
 * being deleted will be run after the posts are either reassigned or deleted.
 * The user meta will also be deleted that are for that User ID.
 *
 * @since 2.0.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param int $id User ID.
 * @param int $reassign Optional. Reassign posts and links to new User ID.
 * @return bool True when finished.
 */
function wp_delete_user($id, $reassign = null)
{
    global $wpdb;
    if (!is_numeric($id)) {
        return false;
    }
    $id = (int) $id;
    $user = new WP_User($id);
    if (!$user->exists()) {
        return false;
    }
    // Normalize $reassign to null or a user ID. 'novalue' was an older default.
    if ('novalue' === $reassign) {
        $reassign = null;
    } elseif (null !== $reassign) {
        $reassign = (int) $reassign;
    }
    /**
     * Fires immediately before a user is deleted from the database.
     *
     * @since 2.0.0
     *
     * @param int      $id       ID of the user to delete.
     * @param int|null $reassign ID of the user to reassign posts and links to.
     *                           Default null, for no reassignment.
     */
    do_action('delete_user', $id, $reassign);
    if (null === $reassign) {
        $post_types_to_delete = array();
        foreach (get_post_types(array(), 'objects') as $post_type) {
            if ($post_type->delete_with_user) {
                $post_types_to_delete[] = $post_type->name;
            } elseif (null === $post_type->delete_with_user && post_type_supports($post_type->name, 'author')) {
                $post_types_to_delete[] = $post_type->name;
            }
        }
        /**
         * Filter the list of post types to delete with a user.
         *
         * @since 3.4.0
         *
         * @param array $post_types_to_delete Post types to delete.
         * @param int   $id                   User ID.
         */
        $post_types_to_delete = apply_filters('post_types_to_delete_with_user', $post_types_to_delete, $id);
        $post_types_to_delete = implode("', '", $post_types_to_delete);
        $post_ids = $wpdb->get_col($wpdb->prepare("SELECT ID FROM {$wpdb->posts} WHERE post_author = %d AND post_type IN ('{$post_types_to_delete}')", $id));
        if ($post_ids) {
            foreach ($post_ids as $post_id) {
                wp_delete_post($post_id);
            }
        }
        // Clean links
        $link_ids = $wpdb->get_col($wpdb->prepare("SELECT link_id FROM {$wpdb->links} WHERE link_owner = %d", $id));
        if ($link_ids) {
            foreach ($link_ids as $link_id) {
                wp_delete_link($link_id);
            }
        }
    } else {
        $post_ids = $wpdb->get_col($wpdb->prepare("SELECT ID FROM {$wpdb->posts} WHERE post_author = %d", $id));
        $wpdb->update($wpdb->posts, array('post_author' => $reassign), array('post_author' => $id));
        if (!empty($post_ids)) {
            foreach ($post_ids as $post_id) {
                clean_post_cache($post_id);
            }
        }
        $link_ids = $wpdb->get_col($wpdb->prepare("SELECT link_id FROM {$wpdb->links} WHERE link_owner = %d", $id));
        $wpdb->update($wpdb->links, array('link_owner' => $reassign), array('link_owner' => $id));
        if (!empty($link_ids)) {
            foreach ($link_ids as $link_id) {
                clean_bookmark_cache($link_id);
            }
        }
    }
    // FINALLY, delete user
    if (is_multisite()) {
        remove_user_from_blog($id, get_current_blog_id());
    } else {
        $meta = $wpdb->get_col($wpdb->prepare("SELECT umeta_id FROM {$wpdb->usermeta} WHERE user_id = %d", $id));
        foreach ($meta as $mid) {
            delete_metadata_by_mid('user', $mid);
        }
        $wpdb->delete($wpdb->users, array('ID' => $id));
    }
    clean_user_cache($user);
    /**
     * Fires immediately after a user is deleted from the database.
     *
     * @since 2.9.0
     *
     * @param int      $id       ID of the deleted user.
     * @param int|null $reassign ID of the user to reassign posts and links to.
     *                           Default null, for no reassignment.
     */
    do_action('deleted_user', $id, $reassign);
    return true;
}
 /**
  * Delete meta from a post
  *
  * @param int $id Post ID
  * @param int $mid Metadata ID
  * @return array|WP_Error Message on success, WP_Error otherwise
  */
 public function delete_meta($id, $mid)
 {
     $id = (int) $id;
     if (empty($id)) {
         return new WP_Error('json_post_invalid_id', __('Invalid post ID.'), array('status' => 404));
     }
     $post = get_post($id, ARRAY_A);
     if (empty($post['ID'])) {
         return new WP_Error('json_post_invalid_id', __('Invalid post ID.'), array('status' => 404));
     }
     if (!$this->check_edit_permission($post)) {
         return new WP_Error('json_cannot_edit', __('Sorry, you cannot edit this post'), array('status' => 403));
     }
     $current = get_metadata_by_mid('post', $mid);
     if (empty($current)) {
         return new WP_Error('json_meta_invalid_id', __('Invalid meta ID.'), array('status' => 404));
     }
     if (absint($current->post_id) !== $id) {
         return new WP_Error('json_meta_post_mismatch', __('Meta does not belong to this post'), array('status' => 400));
     }
     // for now let's not allow updating of arrays, objects or serialized values.
     if (!$this->is_valid_meta_data($current->meta_value)) {
         return new WP_Error('json_post_invalid_action', __('Invalid existing meta data for action.'), array('status' => 400));
     }
     if (is_protected_meta($current->meta_key)) {
         return new WP_Error('json_meta_protected', sprintf(__('%s is marked as a protected field.'), $current->meta_key), array('status' => 403));
     }
     if (!delete_metadata_by_mid('post', $mid)) {
         return new WP_Error('json_meta_could_not_add', __('Could not delete post meta.'), array('status' => 500));
     }
     return array('message' => __('Deleted meta'));
 }
Beispiel #11
0
/**
 * Remove a Media entry from gallery
 * 
 * @param type $media_id
 */
function mpp_delete_media($media_id)
{
    global $wpdb;
    if (!($media = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->posts} WHERE ID = %d", $media_id)))) {
        return $post;
    }
    if (mpp_get_media_post_type() != $media->post_type) {
        return false;
    }
    //firs of all delete all media associated with this post
    $storage_manager = mpp_get_storage_manager($media_id);
    $storage_manager->delete($media_id);
    //now proceed to delete the post
    mpp_delete_media_meta($media_id, '_wp_trash_meta_status');
    mpp_delete_media_meta($media_id, '_wp_trash_meta_time');
    do_action('mpp_delete_media', $media_id);
    wp_delete_object_term_relationships($media_id, array('category', 'post_tag'));
    wp_delete_object_term_relationships($media_id, get_object_taxonomies(mpp_get_media_post_type()));
    delete_metadata('post', null, '_thumbnail_id', $media_id, true);
    // delete all for any posts.
    //dele if it is set as cover
    delete_metadata('post', null, '_mpp_cover_id', $media_id, true);
    // delete all for any posts.
    $comment_ids = $wpdb->get_col($wpdb->prepare("SELECT comment_ID FROM {$wpdb->comments} WHERE comment_post_ID = %d", $media_id));
    foreach ($comment_ids as $comment_id) {
        wp_delete_comment($comment_id, true);
    }
    //if media has cover, delete the cover
    if (mpp_media_has_cover_image($media_id)) {
        mpp_delete_media(mpp_get_media_cover_id($media_id));
    }
    //delete met
    $post_meta_ids = $wpdb->get_col($wpdb->prepare("SELECT meta_id FROM {$wpdb->postmeta} WHERE post_id = %d ", $media_id));
    foreach ($post_meta_ids as $mid) {
        delete_metadata_by_mid('post', $mid);
    }
    $result = $wpdb->delete($wpdb->posts, array('ID' => $media_id));
    if (!$result) {
        return false;
    }
    //decrease the media_count in gallery by 1
    mpp_gallery_decrement_media_count($media->post_parent);
    //delete all activities related to this media
    mpp_media_delete_activities($media_id);
    //delete all activity meta key where this media is associated
    mpp_media_delete_activity_meta($media_id);
    clean_post_cache($media);
    do_action('mpp_media_deleted', $media_id);
    return $media;
}
 /**
  * Deletes meta based on meta ID.
  *
  * @since  2.7.0
  * @param  WC_Data
  * @param  stdClass (containing at least ->id)
  * @return array
  */
 public function delete_meta(&$object, $meta)
 {
     delete_metadata_by_mid($this->meta_type, $meta->id);
 }
/**
 * Check content for video and audio links to add as enclosures.
 *
 * Will not add enclosures that have already been added and will
 * remove enclosures that are no longer in the post. This is called as
 * pingbacks and trackbacks.
 *
 * @package WordPress
 * @since 1.5.0
 *
 * @uses $wpdb
 *
 * @param string $content Post Content
 * @param int $post_ID Post ID
 */
function do_enclose( $content, $post_ID ) {
	global $wpdb;

	//TODO: Tidy this ghetto code up and make the debug code optional
	include_once( ABSPATH . WPINC . '/class-IXR.php' );

	$post_links = array();

	$pung = get_enclosed( $post_ID );

	$ltrs = '\w';
	$gunk = '/#~:.?+=&%@!\-';
	$punc = '.:?\-';
	$any = $ltrs . $gunk . $punc;

	preg_match_all( "{\b http : [$any] +? (?= [$punc] * [^$any] | $)}x", $content, $post_links_temp );

	foreach ( $pung as $link_test ) {
		if ( !in_array( $link_test, $post_links_temp[0] ) ) { // link no longer in post
			$mids = $wpdb->get_col( $wpdb->prepare("SELECT meta_id FROM $wpdb->postmeta WHERE post_id = %d AND meta_key = 'enclosure' AND meta_value LIKE (%s)", $post_ID, like_escape( $link_test ) . '%') );
			foreach ( $mids as $mid )
				delete_metadata_by_mid( 'post', $mid );
		}
	}

	foreach ( (array) $post_links_temp[0] as $link_test ) {
		if ( !in_array( $link_test, $pung ) ) { // If we haven't pung it already
			$test = @parse_url( $link_test );
			if ( false === $test )
				continue;
			if ( isset( $test['query'] ) )
				$post_links[] = $link_test;
			elseif ( isset($test['path']) && ( $test['path'] != '/' ) &&  ($test['path'] != '' ) )
				$post_links[] = $link_test;
		}
	}

	foreach ( (array) $post_links as $url ) {
		if ( $url != '' && !$wpdb->get_var( $wpdb->prepare( "SELECT post_id FROM $wpdb->postmeta WHERE post_id = %d AND meta_key = 'enclosure' AND meta_value LIKE (%s)", $post_ID, like_escape( $url ) . '%' ) ) ) {

			if ( $headers = wp_get_http_headers( $url) ) {
				$len = isset( $headers['content-length'] ) ? (int) $headers['content-length'] : 0;
				$type = isset( $headers['content-type'] ) ? $headers['content-type'] : '';
				$allowed_types = array( 'video', 'audio' );

				// Check to see if we can figure out the mime type from
				// the extension
				$url_parts = @parse_url( $url );
				if ( false !== $url_parts ) {
					$extension = pathinfo( $url_parts['path'], PATHINFO_EXTENSION );
					if ( !empty( $extension ) ) {
						foreach ( get_allowed_mime_types( ) as $exts => $mime ) {
							if ( preg_match( '!^(' . $exts . ')$!i', $extension ) ) {
								$type = $mime;
								break;
							}
						}
					}
				}

				if ( in_array( substr( $type, 0, strpos( $type, "/" ) ), $allowed_types ) ) {
					add_post_meta( $post_ID, 'enclosure', "$url\n$len\n$mime\n" );
				}
			}
		}
	}
}
 function write_post($path, $blog_id, $post_id)
 {
     $new = $this->api->ends_with($path, '/new');
     $args = $this->query_args();
     // unhook publicize, it's hooked again later -- without this, skipping services is impossible
     remove_action('save_post', array($GLOBALS['publicize_ui']->publicize, 'async_publicize_post'), 100, 2);
     add_action('rest_api_inserted_post', array($GLOBALS['publicize_ui']->publicize, 'async_publicize_post'));
     if ($new) {
         $input = $this->input(true);
         if ('revision' === $input['type']) {
             if (!isset($input['parent'])) {
                 return new WP_Error('invalid_input', 'Invalid request input', 400);
             }
             $input['status'] = 'inherit';
             // force inherit for revision type
             $input['slug'] = $input['parent'] . '-autosave-v1';
         } elseif (!isset($input['title']) && !isset($input['content']) && !isset($input['excerpt'])) {
             return new WP_Error('invalid_input', 'Invalid request input', 400);
         }
         // default to post
         if (empty($input['type'])) {
             $input['type'] = 'post';
         }
         $post_type = get_post_type_object($input['type']);
         if (!$this->is_post_type_allowed($input['type'])) {
             return new WP_Error('unknown_post_type', 'Unknown post type', 404);
         }
         if (!empty($input['author'])) {
             $author_id = $this->parse_and_set_author($input['author'], $input['type']);
             unset($input['author']);
             if (is_wp_error($author_id)) {
                 return $author_id;
             }
         }
         if ('publish' === $input['status']) {
             if (!current_user_can($post_type->cap->publish_posts)) {
                 if (current_user_can($post_type->cap->edit_posts)) {
                     $input['status'] = 'pending';
                 } else {
                     return new WP_Error('unauthorized', 'User cannot publish posts', 403);
                 }
             }
         } else {
             if (!current_user_can($post_type->cap->edit_posts)) {
                 return new WP_Error('unauthorized', 'User cannot edit posts', 403);
             }
         }
     } else {
         $input = $this->input(false);
         if (!is_array($input) || !$input) {
             return new WP_Error('invalid_input', 'Invalid request input', 400);
         }
         $post = get_post($post_id);
         $_post_type = !empty($input['type']) ? $input['type'] : $post->post_type;
         $post_type = get_post_type_object($_post_type);
         if (!$post || is_wp_error($post)) {
             return new WP_Error('unknown_post', 'Unknown post', 404);
         }
         if (!current_user_can('edit_post', $post->ID)) {
             return new WP_Error('unauthorized', 'User cannot edit post', 403);
         }
         if (!empty($input['author'])) {
             $author_id = $this->parse_and_set_author($input['author'], $_post_type);
             unset($input['author']);
             if (is_wp_error($author_id)) {
                 return $author_id;
             }
         }
         if ('publish' === $input['status'] && 'publish' !== $post->post_status && !current_user_can('publish_post', $post->ID)) {
             $input['status'] = 'pending';
         }
         $last_status = $post->post_status;
         $new_status = $input['status'];
     }
     if (!empty($author_id) && get_current_user_id() != $author_id) {
         if (!current_user_can($post_type->cap->edit_others_posts)) {
             return new WP_Error('unauthorized', "User is not allowed to publish others' posts.", 403);
         } elseif (!user_can($author_id, $post_type->cap->edit_posts)) {
             return new WP_Error('unauthorized', 'Assigned author cannot publish post.', 403);
         }
     }
     if (!is_post_type_hierarchical($post_type->name) && 'revision' !== $post_type->name) {
         unset($input['parent']);
     }
     $categories = null;
     $tags = null;
     if (!empty($input['categories'])) {
         if (is_array($input['categories'])) {
             $_categories = $input['categories'];
         } else {
             foreach (explode(',', $input['categories']) as $category) {
                 $_categories[] = $category;
             }
         }
         foreach ($_categories as $category) {
             if (!($category_info = term_exists($category, 'category'))) {
                 if (is_int($category)) {
                     continue;
                 }
                 $category_info = wp_insert_term($category, 'category');
             }
             if (!is_wp_error($category_info)) {
                 $categories[] = (int) $category_info['term_id'];
             }
         }
     }
     if (!empty($input['tags'])) {
         if (is_array($input['tags'])) {
             $tags = $input['tags'];
         } else {
             foreach (explode(',', $input['tags']) as $tag) {
                 $tags[] = $tag;
             }
         }
         $tags_string = implode(',', $tags);
     }
     unset($input['tags'], $input['categories']);
     $insert = array();
     if (!empty($input['slug'])) {
         $insert['post_name'] = $input['slug'];
         unset($input['slug']);
     }
     if (true === $input['comments_open']) {
         $insert['comment_status'] = 'open';
     } else {
         if (false === $input['comments_open']) {
             $insert['comment_status'] = 'closed';
         }
     }
     if (true === $input['pings_open']) {
         $insert['ping_status'] = 'open';
     } else {
         if (false === $input['pings_open']) {
             $insert['ping_status'] = 'closed';
         }
     }
     unset($input['comments_open'], $input['pings_open']);
     $publicize = $input['publicize'];
     $publicize_custom_message = $input['publicize_message'];
     unset($input['publicize'], $input['publicize_message']);
     if (isset($input['featured_image'])) {
         $featured_image = trim($input['featured_image']);
         $delete_featured_image = empty($featured_image);
         $featured_image = $input['featured_image'];
         unset($input['featured_image']);
     }
     $metadata = $input['metadata'];
     unset($input['metadata']);
     $likes = $input['likes_enabled'];
     $sharing = $input['sharing_enabled'];
     $gplus = $input['gplusauthorship_enabled'];
     unset($input['likes_enabled']);
     unset($input['sharing_enabled']);
     unset($input['gplusauthorship_enabled']);
     $sticky = $input['sticky'];
     unset($input['sticky']);
     foreach ($input as $key => $value) {
         $insert["post_{$key}"] = $value;
     }
     if (!empty($author_id)) {
         $insert['post_author'] = absint($author_id);
     }
     if (!empty($tags)) {
         $insert["tax_input"]["post_tag"] = $tags;
     }
     if (!empty($categories)) {
         $insert["tax_input"]["category"] = $categories;
     }
     $has_media = isset($input['media']) && $input['media'] ? count($input['media']) : false;
     $has_media_by_url = isset($input['media_urls']) && $input['media_urls'] ? count($input['media_urls']) : false;
     if ($new) {
         if (false === strpos($input['content'], '[gallery') && ($has_media || $has_media_by_url)) {
             switch ($has_media + $has_media_by_url) {
                 case 0:
                     // No images - do nothing.
                     break;
                 case 1:
                     // 1 image - make it big
                     $insert['post_content'] = $input['content'] = "[gallery size=full columns=1]\n\n" . $input['content'];
                     break;
                 default:
                     // Several images - 3 column gallery
                     $insert['post_content'] = $input['content'] = "[gallery]\n\n" . $input['content'];
                     break;
             }
         }
         $post_id = wp_insert_post(add_magic_quotes($insert), true);
     } else {
         $insert['ID'] = $post->ID;
         $post_id = wp_update_post((object) $insert);
     }
     if (!$post_id || is_wp_error($post_id)) {
         return $post_id;
     }
     if ($has_media) {
         $this->api->trap_wp_die('upload_error');
         foreach ($input['media'] as $media_item) {
             $_FILES['.api.media.item.'] = $media_item;
             // check for WP_Error if we ever actually need $media_id
             $media_id = media_handle_upload('.api.media.item.', $post_id);
         }
         $this->api->trap_wp_die(null);
         unset($_FILES['.api.media.item.']);
     }
     if ($has_media_by_url) {
         foreach ($input['media_urls'] as $url) {
             $this->handle_media_sideload($url, $post_id);
         }
     }
     // Set like status for the post
     $sitewide_likes_enabled = (bool) apply_filters('wpl_is_enabled_sitewide', !get_option('disabled_likes'));
     if ($new) {
         if ($sitewide_likes_enabled) {
             if (false === $likes) {
                 update_post_meta($post_id, 'switch_like_status', 1);
             } else {
                 delete_post_meta($post_id, 'switch_like_status');
             }
         } else {
             if ($likes) {
                 update_post_meta($post_id, 'switch_like_status', 1);
             } else {
                 delete_post_meta($post_id, 'switch_like_status');
             }
         }
     } else {
         if (isset($likes)) {
             if ($sitewide_likes_enabled) {
                 if (false === $likes) {
                     update_post_meta($post_id, 'switch_like_status', 1);
                 } else {
                     delete_post_meta($post_id, 'switch_like_status');
                 }
             } else {
                 if (true === $likes) {
                     update_post_meta($post_id, 'switch_like_status', 1);
                 } else {
                     delete_post_meta($post_id, 'switch_like_status');
                 }
             }
         }
     }
     // Set Google+ authorship status for the post
     if ($new) {
         $gplus_enabled = isset($gplus) ? (bool) $gplus : true;
         if (false === $gplus_enabled) {
             update_post_meta($post_id, 'gplus_authorship_disabled', 1);
         }
     } else {
         if (isset($gplus) && true === $gplus) {
             delete_post_meta($post_id, 'gplus_authorship_disabled');
         } else {
             if (isset($gplus) && false == $gplus) {
                 update_post_meta($post_id, 'gplus_authorship_disabled', 1);
             }
         }
     }
     // Set sharing status of the post
     if ($new) {
         $sharing_enabled = isset($sharing) ? (bool) $sharing : true;
         if (false === $sharing_enabled) {
             update_post_meta($post_id, 'sharing_disabled', 1);
         }
     } else {
         if (isset($sharing) && true === $sharing) {
             delete_post_meta($post_id, 'sharing_disabled');
         } else {
             if (isset($sharing) && false == $sharing) {
                 update_post_meta($post_id, 'sharing_disabled', 1);
             }
         }
     }
     if (true === $sticky) {
         stick_post($post_id);
     } else {
         unstick_post($post_id);
     }
     // WPCOM Specific (Jetpack's will get bumped elsewhere
     // Tracks how many posts are published and sets meta so we can track some other cool stats (like likes & comments on posts published)
     if ($new && 'publish' == $input['status'] || !$new && isset($last_status) && 'publish' != $last_status && isset($new_status) && 'publish' == $new_status) {
         if (function_exists('bump_stats_extras')) {
             bump_stats_extras('api-insights-posts', $this->api->token_details['client_id']);
             update_post_meta($post_id, '_rest_api_published', 1);
             update_post_meta($post_id, '_rest_api_client_id', $this->api->token_details['client_id']);
         }
     }
     // We ask the user/dev to pass Publicize services he/she wants activated for the post, but Publicize expects us
     // to instead flag the ones we don't want to be skipped. proceed with said logic.
     // any posts coming from Path (client ID 25952) should also not publicize
     if ($publicize === false || 25952 == $this->api->token_details['client_id']) {
         // No publicize at all, skipp all by full service
         foreach ($GLOBALS['publicize_ui']->publicize->get_services('all') as $name => $service) {
             update_post_meta($post_id, $GLOBALS['publicize_ui']->publicize->POST_SKIP . $name, 1);
         }
     } else {
         if (is_array($publicize) && count($publicize) > 0) {
             foreach ($GLOBALS['publicize_ui']->publicize->get_services('all') as $name => $service) {
                 /*
                  * We support both indexed and associative arrays:
                  * * indexed are to pass entire services
                  * * associative are to pass specific connections per service
                  *
                  * We do support mixed arrays: mixed integer and string keys (see 3rd example below).
                  *
                  * EG: array( 'twitter', 'facebook') will only publicize to those, ignoring the other available services
                  * 		Form data: publicize[]=twitter&publicize[]=facebook
                  * EG: array( 'twitter' => '(int) $pub_conn_id_0, (int) $pub_conn_id_3', 'facebook' => (int) $pub_conn_id_7 ) will publicize to two Twitter accounts, and one Facebook connection, of potentially many.
                  * 		Form data: publicize[twitter]=$pub_conn_id_0,$pub_conn_id_3&publicize[facebook]=$pub_conn_id_7
                  * EG: array( 'twitter', 'facebook' => '(int) $pub_conn_id_0, (int) $pub_conn_id_3' ) will publicize to all available Twitter accounts, but only 2 of potentially many Facebook connections
                  * 		Form data: publicize[]=twitter&publicize[facebook]=$pub_conn_id_0,$pub_conn_id_3
                  */
                 if (!in_array($name, $publicize) && !array_key_exists($name, $publicize)) {
                     // Skip the whole service
                     update_post_meta($post_id, $GLOBALS['publicize_ui']->publicize->POST_SKIP . $name, 1);
                 } else {
                     if (!empty($publicize[$name])) {
                         // Seems we're being asked to only push to [a] specific connection[s].
                         // Explode the list on commas, which will also support a single passed ID
                         $requested_connections = explode(',', preg_replace('/[\\s]*/', '', $publicize[$name]));
                         // Get the user's connections and flag the ones we can't match with the requested list to be skipped.
                         $service_connections = $GLOBALS['publicize_ui']->publicize->get_connections($name);
                         foreach ($service_connections as $service_connection) {
                             if (!in_array($service_connection->meta['connection_data']->id, $requested_connections)) {
                                 update_post_meta($post_id, $GLOBALS['publicize_ui']->publicize->POST_SKIP . $service_connection->unique_id, 1);
                             }
                         }
                     }
                 }
             }
         }
     }
     if (!empty($publicize_custom_message)) {
         update_post_meta($post_id, $GLOBALS['publicize_ui']->publicize->POST_MESS, trim($publicize_custom_message));
     }
     set_post_format($post_id, $insert['post_format']);
     if (!empty($featured_image)) {
         $this->parse_and_set_featured_image($post_id, $delete_featured_image, $featured_image);
     }
     if (!empty($metadata)) {
         foreach ((array) $metadata as $meta) {
             $meta = (object) $meta;
             $existing_meta_item = new stdClass();
             if (empty($meta->operation)) {
                 $meta->operation = 'update';
             }
             if (!empty($meta->value)) {
                 if ('true' == $meta->value) {
                     $meta->value = true;
                 }
                 if ('false' == $meta->value) {
                     $meta->value = false;
                 }
             }
             if (!empty($meta->id)) {
                 $meta->id = absint($meta->id);
                 $existing_meta_item = get_metadata_by_mid('post', $meta->id);
             }
             $unslashed_meta_key = wp_unslash($meta->key);
             // should match what the final key will be
             $meta->key = wp_slash($meta->key);
             $unslashed_existing_meta_key = wp_unslash($existing_meta_item->meta_key);
             $existing_meta_item->meta_key = wp_slash($existing_meta_item->meta_key);
             switch ($meta->operation) {
                 case 'delete':
                     if (!empty($meta->id) && !empty($existing_meta_item->meta_key) && current_user_can('delete_post_meta', $post_id, $unslashed_existing_meta_key)) {
                         delete_metadata_by_mid('post', $meta->id);
                     } elseif (!empty($meta->key) && !empty($meta->previous_value) && current_user_can('delete_post_meta', $post_id, $unslashed_meta_key)) {
                         delete_post_meta($post_id, $meta->key, $meta->previous_value);
                     } elseif (!empty($meta->key) && current_user_can('delete_post_meta', $post_id, $unslashed_meta_key)) {
                         delete_post_meta($post_id, $meta->key);
                     }
                     break;
                 case 'add':
                     if (!empty($meta->id) || !empty($meta->previous_value)) {
                         continue;
                     } elseif (!empty($meta->key) && !empty($meta->value) && current_user_can('add_post_meta', $post_id, $unslashed_meta_key) || $this->is_metadata_public($meta->key)) {
                         add_post_meta($post_id, $meta->key, $meta->value);
                     }
                     break;
                 case 'update':
                     if (!isset($meta->value)) {
                         continue;
                     } elseif (!empty($meta->id) && !empty($existing_meta_item->meta_key) && (current_user_can('edit_post_meta', $post_id, $unslashed_existing_meta_key) || $this->is_metadata_public($meta->key))) {
                         update_metadata_by_mid('post', $meta->id, $meta->value);
                     } elseif (!empty($meta->key) && !empty($meta->previous_value) && (current_user_can('edit_post_meta', $post_id, $unslashed_meta_key) || $this->is_metadata_public($meta->key))) {
                         update_post_meta($post_id, $meta->key, $meta->value, $meta->previous_value);
                     } elseif (!empty($meta->key) && (current_user_can('edit_post_meta', $post_id, $unslashed_meta_key) || $this->is_metadata_public($meta->key))) {
                         update_post_meta($post_id, $meta->key, $meta->value);
                     }
                     break;
             }
         }
     }
     do_action('rest_api_inserted_post', $post_id, $insert, $new);
     $return = $this->get_post_by('ID', $post_id, $args['context']);
     if (!$return || is_wp_error($return)) {
         return $return;
     }
     if ('revision' === $input['type']) {
         $return['preview_nonce'] = wp_create_nonce('post_preview_' . $input['parent']);
     }
     do_action('wpcom_json_api_objects', 'posts');
     return $return;
 }
Beispiel #15
0
 public static function wpmu_delete_user($id)
 {
     global $wpdb;
     $id = (int) $id;
     $user = new WP_User($id);
     if (!$user->exists()) {
         return false;
     }
     /**
      * Fires before a user is deleted from the network.
      *
      * @since MU
      *
      * @param int $id ID of the user about to be deleted from the network.
      */
     do_action('wpmu_delete_user', $id);
     $meta = $wpdb->get_col($wpdb->prepare("SELECT umeta_id FROM {$wpdb->usermeta} WHERE user_id = %d", $id));
     foreach ($meta as $mid) {
         delete_metadata_by_mid('user', $mid);
     }
     $wpdb->delete($wpdb->users, array('ID' => $id));
     clean_user_cache($user);
     do_action('deleted_user', $id);
     return true;
 }
Beispiel #16
0
/**
 * Delete a user from the network and remove from all sites.
 *
 * @since 3.0.0
 *
 * @todo Merge with wp_delete_user() ?
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param int $id The user ID.
 * @return bool True if the user was deleted, otherwise false.
 */
function wpmu_delete_user($id)
{
    global $wpdb;
    if (!is_numeric($id)) {
        return false;
    }
    $id = (int) $id;
    $user = new WP_User($id);
    if (!$user->exists()) {
        return false;
    }
    // Global super-administrators are protected, and cannot be deleted.
    $_super_admins = get_super_admins();
    if (in_array($user->user_login, $_super_admins, true)) {
        return false;
    }
    /**
     * Fires before a user is deleted from the network.
     *
     * @since MU
     *
     * @param int $id ID of the user about to be deleted from the network.
     */
    do_action('wpmu_delete_user', $id);
    $blogs = get_blogs_of_user($id);
    if (!empty($blogs)) {
        foreach ($blogs as $blog) {
            switch_to_blog($blog->userblog_id);
            remove_user_from_blog($id, $blog->userblog_id);
            $post_ids = $wpdb->get_col($wpdb->prepare("SELECT ID FROM {$wpdb->posts} WHERE post_author = %d", $id));
            foreach ((array) $post_ids as $post_id) {
                wp_delete_post($post_id);
            }
            // Clean links
            $link_ids = $wpdb->get_col($wpdb->prepare("SELECT link_id FROM {$wpdb->links} WHERE link_owner = %d", $id));
            if ($link_ids) {
                foreach ($link_ids as $link_id) {
                    wp_delete_link($link_id);
                }
            }
            restore_current_blog();
        }
    }
    $meta = $wpdb->get_col($wpdb->prepare("SELECT umeta_id FROM {$wpdb->usermeta} WHERE user_id = %d", $id));
    foreach ($meta as $mid) {
        delete_metadata_by_mid('user', $mid);
    }
    $wpdb->delete($wpdb->users, array('ID' => $id));
    clean_user_cache($user);
    /** This action is documented in wp-admin/includes/user.php */
    do_action('deleted_user', $id);
    return true;
}
Beispiel #17
0
/**
 * Trashes or deletes an attachment.
 *
 * When an attachment is permanently deleted, the file will also be removed.
 * Deletion removes all post meta fields, taxonomy, comments, etc. associated
 * with the attachment (except the main post).
 *
 * The attachment is moved to the trash instead of permanently deleted unless trash
 * for media is disabled, item is already in the trash, or $force_delete is true.
 *
 * @since 2.0.0
 * @uses $wpdb
 * @uses do_action() Calls 'delete_attachment' hook on Attachment ID.
 *
 * @param int $post_id Attachment ID.
 * @param bool $force_delete Whether to bypass trash and force deletion. Defaults to false.
 * @return mixed False on failure. Post data on success.
 */
function wp_delete_attachment($post_id, $force_delete = false)
{
    global $wpdb;
    if (!($post = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->posts} WHERE ID = %d", $post_id)))) {
        return $post;
    }
    if ('attachment' != $post->post_type) {
        return false;
    }
    if (!$force_delete && EMPTY_TRASH_DAYS && MEDIA_TRASH && 'trash' != $post->post_status) {
        return wp_trash_post($post_id);
    }
    delete_post_meta($post_id, '_wp_trash_meta_status');
    delete_post_meta($post_id, '_wp_trash_meta_time');
    $meta = wp_get_attachment_metadata($post_id);
    $backup_sizes = get_post_meta($post->ID, '_wp_attachment_backup_sizes', true);
    $file = get_attached_file($post_id);
    $intermediate_sizes = array();
    foreach (get_intermediate_image_sizes() as $size) {
        if ($intermediate = image_get_intermediate_size($post_id, $size)) {
            $intermediate_sizes[] = $intermediate;
        }
    }
    if (is_multisite()) {
        delete_transient('dirsize_cache');
    }
    do_action('delete_attachment', $post_id);
    wp_delete_object_term_relationships($post_id, array('category', 'post_tag'));
    wp_delete_object_term_relationships($post_id, get_object_taxonomies($post->post_type));
    delete_metadata('post', null, '_thumbnail_id', $post_id, true);
    // delete all for any posts.
    $comment_ids = $wpdb->get_col($wpdb->prepare("SELECT comment_ID FROM {$wpdb->comments} WHERE comment_post_ID = %d", $post_id));
    foreach ($comment_ids as $comment_id) {
        wp_delete_comment($comment_id, true);
    }
    $post_meta_ids = $wpdb->get_col($wpdb->prepare("SELECT meta_id FROM {$wpdb->postmeta} WHERE post_id = %d ", $post_id));
    foreach ($post_meta_ids as $mid) {
        delete_metadata_by_mid('post', $mid);
    }
    do_action('delete_post', $post_id);
    $wpdb->delete($wpdb->posts, array('ID' => $post_id));
    do_action('deleted_post', $post_id);
    $uploadpath = wp_upload_dir();
    if (!empty($meta['thumb'])) {
        // Don't delete the thumb if another attachment uses it
        if (!$wpdb->get_row($wpdb->prepare("SELECT meta_id FROM {$wpdb->postmeta} WHERE meta_key = '_wp_attachment_metadata' AND meta_value LIKE %s AND post_id <> %d", '%' . $meta['thumb'] . '%', $post_id))) {
            $thumbfile = str_replace(basename($file), $meta['thumb'], $file);
            $thumbfile = apply_filters('wp_delete_file', $thumbfile);
            @unlink(path_join($uploadpath['basedir'], $thumbfile));
        }
    }
    // remove intermediate and backup images if there are any
    foreach ($intermediate_sizes as $intermediate) {
        $intermediate_file = apply_filters('wp_delete_file', $intermediate['path']);
        @unlink(path_join($uploadpath['basedir'], $intermediate_file));
    }
    if (is_array($backup_sizes)) {
        foreach ($backup_sizes as $size) {
            $del_file = path_join(dirname($meta['file']), $size['file']);
            $del_file = apply_filters('wp_delete_file', $del_file);
            @unlink(path_join($uploadpath['basedir'], $del_file));
        }
    }
    $file = apply_filters('wp_delete_file', $file);
    if (!empty($file)) {
        @unlink($file);
    }
    clean_post_cache($post);
    return $post;
}
 /**
  * Update Meta Data in the database.
  * @since 2.6.0
  */
 protected function save_meta_data()
 {
     global $wpdb;
     $db_info = $this->_get_db_info();
     $all_meta_ids = array_map('absint', $wpdb->get_col($wpdb->prepare("\n\t\t\tSELECT " . $db_info['meta_id_field'] . " FROM " . $db_info['table'] . "\n\t\t\tWHERE " . $db_info['object_id_field'] . " = %d", $this->get_id()) . "\n\t\t\tAND meta_key NOT IN ('" . implode("','", array_map('esc_sql', $this->get_internal_meta_keys())) . "')\n\t\t\tAND meta_key NOT LIKE 'wp\\_%%';\n\t\t"));
     $set_meta_ids = array();
     foreach ($this->_meta_data as $array_key => $meta) {
         if (empty($meta->id)) {
             $new_meta_id = add_metadata($this->_meta_type, $this->get_id(), $meta->key, $meta->value, false);
             $set_meta_ids[] = $new_meta_id;
             $this->_meta_data[$array_key]->id = $new_meta_id;
         } else {
             update_metadata_by_mid($this->_meta_type, $meta->id, $meta->value, $meta->key);
             $set_meta_ids[] = absint($meta->id);
         }
     }
     // Delete no longer set meta data
     $delete_meta_ids = array_diff($all_meta_ids, $set_meta_ids);
     foreach ($delete_meta_ids as $meta_id) {
         delete_metadata_by_mid($this->_meta_type, $meta_id);
     }
     if (!empty($this->_cache_group)) {
         WC_Cache_Helper::incr_cache_prefix($this->_cache_group);
     }
     $this->read_meta_data();
 }
 function write_post($path, $blog_id, $post_id)
 {
     $new = $this->api->ends_with($path, '/new');
     $args = $this->query_args();
     // unhook publicize, it's hooked again later -- without this, skipping services is impossible
     if (defined('IS_WPCOM') && IS_WPCOM) {
         remove_action('save_post', array($GLOBALS['publicize_ui']->publicize, 'async_publicize_post'), 100, 2);
         add_action('rest_api_inserted_post', array($GLOBALS['publicize_ui']->publicize, 'async_publicize_post'));
     }
     if ($new) {
         $input = $this->input(true);
         if ('revision' === $input['type']) {
             if (!isset($input['parent'])) {
                 return new WP_Error('invalid_input', 'Invalid request input', 400);
             }
             $input['status'] = 'inherit';
             // force inherit for revision type
             $input['slug'] = $input['parent'] . '-autosave-v1';
         } elseif (!isset($input['title']) && !isset($input['content']) && !isset($input['excerpt'])) {
             return new WP_Error('invalid_input', 'Invalid request input', 400);
         }
         // default to post
         if (empty($input['type'])) {
             $input['type'] = 'post';
         }
         $post_type = get_post_type_object($input['type']);
         if (!$this->is_post_type_allowed($input['type'])) {
             return new WP_Error('unknown_post_type', 'Unknown post type', 404);
         }
         if (!empty($input['author'])) {
             $author_id = parent::parse_and_set_author($input['author'], $input['type']);
             unset($input['author']);
             if (is_wp_error($author_id)) {
                 return $author_id;
             }
         }
         if ('publish' === $input['status']) {
             if (!current_user_can($post_type->cap->publish_posts)) {
                 if (current_user_can($post_type->cap->edit_posts)) {
                     $input['status'] = 'pending';
                 } else {
                     return new WP_Error('unauthorized', 'User cannot publish posts', 403);
                 }
             }
         } else {
             if (!current_user_can($post_type->cap->edit_posts)) {
                 return new WP_Error('unauthorized', 'User cannot edit posts', 403);
             }
         }
     } else {
         $input = $this->input(false);
         if (!is_array($input) || !$input) {
             return new WP_Error('invalid_input', 'Invalid request input', 400);
         }
         $post = get_post($post_id);
         $_post_type = !empty($input['type']) ? $input['type'] : $post->post_type;
         $post_type = get_post_type_object($_post_type);
         if (!$post || is_wp_error($post)) {
             return new WP_Error('unknown_post', 'Unknown post', 404);
         }
         if (!current_user_can('edit_post', $post->ID)) {
             return new WP_Error('unauthorized', 'User cannot edit post', 403);
         }
         if (!empty($input['author'])) {
             $author_id = parent::parse_and_set_author($input['author'], $_post_type);
             unset($input['author']);
             if (is_wp_error($author_id)) {
                 return $author_id;
             }
         }
         if ('publish' === $input['status'] && 'publish' !== $post->post_status && !current_user_can('publish_post', $post->ID)) {
             $input['status'] = 'pending';
         }
         $last_status = $post->post_status;
         $new_status = $input['status'];
     }
     // Fix for https://iorequests.wordpress.com/2014/08/13/scheduled-posts-made-in-the/
     // See: https://a8c.slack.com/archives/io/p1408047082000273
     // If date was set, $this->input will set date_gmt, date still needs to be adjusted for the blog's offset
     if (isset($input['date_gmt'])) {
         $gmt_offset = get_option('gmt_offset');
         $time_with_offset = strtotime($input['date_gmt']) + $gmt_offset * HOUR_IN_SECONDS;
         $input['date'] = date('Y-m-d H:i:s', $time_with_offset);
     }
     if (!empty($author_id) && get_current_user_id() != $author_id) {
         if (!current_user_can($post_type->cap->edit_others_posts)) {
             return new WP_Error('unauthorized', "User is not allowed to publish others' posts.", 403);
         } elseif (!user_can($author_id, $post_type->cap->edit_posts)) {
             return new WP_Error('unauthorized', 'Assigned author cannot publish post.', 403);
         }
     }
     if (!is_post_type_hierarchical($post_type->name) && 'revision' !== $post_type->name) {
         unset($input['parent']);
     }
     /* add taxonomies by name */
     $tax_input = array();
     foreach (array('categories' => 'category', 'tags' => 'post_tag') as $key => $taxonomy) {
         if (!isset($input[$key])) {
             continue;
         }
         $tax_input[$taxonomy] = array();
         $is_hierarchical = is_taxonomy_hierarchical($taxonomy);
         if (is_array($input[$key])) {
             $terms = $input[$key];
         } else {
             $terms = explode(',', $input[$key]);
         }
         foreach ($terms as $term) {
             /**
              * We assume these are names, not IDs, even if they are numeric.
              * Note: A category named "0" will not work right.
              * https://core.trac.wordpress.org/ticket/9059
              */
             $term_info = get_term_by('name', $term, $taxonomy, ARRAY_A);
             if (!$term_info) {
                 // only add a new tag/cat if the user has access to
                 $tax = get_taxonomy($taxonomy);
                 if (!current_user_can($tax->cap->edit_terms)) {
                     continue;
                 }
                 $term_info = wp_insert_term($term, $taxonomy);
             }
             if (!is_wp_error($term_info)) {
                 if ($is_hierarchical) {
                     // Categories must be added by ID
                     $tax_input[$taxonomy][] = (int) $term_info['term_id'];
                 } else {
                     // Tags must be added by name
                     $tax_input[$taxonomy][] = $term;
                 }
             }
         }
     }
     /* add taxonomies by ID */
     foreach (array('categories_by_id' => 'category', 'tags_by_id' => 'post_tag') as $key => $taxonomy) {
         if (!isset($input[$key])) {
             continue;
         }
         // combine with any previous selections
         if (!is_array($tax_input[$taxonomy])) {
             $tax_input[$taxonomy] = array();
         }
         $is_hierarchical = is_taxonomy_hierarchical($taxonomy);
         if (is_array($input[$key])) {
             $terms = $input[$key];
         } else {
             $terms = explode(',', $input[$key]);
         }
         foreach ($terms as $term) {
             if (!ctype_digit($term)) {
                 // skip anything that doesn't look like an ID
                 continue;
             }
             $term = (int) $term;
             $term_info = get_term_by('id', $term, $taxonomy, ARRAY_A);
             if ($term_info && !is_wp_error($term_info)) {
                 if ($is_hierarchical) {
                     // Categories must be added by ID
                     $tax_input[$taxonomy][] = $term;
                 } else {
                     // Tags must be added by name
                     $tax_input[$taxonomy][] = $term_info['name'];
                 }
             }
         }
     }
     if ((isset($input['categories']) || isset($input['categories_by_id'])) && empty($tax_input['category']) && 'revision' !== $post_type->name) {
         $tax_input['category'][] = get_option('default_category');
     }
     unset($input['tags'], $input['categories'], $input['tags_by_id'], $input['categories_by_id']);
     $insert = array();
     if (!empty($input['slug'])) {
         $insert['post_name'] = $input['slug'];
         unset($input['slug']);
     }
     if (isset($input['discussion'])) {
         $discussion = (array) $input['discussion'];
         foreach (array('comment', 'ping') as $discussion_type) {
             $discussion_open = sprintf('%ss_open', $discussion_type);
             $discussion_status = sprintf('%s_status', $discussion_type);
             if (isset($discussion[$discussion_open])) {
                 $is_open = WPCOM_JSON_API::is_truthy($discussion[$discussion_open]);
                 $discussion[$discussion_status] = $is_open ? 'open' : 'closed';
             }
             if (in_array($discussion[$discussion_status], array('open', 'closed'))) {
                 $insert[$discussion_status] = $discussion[$discussion_status];
             }
         }
     }
     unset($input['discussion']);
     if (isset($input['menu_order'])) {
         $insert['menu_order'] = $input['menu_order'];
         unset($input['menu_order']);
     }
     if (isset($input['publicize'])) {
         $publicize = $input['publicize'];
         unset($input['publicize']);
     }
     if (isset($input['publicize_message'])) {
         $publicize_custom_message = $input['publicize_message'];
         unset($input['publicize_message']);
     }
     if (isset($input['featured_image'])) {
         $featured_image = trim($input['featured_image']);
         $delete_featured_image = empty($featured_image);
         unset($input['featured_image']);
     }
     if (isset($input['metadata'])) {
         $metadata = $input['metadata'];
         unset($input['metadata']);
     }
     if (isset($input['likes_enabled'])) {
         $likes = $input['likes_enabled'];
         unset($input['likes_enabled']);
     }
     if (isset($input['sharing_enabled'])) {
         $sharing = $input['sharing_enabled'];
         unset($input['sharing_enabled']);
     }
     if (isset($input['sticky'])) {
         $sticky = $input['sticky'];
         unset($input['sticky']);
     }
     foreach ($input as $key => $value) {
         $insert["post_{$key}"] = $value;
     }
     if (!empty($author_id)) {
         $insert['post_author'] = absint($author_id);
     }
     if (!empty($tax_input)) {
         $insert['tax_input'] = $tax_input;
     }
     $has_media = !empty($input['media']) ? count($input['media']) : false;
     $has_media_by_url = !empty($input['media_urls']) ? count($input['media_urls']) : false;
     if ($new) {
         if (false === strpos($input['content'], '[gallery') && ($has_media || $has_media_by_url)) {
             switch ($has_media + $has_media_by_url) {
                 case 0:
                     // No images - do nothing.
                     break;
                 case 1:
                     // 1 image - make it big
                     $insert['post_content'] = $input['content'] = "[gallery size=full columns=1]\n\n" . $input['content'];
                     break;
                 default:
                     // Several images - 3 column gallery
                     $insert['post_content'] = $input['content'] = "[gallery]\n\n" . $input['content'];
                     break;
             }
         }
         $post_id = wp_insert_post(add_magic_quotes($insert), true);
     } else {
         $insert['ID'] = $post->ID;
         // wp_update_post ignores date unless edit_date is set
         // See: http://codex.wordpress.org/Function_Reference/wp_update_post#Scheduling_posts
         // See: https://core.trac.wordpress.org/browser/tags/3.9.2/src/wp-includes/post.php#L3302
         if (isset($input['date_gmt']) || isset($input['date'])) {
             $insert['edit_date'] = true;
         }
         $post_id = wp_update_post((object) $insert);
     }
     if (!$post_id || is_wp_error($post_id)) {
         return $post_id;
     }
     // make sure this post actually exists and is not an error of some kind (ie, trying to load media in the posts endpoint)
     $post_check = $this->get_post_by('ID', $post_id, $args['context']);
     if (is_wp_error($post_check)) {
         return $post_check;
     }
     if ($has_media || $has_media_by_url) {
         $media_files = !empty($input['media']) ? $input['media'] : array();
         $media_urls = !empty($input['media_urls']) ? $input['media_urls'] : array();
         $media_attrs = !empty($input['media_attrs']) ? $input['media_attrs'] : array();
         $force_parent_id = $post_id;
         $media_results = $this->handle_media_creation_v1_1($media_files, $media_urls, $media_attrs, $force_parent_id);
     }
     // set page template for this post..
     if (isset($input['page_template']) && 'page' == $post_type->name) {
         $page_template = $input['page_template'];
         $page_templates = wp_get_theme()->get_page_templates(get_post($post_id));
         if (empty($page_template) || 'default' == $page_template || isset($page_templates[$page_template])) {
             update_post_meta($post_id, '_wp_page_template', $page_template);
         }
     }
     // Set like status for the post
     $sitewide_likes_enabled = (bool) apply_filters('wpl_is_enabled_sitewide', !get_option('disabled_likes'));
     if ($new) {
         if ($sitewide_likes_enabled) {
             if (false === $likes) {
                 update_post_meta($post_id, 'switch_like_status', 1);
             } else {
                 delete_post_meta($post_id, 'switch_like_status');
             }
         } else {
             if ($likes) {
                 update_post_meta($post_id, 'switch_like_status', 1);
             } else {
                 delete_post_meta($post_id, 'switch_like_status');
             }
         }
     } else {
         if (isset($likes)) {
             if ($sitewide_likes_enabled) {
                 if (false === $likes) {
                     update_post_meta($post_id, 'switch_like_status', 1);
                 } else {
                     delete_post_meta($post_id, 'switch_like_status');
                 }
             } else {
                 if (true === $likes) {
                     update_post_meta($post_id, 'switch_like_status', 1);
                 } else {
                     delete_post_meta($post_id, 'switch_like_status');
                 }
             }
         }
     }
     // Set sharing status of the post
     if ($new) {
         $sharing_enabled = isset($sharing) ? (bool) $sharing : true;
         if (false === $sharing_enabled) {
             update_post_meta($post_id, 'sharing_disabled', 1);
         }
     } else {
         if (isset($sharing) && true === $sharing) {
             delete_post_meta($post_id, 'sharing_disabled');
         } else {
             if (isset($sharing) && false == $sharing) {
                 update_post_meta($post_id, 'sharing_disabled', 1);
             }
         }
     }
     if (true === $sticky) {
         stick_post($post_id);
     } else {
         unstick_post($post_id);
     }
     // WPCOM Specific (Jetpack's will get bumped elsewhere
     // Tracks how many posts are published and sets meta so we can track some other cool stats (like likes & comments on posts published)
     if ($new && 'publish' == $input['status'] || !$new && isset($last_status) && 'publish' != $last_status && isset($new_status) && 'publish' == $new_status) {
         if (function_exists('bump_stats_extras')) {
             bump_stats_extras('api-insights-posts', $this->api->token_details['client_id']);
             update_post_meta($post_id, '_rest_api_published', 1);
             update_post_meta($post_id, '_rest_api_client_id', $this->api->token_details['client_id']);
         }
     }
     // We ask the user/dev to pass Publicize services he/she wants activated for the post, but Publicize expects us
     // to instead flag the ones we don't want to be skipped. proceed with said logic.
     // any posts coming from Path (client ID 25952) should also not publicize
     if ($publicize === false || isset($this->api->token_details['client_id']) && 25952 == $this->api->token_details['client_id']) {
         // No publicize at all, skip all by ID
         foreach ($GLOBALS['publicize_ui']->publicize->get_services('all') as $name => $service) {
             delete_post_meta($post_id, $GLOBALS['publicize_ui']->publicize->POST_SKIP . $name);
             $service_connections = $GLOBALS['publicize_ui']->publicize->get_connections($name);
             if (!$service_connections) {
                 continue;
             }
             foreach ($service_connections as $service_connection) {
                 update_post_meta($post_id, $GLOBALS['publicize_ui']->publicize->POST_SKIP . $service_connection->unique_id, 1);
             }
         }
     } else {
         if (is_array($publicize) && count($publicize) > 0) {
             foreach ($GLOBALS['publicize_ui']->publicize->get_services('all') as $name => $service) {
                 /*
                  * We support both indexed and associative arrays:
                  * * indexed are to pass entire services
                  * * associative are to pass specific connections per service
                  *
                  * We do support mixed arrays: mixed integer and string keys (see 3rd example below).
                  *
                  * EG: array( 'twitter', 'facebook') will only publicize to those, ignoring the other available services
                  * 		Form data: publicize[]=twitter&publicize[]=facebook
                  * EG: array( 'twitter' => '(int) $pub_conn_id_0, (int) $pub_conn_id_3', 'facebook' => (int) $pub_conn_id_7 ) will publicize to two Twitter accounts, and one Facebook connection, of potentially many.
                  * 		Form data: publicize[twitter]=$pub_conn_id_0,$pub_conn_id_3&publicize[facebook]=$pub_conn_id_7
                  * EG: array( 'twitter', 'facebook' => '(int) $pub_conn_id_0, (int) $pub_conn_id_3' ) will publicize to all available Twitter accounts, but only 2 of potentially many Facebook connections
                  * 		Form data: publicize[]=twitter&publicize[facebook]=$pub_conn_id_0,$pub_conn_id_3
                  */
                 // Delete any stale SKIP value for the service by name. We'll add it back by ID.
                 delete_post_meta($post_id, $GLOBALS['publicize_ui']->publicize->POST_SKIP . $name);
                 // Get the user's connections
                 $service_connections = $GLOBALS['publicize_ui']->publicize->get_connections($name);
                 // if the user doesn't have any connections for this service, move on
                 if (!$service_connections) {
                     continue;
                 }
                 if (!in_array($name, $publicize) && !array_key_exists($name, $publicize)) {
                     // Skip the whole service by adding each connection ID
                     foreach ($service_connections as $service_connection) {
                         update_post_meta($post_id, $GLOBALS['publicize_ui']->publicize->POST_SKIP . $service_connection->unique_id, 1);
                     }
                 } else {
                     if (!empty($publicize[$name])) {
                         // Seems we're being asked to only push to [a] specific connection[s].
                         // Explode the list on commas, which will also support a single passed ID
                         $requested_connections = explode(',', preg_replace('/[\\s]*/', '', $publicize[$name]));
                         // Flag the connections we can't match with the requested list to be skipped.
                         foreach ($service_connections as $service_connection) {
                             if (!in_array($service_connection->meta['connection_data']->id, $requested_connections)) {
                                 update_post_meta($post_id, $GLOBALS['publicize_ui']->publicize->POST_SKIP . $service_connection->unique_id, 1);
                             } else {
                                 delete_post_meta($post_id, $GLOBALS['publicize_ui']->publicize->POST_SKIP . $service_connection->unique_id);
                             }
                         }
                     } else {
                         // delete all SKIP values; it's okay to publish to all connected IDs for this service
                         foreach ($service_connections as $service_connection) {
                             delete_post_meta($post_id, $GLOBALS['publicize_ui']->publicize->POST_SKIP . $service_connection->unique_id);
                         }
                     }
                 }
             }
         }
     }
     if (!empty($publicize_custom_message)) {
         update_post_meta($post_id, $GLOBALS['publicize_ui']->publicize->POST_MESS, trim($publicize_custom_message));
     }
     set_post_format($post_id, $insert['post_format']);
     if (isset($featured_image)) {
         parent::parse_and_set_featured_image($post_id, $delete_featured_image, $featured_image);
     }
     if (!empty($metadata)) {
         foreach ((array) $metadata as $meta) {
             $meta = (object) $meta;
             $existing_meta_item = new stdClass();
             if (empty($meta->operation)) {
                 $meta->operation = 'update';
             }
             if (!empty($meta->value)) {
                 if ('true' == $meta->value) {
                     $meta->value = true;
                 }
                 if ('false' == $meta->value) {
                     $meta->value = false;
                 }
             }
             if (!empty($meta->id)) {
                 $meta->id = absint($meta->id);
                 $existing_meta_item = get_metadata_by_mid('post', $meta->id);
             }
             $unslashed_meta_key = wp_unslash($meta->key);
             // should match what the final key will be
             $meta->key = wp_slash($meta->key);
             $unslashed_existing_meta_key = wp_unslash($existing_meta_item->meta_key);
             $existing_meta_item->meta_key = wp_slash($existing_meta_item->meta_key);
             // make sure that the meta id passed matches the existing meta key
             if (!empty($meta->id) && !empty($meta->key)) {
                 $meta_by_id = get_metadata_by_mid('post', $meta->id);
                 if ($meta_by_id->meta_key !== $meta->key) {
                     continue;
                     // skip this meta
                 }
             }
             switch ($meta->operation) {
                 case 'delete':
                     if (!empty($meta->id) && !empty($existing_meta_item->meta_key) && current_user_can('delete_post_meta', $post_id, $unslashed_existing_meta_key)) {
                         delete_metadata_by_mid('post', $meta->id);
                     } elseif (!empty($meta->key) && !empty($meta->previous_value) && current_user_can('delete_post_meta', $post_id, $unslashed_meta_key)) {
                         delete_post_meta($post_id, $meta->key, $meta->previous_value);
                     } elseif (!empty($meta->key) && current_user_can('delete_post_meta', $post_id, $unslashed_meta_key)) {
                         delete_post_meta($post_id, $meta->key);
                     }
                     break;
                 case 'add':
                     if (!empty($meta->id) || !empty($meta->previous_value)) {
                         continue;
                     } elseif (!empty($meta->key) && !empty($meta->value) && current_user_can('add_post_meta', $post_id, $unslashed_meta_key) || $this->is_metadata_public($meta->key)) {
                         add_post_meta($post_id, $meta->key, $meta->value);
                     }
                     break;
                 case 'update':
                     if (!isset($meta->value)) {
                         continue;
                     } elseif (!empty($meta->id) && !empty($existing_meta_item->meta_key) && (current_user_can('edit_post_meta', $post_id, $unslashed_existing_meta_key) || $this->is_metadata_public($meta->key))) {
                         update_metadata_by_mid('post', $meta->id, $meta->value);
                     } elseif (!empty($meta->key) && !empty($meta->previous_value) && (current_user_can('edit_post_meta', $post_id, $unslashed_meta_key) || $this->is_metadata_public($meta->key))) {
                         update_post_meta($post_id, $meta->key, $meta->value, $meta->previous_value);
                     } elseif (!empty($meta->key) && (current_user_can('edit_post_meta', $post_id, $unslashed_meta_key) || $this->is_metadata_public($meta->key))) {
                         update_post_meta($post_id, $meta->key, $meta->value);
                     }
                     break;
             }
         }
     }
     do_action('rest_api_inserted_post', $post_id, $insert, $new);
     $return = $this->get_post_by('ID', $post_id, $args['context']);
     if (!$return || is_wp_error($return)) {
         return $return;
     }
     if (isset($input['type']) && 'revision' === $input['type']) {
         $return['preview_nonce'] = wp_create_nonce('post_preview_' . $input['parent']);
     }
     // workaround for sticky test occasionally failing, maybe a race condition with stick_post() above
     $return['sticky'] = true === $sticky;
     if (!empty($media_results['errors'])) {
         $return['media_errors'] = $media_results['errors'];
     }
     do_action('wpcom_json_api_objects', 'posts');
     return $return;
 }
 /**
  * Delete meta from an object.
  *
  * @param WP_REST_Request $request
  * @return WP_REST_Response|WP_Error Message on success, WP_Error otherwise
  */
 public function delete_item($request)
 {
     $parent_id = (int) $request['parent_id'];
     $mid = (int) $request['id'];
     $force = isset($request['force']) ? (bool) $request['force'] : false;
     // We don't support trashing for this type, error out
     if (!$force) {
         return new WP_Error('rest_trash_not_supported', __('Meta does not support trashing.'), array('status' => 501));
     }
     $parent_column = $this->get_parent_column();
     $current = get_metadata_by_mid($this->parent_type, $mid);
     if (empty($current)) {
         return new WP_Error('rest_meta_invalid_id', __('Invalid meta id.'), array('status' => 404));
     }
     if (absint($current->{$parent_column}) !== (int) $parent_id) {
         return new WP_Error('rest_meta_' . $this->parent_type . '_mismatch', __('Meta does not belong to this object'), array('status' => 400));
     }
     // for now let's not allow updating of arrays, objects or serialized values.
     if (!$this->is_valid_meta_data($current->meta_value)) {
         $code = $this->parent_type === 'post' ? 'rest_post_invalid_action' : 'rest_meta_invalid_action';
         return new WP_Error($code, __('Invalid existing meta data for action.'), array('status' => 400));
     }
     if (is_protected_meta($current->meta_key)) {
         return new WP_Error('rest_meta_protected', sprintf(__('%s is marked as a protected field.'), $current->meta_key), array('status' => 403));
     }
     if (!delete_metadata_by_mid($this->parent_type, $mid)) {
         return new WP_Error('rest_meta_could_not_delete', __('Could not delete meta.'), array('status' => 500));
     }
     /**
      * Fires after a meta value is deleted via the REST API.
      *
      * @param WP_REST_Request $request The request sent to the API.
      */
     do_action('rest_delete_meta', $request);
     return rest_ensure_response(array('message' => __('Deleted meta')));
 }
 /**
  * General clean-up of the saved meta values
  * - Remove potentially lingering old meta keys
  * - Remove all default and invalid values
  *
  * @static
  * @return void
  */
 public static function clean_up()
 {
     global $wpdb;
     /**
      * Clean up '_yoast_wpseo_meta-robots'
      *
      * Retrieve all '_yoast_wpseo_meta-robots' meta values and convert if no new values found
      * @internal Query is pretty well optimized this way
      *
      * @todo [JRF => Yoast] find out all possible values which the old '_yoast_wpseo_meta-robots' could contain
      * to convert the data correctly
      */
     $query = $wpdb->prepare("\r\n\t\t\t\tSELECT `a`.*\r\n\t\t\t\tFROM {$wpdb->postmeta} AS a\r\n\t\t\t\tWHERE `a`.`meta_key` = %s\r\n\t\t\t\t\tAND NOT\tEXISTS (\r\n\t\t\t\t\t\tSELECT DISTINCT `post_id` , count( `meta_id` ) AS count\r\n\t\t\t\t\t\tFROM {$wpdb->postmeta} AS b\r\n\t\t\t\t\t\tWHERE `a`.`post_id` = `b`.`post_id`\r\n\t\t\t\t\t\t\tAND ( `meta_key` = %s\r\n\t\t\t\t\t\t\tOR `meta_key` = %s )\r\n\t\t\t\t\t\tGROUP BY `post_id`\r\n\t\t\t\t\t)\r\n\t\t\t\t;", self::$meta_prefix . 'meta-robots', self::$meta_prefix . 'meta-robots-noindex', self::$meta_prefix . 'meta-robots-nofollow');
     $oldies = $wpdb->get_results($query);
     if (is_array($oldies) && $oldies !== array()) {
         foreach ($oldies as $old) {
             $old_values = explode(',', $old->meta_value);
             foreach ($old_values as $value) {
                 if ($value === 'noindex') {
                     update_post_meta($old->post_id, self::$meta_prefix . 'meta-robots-noindex', 1);
                 } elseif ($value === 'nofollow') {
                     update_post_meta($old->post_id, self::$meta_prefix . 'meta-robots-nofollow', 1);
                 }
             }
         }
     }
     unset($query, $oldies, $old, $old_values, $value);
     // Delete old keys
     delete_post_meta_by_key(self::$meta_prefix . 'meta-robots');
     /**
      * Remove all default values and (most) invalid option values
      * Invalid option values for the multiselect (meta-robots-adv) field will be dealt with seperately
      *
      * @internal some of the defaults have changed in v1.5, but as the defaults will be removed and
      * new defaults will now automatically be passed when no data found, this update is automatic
      * (as long as we remove the old values which we do in the below routine)
      *
      * @internal unfortunately we can't use the normal delete_meta() with key/value combination as ''
      * (empty string) values will be ignored and would result in all metas with that key being deleted,
      * not just the empty fields.
      * Still, the below implementation is largely based on the delete_meta() function
      */
     $query = array();
     foreach (self::$meta_fields as $subset => $field_group) {
         foreach ($field_group as $key => $field_def) {
             if ($field_def['type'] === 'snippetpreview' || !isset($field_def['default_value'])) {
                 continue;
             }
             if ($key === 'meta-robots-adv') {
                 $query[] = $wpdb->prepare("( meta_key = %s AND ( meta_value = 'none' OR meta_value = '-' ) )", self::$meta_prefix . $key);
             } elseif (isset($field_def['options']) && is_array($field_def['options']) && $field_def['options'] !== array()) {
                 $valid = $field_def['options'];
                 // remove the default value from the valid options
                 unset($valid[$field_def['default_value']]);
                 $valid = array_keys($valid);
                 $query[] = $wpdb->prepare("( meta_key = %s AND meta_value NOT IN ( '" . implode("','", esc_sql($valid)) . "' ) )", self::$meta_prefix . $key);
                 unset($valid);
             } elseif (is_string($field_def['default_value']) && $field_def['default_value'] !== '') {
                 $query[] = $wpdb->prepare('( meta_key = %s AND meta_value = %s )', self::$meta_prefix . $key, $field_def['default_value']);
             } else {
                 $query[] = $wpdb->prepare("( meta_key = %s AND meta_value = '' )", self::$meta_prefix . $key);
             }
         }
     }
     unset($subset, $field_group, $key, $field_def, $where_or_or);
     $query = "SELECT meta_id FROM {$wpdb->postmeta} WHERE " . implode(' OR ', $query) . ';';
     $meta_ids = $wpdb->get_col($query);
     if (is_array($meta_ids) && $meta_ids !== array()) {
         // wp native action
         do_action('delete_post_meta', $meta_ids, null, null, null);
         $query = "DELETE FROM {$wpdb->postmeta} WHERE meta_id IN( " . implode(',', $meta_ids) . ' )';
         $count = $wpdb->query($query);
         if ($count) {
             foreach ($meta_ids as $object_id) {
                 wp_cache_delete($object_id, 'post_meta');
             }
             // wp native action
             do_action('deleted_post_meta', $meta_ids, null, null, null);
         }
     }
     unset($query, $meta_ids, $count, $object_id);
     /**
      * Deal with the multiselect (meta-robots-adv) field
      *
      * Removes invalid option combinations, such as 'none,noarchive'
      *
      * Default values have already been removed, so we should have a small result set and
      * (hopefully) even smaller set of invalid results.
      */
     $query = $wpdb->prepare("SELECT meta_id, meta_value FROM {$wpdb->postmeta} WHERE meta_key = %s", self::$meta_prefix . 'meta-robots-adv');
     $oldies = $wpdb->get_results($query);
     if (is_array($oldies) && $oldies !== array()) {
         foreach ($oldies as $old) {
             $clean = self::validate_meta_robots_adv($old->meta_value);
             if ($clean !== $old->meta_value) {
                 if ($clean !== self::$meta_fields['advanced']['meta-robots-adv']['default_value']) {
                     update_metadata_by_mid('post', $old->meta_id, $clean);
                 } else {
                     delete_metadata_by_mid('post', $old->meta_id);
                 }
             }
         }
     }
     unset($query, $oldies, $old, $clean);
     do_action('wpseo_meta_clean_up');
 }
 function write_post($path, $blog_id, $post_id)
 {
     $new = $this->api->ends_with($path, '/new');
     $args = $this->query_args();
     if ($new) {
         $input = $this->input(true);
         if (!isset($input['title']) && !isset($input['content']) && !isset($input['excerpt'])) {
             return new WP_Error('invalid_input', 'Invalid request input', 400);
         }
         // default to post
         if (empty($input['type'])) {
             $input['type'] = 'post';
         }
         $post_type = get_post_type_object($input['type']);
         if (!$this->is_post_type_allowed($input['type'])) {
             return new WP_Error('unknown_post_type', 'Unknown post type', 404);
         }
         if ('publish' === $input['status']) {
             if (!current_user_can($post_type->cap->publish_posts)) {
                 if (current_user_can($post_type->cap->edit_posts)) {
                     $input['status'] = 'pending';
                 } else {
                     return new WP_Error('unauthorized', 'User cannot publish posts', 403);
                 }
             }
         } else {
             if (!current_user_can($post_type->cap->edit_posts)) {
                 return new WP_Error('unauthorized', 'User cannot edit posts', 403);
             }
         }
     } else {
         $input = $this->input(false);
         if (!is_array($input) || !$input) {
             return new WP_Error('invalid_input', 'Invalid request input', 400);
         }
         $post = get_post($post_id);
         if (!$post || is_wp_error($post)) {
             return new WP_Error('unknown_post', 'Unknown post', 404);
         }
         if (!current_user_can('edit_post', $post->ID)) {
             return new WP_Error('unauthorized', 'User cannot edit post', 403);
         }
         if ('publish' === $input['status'] && 'publish' !== $post->post_status && !current_user_can('publish_post', $post->ID)) {
             $input['status'] = 'pending';
         }
         $post_type = get_post_type_object($post->post_type);
     }
     if (!is_post_type_hierarchical($post_type->name)) {
         unset($input['parent']);
     }
     $categories = null;
     $tags = null;
     if (!empty($input['categories'])) {
         if (is_array($input['categories'])) {
             $_categories = $input['categories'];
         } else {
             foreach (explode(',', $input['categories']) as $category) {
                 $_categories[] = $category;
             }
         }
         foreach ($_categories as $category) {
             if (!($category_info = term_exists($category, 'category'))) {
                 if (is_int($category)) {
                     continue;
                 }
                 $category_info = wp_insert_term($category, 'category');
             }
             if (!is_wp_error($category_info)) {
                 $categories[] = (int) $category_info['term_id'];
             }
         }
     }
     if (!empty($input['tags'])) {
         if (is_array($input['tags'])) {
             $tags = $input['tags'];
         } else {
             foreach (explode(',', $input['tags']) as $tag) {
                 $tags[] = $tag;
             }
         }
         $tags_string = implode(',', $tags);
     }
     unset($input['tags'], $input['categories']);
     $insert = array();
     if (!empty($input['slug'])) {
         $insert['post_name'] = $input['slug'];
         unset($input['slug']);
     }
     if (true === $input['comments_open']) {
         $insert['comment_status'] = 'open';
     } else {
         if (false === $input['comments_open']) {
             $insert['comment_status'] = 'closed';
         }
     }
     if (true === $input['pings_open']) {
         $insert['ping_status'] = 'open';
     } else {
         if (false === $input['pings_open']) {
             $insert['ping_status'] = 'closed';
         }
     }
     unset($input['comments_open'], $input['pings_open']);
     $publicize = $input['publicize'];
     $publicize_custom_message = $input['publicize_message'];
     unset($input['publicize'], $input['publicize_message']);
     $metadata = $input['metadata'];
     unset($input['metadata']);
     foreach ($input as $key => $value) {
         $insert["post_{$key}"] = $value;
     }
     if (!empty($tags)) {
         $insert["tax_input"]["post_tag"] = $tags;
     }
     if (!empty($categories)) {
         $insert["tax_input"]["category"] = $categories;
     }
     $has_media = isset($input['media']) && $input['media'] ? count($input['media']) : false;
     if ($new) {
         if (false === strpos($input['content'], '[gallery') && $has_media) {
             switch ($has_media) {
                 case 0:
                     // No images - do nothing.
                     break;
                 case 1:
                     // 1 image - make it big
                     $insert['post_content'] = $input['content'] = "[gallery size=full columns=1]\n\n" . $input['content'];
                     break;
                 default:
                     // Several images - 3 column gallery
                     $insert['post_content'] = $input['content'] = "[gallery]\n\n" . $input['content'];
                     break;
             }
         }
         $post_id = wp_insert_post(add_magic_quotes($insert), true);
         if ($has_media) {
             $this->api->trap_wp_die('upload_error');
             foreach ($input['media'] as $media_item) {
                 $_FILES['.api.media.item.'] = $media_item;
                 // check for WP_Error if we ever actually need $media_id
                 $media_id = media_handle_upload('.api.media.item.', $post_id);
             }
             $this->api->trap_wp_die(null);
             unset($_FILES['.api.media.item.']);
         }
     } else {
         $insert['ID'] = $post->ID;
         $post_id = wp_update_post((object) $insert);
     }
     if (!$post_id || is_wp_error($post_id)) {
         return $post_id;
     }
     if ($publicize === false) {
         foreach ($GLOBALS['publicize_ui']->publicize->get_services('all') as $name => $service) {
             update_post_meta($post_id, $GLOBALS['publicize_ui']->publicize->POST_SKIP . $name, 1);
         }
     } else {
         if (is_array($publicize) && count($publicize) > 0) {
             foreach ($GLOBALS['publicize_ui']->publicize->get_services('all') as $name => $service) {
                 if (!in_array($name, $publicize)) {
                     update_post_meta($post_id, $GLOBALS['publicize_ui']->publicize->POST_SKIP . $name, 1);
                 }
             }
         }
     }
     if (!empty($publicize_custom_message)) {
         update_post_meta($post_id, $GLOBALS['publicize_ui']->publicize->POST_MESS, trim($publicize_custom_message));
     }
     set_post_format($post_id, $insert['post_format']);
     if (!empty($metadata)) {
         foreach ((array) $metadata as $meta) {
             $meta = (object) $meta;
             $existing_meta_item = new stdClass();
             if (empty($meta->operation)) {
                 $meta->operation = 'update';
             }
             if (!empty($meta->value)) {
                 if ('true' == $meta->value) {
                     $meta->value = true;
                 }
                 if ('false' == $meta->value) {
                     $meta->value = false;
                 }
             }
             if (!empty($meta->id)) {
                 $meta->id = absint($meta->id);
                 $existing_meta_item = get_metadata_by_mid('post', $meta->id);
             }
             $unslashed_meta_key = wp_unslash($meta->key);
             // should match what the final key will be
             $meta->key = wp_slash($meta->key);
             $unslashed_existing_meta_key = wp_unslash($existing_meta_item->meta_key);
             $existing_meta_item->meta_key = wp_slash($existing_meta_item->meta_key);
             switch ($meta->operation) {
                 case 'delete':
                     if (!empty($meta->id) && !empty($existing_meta_item->meta_key) && current_user_can('delete_post_meta', $post_id, $unslashed_existing_meta_key)) {
                         delete_metadata_by_mid('post', $meta->id);
                     } elseif (!empty($meta->key) && !empty($meta->previous_value) && current_user_can('delete_post_meta', $post_id, $unslashed_meta_key)) {
                         delete_post_meta($post_id, $meta->key, $meta->previous_value);
                     } elseif (!empty($meta->key) && current_user_can('delete_post_meta', $post_id, $unslashed_meta_key)) {
                         delete_post_meta($post_id, $meta->key);
                     }
                     break;
                 case 'add':
                     if (!empty($meta->id) || !empty($meta->previous_value)) {
                         continue;
                     } elseif (!empty($meta->key) && !empty($meta->value) && current_user_can('add_post_meta', $post_id, $unslashed_meta_key)) {
                         add_post_meta($post_id, $meta->key, $meta->value);
                     }
                     break;
                 case 'update':
                     if (empty($meta->value)) {
                         continue;
                     } elseif (!empty($meta->id) && !empty($existing_meta_item->meta_key) && current_user_can('edit_post_meta', $post_id, $unslashed_existing_meta_key)) {
                         update_metadata_by_mid('post', $meta->id, $meta->value);
                     } elseif (!empty($meta->key) && !empty($meta->previous_value) && current_user_can('edit_post_meta', $post_id, $unslashed_meta_key)) {
                         update_post_meta($post_id, $meta->key, $meta->value, $meta->previous_value);
                     } elseif (!empty($meta->key) && current_user_can('edit_post_meta', $post_id, $unslashed_meta_key)) {
                         update_post_meta($post_id, $meta->key, $meta->value);
                     }
                     break;
             }
         }
     }
     do_action('rest_api_inserted_post', $post_id, $insert, $new);
     $return = $this->get_post_by('ID', $post_id, $args['context']);
     if (!$return || is_wp_error($return)) {
         return $return;
     }
     do_action('wpcom_json_api_objects', 'posts');
     return $return;
 }
 /**
  * Decrease usage count for current coupon.
  *
  * @param string $used_by Either user ID or billing email
  */
 public function dcr_usage_count($used_by = '')
 {
     if ($this->id && $this->usage_count > 0) {
         global $wpdb;
         $this->usage_count--;
         update_post_meta($this->id, 'usage_count', $this->usage_count);
         if ($used_by) {
             /**
              * We're doing this the long way because `delete_post_meta( $id, $key, $value )` deletes.
              * all instances where the key and value match, and we only want to delete one.
              */
             $meta_id = $wpdb->get_var($wpdb->prepare("SELECT meta_id FROM {$wpdb->postmeta} WHERE meta_key = '_used_by' AND meta_value = %s AND post_id = %d LIMIT 1;", $used_by, $this->id));
             if ($meta_id) {
                 delete_metadata_by_mid('post', $meta_id);
             }
         }
     }
 }
Beispiel #24
0
/**
 * Remove user and optionally reassign posts and links to another user.
 *
 * If the $reassign parameter is not assigned to an User ID, then all posts will
 * be deleted of that user. The action 'delete_user' that is passed the User ID
 * being deleted will be run after the posts are either reassigned or deleted.
 * The user meta will also be deleted that are for that User ID.
 *
 * @since 2.0.0
 *
 * @param int $id User ID.
 * @param int $reassign Optional. Reassign posts and links to new User ID.
 * @return bool True when finished.
 */
function wp_delete_user($id, $reassign = 'novalue')
{
    global $wpdb;
    $id = (int) $id;
    $user = new WP_User($id);
    // allow for transaction statement
    do_action('delete_user', $id);
    if ('novalue' === $reassign || null === $reassign) {
        $post_types_to_delete = array();
        foreach (get_post_types(array(), 'objects') as $post_type) {
            if ($post_type->delete_with_user) {
                $post_types_to_delete[] = $post_type->name;
            } elseif (null === $post_type->delete_with_user && post_type_supports($post_type->name, 'author')) {
                $post_types_to_delete[] = $post_type->name;
            }
        }
        $post_types_to_delete = apply_filters('post_types_to_delete_with_user', $post_types_to_delete, $id);
        $post_types_to_delete = implode("', '", $post_types_to_delete);
        $post_ids = $wpdb->get_col($wpdb->prepare("SELECT ID FROM {$wpdb->posts} WHERE post_author = %d AND post_type IN ('{$post_types_to_delete}')", $id));
        if ($post_ids) {
            foreach ($post_ids as $post_id) {
                wp_delete_post($post_id);
            }
        }
        // Clean links
        $link_ids = $wpdb->get_col($wpdb->prepare("SELECT link_id FROM {$wpdb->links} WHERE link_owner = %d", $id));
        if ($link_ids) {
            foreach ($link_ids as $link_id) {
                wp_delete_link($link_id);
            }
        }
    } else {
        $reassign = (int) $reassign;
        $wpdb->update($wpdb->posts, array('post_author' => $reassign), array('post_author' => $id));
        $wpdb->update($wpdb->links, array('link_owner' => $reassign), array('link_owner' => $id));
    }
    // FINALLY, delete user
    if (is_multisite()) {
        remove_user_from_blog($id, get_current_blog_id());
    } else {
        $meta = $wpdb->get_col($wpdb->prepare("SELECT umeta_id FROM {$wpdb->usermeta} WHERE user_id = %d", $id));
        foreach ($meta as $mid) {
            delete_metadata_by_mid('user', $mid);
        }
        $wpdb->delete($wpdb->users, array('ID' => $id));
    }
    clean_user_cache($user);
    // allow for commit transaction
    do_action('deleted_user', $id);
    return true;
}
/**
 * Removes a term from the database.
 *
 * If the term is a parent of other terms, then the children will be updated to
 * that term's parent.
 *
 * Metadata associated with the term will be deleted.
 *
 * The `$args` 'default' will only override the terms found, if there is only one
 * term found. Any other and the found terms are used.
 *
 * The $args 'force_default' will force the term supplied as default to be
 * assigned even if the object was not going to be termless
 *
 * @todo Document $args as a hash notation.
 *
 * @since 2.3.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param int          $term     Term ID.
 * @param string       $taxonomy Taxonomy Name.
 * @param array|string $args     Optional. Change 'default' term id and override found term ids.
 * @return bool|int|WP_Error Returns false if not term; true if completes delete action.
 */
function wp_delete_term($term, $taxonomy, $args = array())
{
    global $wpdb;
    $term = (int) $term;
    if (!($ids = term_exists($term, $taxonomy))) {
        return false;
    }
    if (is_wp_error($ids)) {
        return $ids;
    }
    $tt_id = $ids['term_taxonomy_id'];
    $defaults = array();
    if ('category' == $taxonomy) {
        $defaults['default'] = get_option('default_category');
        if ($defaults['default'] == $term) {
            return 0;
        }
        // Don't delete the default category
    }
    $args = wp_parse_args($args, $defaults);
    if (isset($args['default'])) {
        $default = (int) $args['default'];
        if (!term_exists($default, $taxonomy)) {
            unset($default);
        }
    }
    if (isset($args['force_default'])) {
        $force_default = $args['force_default'];
    }
    /**
     * Fires when deleting a term, before any modifications are made to posts or terms.
     *
     * @since 4.1.0
     *
     * @param int    $term     Term ID.
     * @param string $taxonomy Taxonomy Name.
     */
    do_action('pre_delete_term', $term, $taxonomy);
    // Update children to point to new parent
    if (is_taxonomy_hierarchical($taxonomy)) {
        $term_obj = get_term($term, $taxonomy);
        if (is_wp_error($term_obj)) {
            return $term_obj;
        }
        $parent = $term_obj->parent;
        $edit_ids = $wpdb->get_results("SELECT term_id, term_taxonomy_id FROM {$wpdb->term_taxonomy} WHERE `parent` = " . (int) $term_obj->term_id);
        $edit_tt_ids = wp_list_pluck($edit_ids, 'term_taxonomy_id');
        /**
         * Fires immediately before a term to delete's children are reassigned a parent.
         *
         * @since 2.9.0
         *
         * @param array $edit_tt_ids An array of term taxonomy IDs for the given term.
         */
        do_action('edit_term_taxonomies', $edit_tt_ids);
        $wpdb->update($wpdb->term_taxonomy, compact('parent'), array('parent' => $term_obj->term_id) + compact('taxonomy'));
        // Clean the cache for all child terms.
        $edit_term_ids = wp_list_pluck($edit_ids, 'term_id');
        clean_term_cache($edit_term_ids, $taxonomy);
        /**
         * Fires immediately after a term to delete's children are reassigned a parent.
         *
         * @since 2.9.0
         *
         * @param array $edit_tt_ids An array of term taxonomy IDs for the given term.
         */
        do_action('edited_term_taxonomies', $edit_tt_ids);
    }
    // Get the term before deleting it or its term relationships so we can pass to actions below.
    $deleted_term = get_term($term, $taxonomy);
    $objects = $wpdb->get_col($wpdb->prepare("SELECT object_id FROM {$wpdb->term_relationships} WHERE term_taxonomy_id = %d", $tt_id));
    foreach ((array) $objects as $object) {
        $terms = wp_get_object_terms($object, $taxonomy, array('fields' => 'ids', 'orderby' => 'none'));
        if (1 == count($terms) && isset($default)) {
            $terms = array($default);
        } else {
            $terms = array_diff($terms, array($term));
            if (isset($default) && isset($force_default) && $force_default) {
                $terms = array_merge($terms, array($default));
            }
        }
        $terms = array_map('intval', $terms);
        wp_set_object_terms($object, $terms, $taxonomy);
    }
    // Clean the relationship caches for all object types using this term.
    $tax_object = get_taxonomy($taxonomy);
    foreach ($tax_object->object_type as $object_type) {
        clean_object_term_cache($objects, $object_type);
    }
    $term_meta_ids = $wpdb->get_col($wpdb->prepare("SELECT meta_id FROM {$wpdb->termmeta} WHERE term_id = %d ", $term));
    foreach ($term_meta_ids as $mid) {
        delete_metadata_by_mid('term', $mid);
    }
    /**
     * Fires immediately before a term taxonomy ID is deleted.
     *
     * @since 2.9.0
     *
     * @param int $tt_id Term taxonomy ID.
     */
    do_action('delete_term_taxonomy', $tt_id);
    $wpdb->delete($wpdb->term_taxonomy, array('term_taxonomy_id' => $tt_id));
    /**
     * Fires immediately after a term taxonomy ID is deleted.
     *
     * @since 2.9.0
     *
     * @param int $tt_id Term taxonomy ID.
     */
    do_action('deleted_term_taxonomy', $tt_id);
    // Delete the term if no taxonomies use it.
    if (!$wpdb->get_var($wpdb->prepare("SELECT COUNT(*) FROM {$wpdb->term_taxonomy} WHERE term_id = %d", $term))) {
        $wpdb->delete($wpdb->terms, array('term_id' => $term));
    }
    clean_term_cache($term, $taxonomy);
    /**
     * Fires after a term is deleted from the database and the cache is cleaned.
     *
     * @since 2.5.0
     *
     * @param int     $term         Term ID.
     * @param int     $tt_id        Term taxonomy ID.
     * @param string  $taxonomy     Taxonomy slug.
     * @param mixed   $deleted_term Copy of the already-deleted term, in the form specified
     *                              by the parent function. WP_Error otherwise.
     */
    do_action('delete_term', $term, $tt_id, $taxonomy, $deleted_term);
    /**
     * Fires after a term in a specific taxonomy is deleted.
     *
     * The dynamic portion of the hook name, `$taxonomy`, refers to the specific
     * taxonomy the term belonged to.
     *
     * @since 2.3.0
     *
     * @param int     $term         Term ID.
     * @param int     $tt_id        Term taxonomy ID.
     * @param mixed   $deleted_term Copy of the already-deleted term, in the form specified
     *                              by the parent function. WP_Error otherwise.
     */
    do_action("delete_{$taxonomy}", $term, $tt_id, $deleted_term);
    return true;
}
Beispiel #26
0
 /**
  * @ticket 28315
  */
 function test_non_numeric_meta_id()
 {
     $this->assertFalse(get_metadata_by_mid('user', array(1)));
     $this->assertFalse(update_metadata_by_mid('user', array(1), 'meta_new_value'));
     $this->assertFalse(delete_metadata_by_mid('user', array(1)));
 }
Beispiel #27
0
/**
 * Check content for video and audio links to add as enclosures.
 *
 * Will not add enclosures that have already been added and will
 * remove enclosures that are no longer in the post. This is called as
 * pingbacks and trackbacks.
 *
 * @since 1.5.0
 *
 * @global wpdb $wpdb
 *
 * @param string $content Post Content.
 * @param int    $post_ID Post ID.
 */
function do_enclose($content, $post_ID)
{
    global $wpdb;
    //TODO: Tidy this ghetto code up and make the debug code optional
    include_once ABSPATH . WPINC . '/class-IXR.php';
    $post_links = array();
    $pung = get_enclosed($post_ID);
    $post_links_temp = wp_extract_urls($content);
    foreach ($pung as $link_test) {
        if (!in_array($link_test, $post_links_temp)) {
            // link no longer in post
            $mids = $wpdb->get_col($wpdb->prepare("SELECT meta_id FROM {$wpdb->postmeta} WHERE post_id = %d AND meta_key = 'enclosure' AND meta_value LIKE %s", $post_ID, $wpdb->esc_like($link_test) . '%'));
            foreach ($mids as $mid) {
                delete_metadata_by_mid('post', $mid);
            }
        }
    }
    foreach ((array) $post_links_temp as $link_test) {
        if (!in_array($link_test, $pung)) {
            // If we haven't pung it already
            $test = @parse_url($link_test);
            if (false === $test) {
                continue;
            }
            if (isset($test['query'])) {
                $post_links[] = $link_test;
            } elseif (isset($test['path']) && $test['path'] != '/' && $test['path'] != '') {
                $post_links[] = $link_test;
            }
        }
    }
    foreach ((array) $post_links as $url) {
        if ($url != '' && !$wpdb->get_var($wpdb->prepare("SELECT post_id FROM {$wpdb->postmeta} WHERE post_id = %d AND meta_key = 'enclosure' AND meta_value LIKE %s", $post_ID, $wpdb->esc_like($url) . '%'))) {
            if ($headers = wp_get_http_headers($url)) {
                $len = isset($headers['content-length']) ? (int) $headers['content-length'] : 0;
                $type = isset($headers['content-type']) ? $headers['content-type'] : '';
                $allowed_types = array('video', 'audio');
                // Check to see if we can figure out the mime type from
                // the extension
                $url_parts = @parse_url($url);
                if (false !== $url_parts) {
                    $extension = pathinfo($url_parts['path'], PATHINFO_EXTENSION);
                    if (!empty($extension)) {
                        foreach (wp_get_mime_types() as $exts => $mime) {
                            if (preg_match('!^(' . $exts . ')$!i', $extension)) {
                                $type = $mime;
                                break;
                            }
                        }
                    }
                }
                if (in_array(substr($type, 0, strpos($type, "/")), $allowed_types)) {
                    add_post_meta($post_ID, 'enclosure', "{$url}\n{$len}\n{$mime}\n");
                }
            }
        }
    }
}
 function write_post($path, $blog_id, $post_id)
 {
     $new = $this->api->ends_with($path, '/new');
     $args = $this->query_args();
     // unhook publicize, it's hooked again later -- without this, skipping services is impossible
     if (defined('IS_WPCOM') && IS_WPCOM) {
         remove_action('save_post', array($GLOBALS['publicize_ui']->publicize, 'async_publicize_post'), 100, 2);
         add_action('rest_api_inserted_post', array($GLOBALS['publicize_ui']->publicize, 'async_publicize_post'));
     }
     if ($new) {
         $input = $this->input(true);
         if ('revision' === $input['type']) {
             if (!isset($input['parent'])) {
                 return new WP_Error('invalid_input', 'Invalid request input', 400);
             }
             $input['status'] = 'inherit';
             // force inherit for revision type
             $input['slug'] = $input['parent'] . '-autosave-v1';
         } elseif (!isset($input['title']) && !isset($input['content']) && !isset($input['excerpt'])) {
             return new WP_Error('invalid_input', 'Invalid request input', 400);
         }
         // default to post
         if (empty($input['type'])) {
             $input['type'] = 'post';
         }
         $post_type = get_post_type_object($input['type']);
         if (!$this->is_post_type_allowed($input['type'])) {
             return new WP_Error('unknown_post_type', 'Unknown post type', 404);
         }
         if (!empty($input['author'])) {
             $author_id = $this->parse_and_set_author($input['author'], $input['type']);
             unset($input['author']);
             if (is_wp_error($author_id)) {
                 return $author_id;
             }
         }
         if ('publish' === $input['status']) {
             if (!current_user_can($post_type->cap->publish_posts)) {
                 if (current_user_can($post_type->cap->edit_posts)) {
                     $input['status'] = 'pending';
                 } else {
                     return new WP_Error('unauthorized', 'User cannot publish posts', 403);
                 }
             }
         } else {
             if (!current_user_can($post_type->cap->edit_posts)) {
                 return new WP_Error('unauthorized', 'User cannot edit posts', 403);
             }
         }
     } else {
         $input = $this->input(false);
         if (!is_array($input) || !$input) {
             return new WP_Error('invalid_input', 'Invalid request input', 400);
         }
         $post = get_post($post_id);
         $_post_type = !empty($input['type']) ? $input['type'] : $post->post_type;
         $post_type = get_post_type_object($_post_type);
         if (!$post || is_wp_error($post)) {
             return new WP_Error('unknown_post', 'Unknown post', 404);
         }
         if (!current_user_can('edit_post', $post->ID)) {
             return new WP_Error('unauthorized', 'User cannot edit post', 403);
         }
         if (!empty($input['author'])) {
             $author_id = $this->parse_and_set_author($input['author'], $_post_type);
             unset($input['author']);
             if (is_wp_error($author_id)) {
                 return $author_id;
             }
         }
         if (isset($input['status']) && 'publish' === $input['status'] && 'publish' !== $post->post_status && !current_user_can('publish_post', $post->ID)) {
             $input['status'] = 'pending';
         }
         $last_status = $post->post_status;
         $new_status = isset($input['status']) ? $input['status'] : $last_status;
         // Make sure that drafts get the current date when transitioning to publish if not supplied in the post.
         $date_in_past = strtotime($post->post_date_gmt) < time();
         if ('publish' === $new_status && 'draft' === $last_status && !isset($input['date_gmt']) && $date_in_past) {
             $input['date_gmt'] = gmdate('Y-m-d H:i:s');
         }
     }
     // If date is set, $this->input will set date_gmt, date still needs to be adjusted for the blog's offset
     if (isset($input['date_gmt'])) {
         $gmt_offset = get_option('gmt_offset');
         $time_with_offset = strtotime($input['date_gmt']) + $gmt_offset * HOUR_IN_SECONDS;
         $input['date'] = date('Y-m-d H:i:s', $time_with_offset);
     }
     if (!empty($author_id) && get_current_user_id() != $author_id) {
         if (!current_user_can($post_type->cap->edit_others_posts)) {
             return new WP_Error('unauthorized', "User is not allowed to publish others' posts.", 403);
         } elseif (!user_can($author_id, $post_type->cap->edit_posts)) {
             return new WP_Error('unauthorized', 'Assigned author cannot publish post.', 403);
         }
     }
     if (!is_post_type_hierarchical($post_type->name) && 'revision' !== $post_type->name) {
         unset($input['parent']);
     }
     $tax_input = array();
     foreach (array('categories' => 'category', 'tags' => 'post_tag') as $key => $taxonomy) {
         if (!isset($input[$key])) {
             continue;
         }
         $tax_input[$taxonomy] = array();
         $is_hierarchical = is_taxonomy_hierarchical($taxonomy);
         if (is_array($input[$key])) {
             $terms = $input[$key];
         } else {
             $terms = explode(',', $input[$key]);
         }
         foreach ($terms as $term) {
             /**
              * `curl --data 'category[]=123'` should be interpreted as a category ID,
              * not a category whose name is '123'.
              *
              * Consequence: To add a category/tag whose name is '123', the client must
              * first look up its ID.
              */
             if (ctype_digit($term)) {
                 $term = (int) $term;
             }
             $term_info = term_exists($term, $taxonomy);
             if (!$term_info) {
                 // A term ID that doesn't already exist. Ignore it: we don't know what name to give it.
                 if (is_int($term)) {
                     continue;
                 }
                 // only add a new tag/cat if the user has access to
                 $tax = get_taxonomy($taxonomy);
                 if (!current_user_can($tax->cap->edit_terms)) {
                     continue;
                 }
                 $term_info = wp_insert_term($term, $taxonomy);
             }
             if (!is_wp_error($term_info)) {
                 if ($is_hierarchical) {
                     // Categories must be added by ID
                     $tax_input[$taxonomy][] = (int) $term_info['term_id'];
                 } else {
                     // Tags must be added by name
                     if (is_int($term)) {
                         $term = get_term($term, $taxonomy);
                         $tax_input[$taxonomy][] = $term->name;
                     } else {
                         $tax_input[$taxonomy][] = $term;
                     }
                 }
             }
         }
     }
     if (isset($input['categories']) && empty($tax_input['category']) && 'revision' !== $post_type->name) {
         $tax_input['category'][] = get_option('default_category');
     }
     unset($input['tags'], $input['categories']);
     $insert = array();
     if (!empty($input['slug'])) {
         $insert['post_name'] = $input['slug'];
         unset($input['slug']);
     }
     if (isset($input['comments_open'])) {
         $insert['comment_status'] = true === $input['comments_open'] ? 'open' : 'closed';
     }
     if (isset($input['pings_open'])) {
         $insert['ping_status'] = true === $input['pings_open'] ? 'open' : 'closed';
     }
     unset($input['comments_open'], $input['pings_open']);
     if (isset($input['menu_order'])) {
         $insert['menu_order'] = $input['menu_order'];
         unset($input['menu_order']);
     }
     $publicize = isset($input['publicize']) ? $input['publicize'] : null;
     unset($input['publicize']);
     $publicize_custom_message = isset($input['publicize_message']) ? $input['publicize_message'] : null;
     unset($input['publicize_message']);
     if (isset($input['featured_image'])) {
         $featured_image = trim($input['featured_image']);
         $delete_featured_image = empty($featured_image);
         unset($input['featured_image']);
     }
     $metadata = isset($input['metadata']) ? $input['metadata'] : null;
     unset($input['metadata']);
     $likes = isset($input['likes_enabled']) ? $input['likes_enabled'] : null;
     unset($input['likes_enabled']);
     $sharing = isset($input['sharing_enabled']) ? $input['sharing_enabled'] : null;
     unset($input['sharing_enabled']);
     $sticky = isset($input['sticky']) ? $input['sticky'] : null;
     unset($input['sticky']);
     foreach ($input as $key => $value) {
         $insert["post_{$key}"] = $value;
     }
     if (!empty($author_id)) {
         $insert['post_author'] = absint($author_id);
     }
     if (!empty($tax_input)) {
         $insert['tax_input'] = $tax_input;
     }
     $has_media = isset($input['media']) && $input['media'] ? count($input['media']) : false;
     $has_media_by_url = isset($input['media_urls']) && $input['media_urls'] ? count($input['media_urls']) : false;
     if ($new) {
         if (isset($input['content']) && !has_shortcode($input['content'], 'gallery') && ($has_media || $has_media_by_url)) {
             switch ($has_media + $has_media_by_url) {
                 case 0:
                     // No images - do nothing.
                     break;
                 case 1:
                     // 1 image - make it big
                     $insert['post_content'] = $input['content'] = "[gallery size=full columns=1]\n\n" . $input['content'];
                     break;
                 default:
                     // Several images - 3 column gallery
                     $insert['post_content'] = $input['content'] = "[gallery]\n\n" . $input['content'];
                     break;
             }
         }
         $post_id = wp_insert_post(add_magic_quotes($insert), true);
     } else {
         $insert['ID'] = $post->ID;
         // wp_update_post ignores date unless edit_date is set
         // See: http://codex.wordpress.org/Function_Reference/wp_update_post#Scheduling_posts
         // See: https://core.trac.wordpress.org/browser/tags/3.9.2/src/wp-includes/post.php#L3302
         if (isset($input['date_gmt']) || isset($input['date'])) {
             $insert['edit_date'] = true;
         }
         $post_id = wp_update_post((object) $insert);
     }
     if (!$post_id || is_wp_error($post_id)) {
         return $post_id;
     }
     // make sure this post actually exists and is not an error of some kind (ie, trying to load media in the posts endpoint)
     $post_check = $this->get_post_by('ID', $post_id, $args['context']);
     if (is_wp_error($post_check)) {
         return $post_check;
     }
     if ($has_media) {
         $this->api->trap_wp_die('upload_error');
         foreach ($input['media'] as $media_item) {
             $_FILES['.api.media.item.'] = $media_item;
             // check for WP_Error if we ever actually need $media_id
             $media_id = media_handle_upload('.api.media.item.', $post_id);
         }
         $this->api->trap_wp_die(null);
         unset($_FILES['.api.media.item.']);
     }
     if ($has_media_by_url) {
         foreach ($input['media_urls'] as $url) {
             $this->handle_media_sideload($url, $post_id);
         }
     }
     // Set like status for the post
     /** This filter is documented in modules/likes.php */
     $sitewide_likes_enabled = (bool) apply_filters('wpl_is_enabled_sitewide', !get_option('disabled_likes'));
     if ($new) {
         if ($sitewide_likes_enabled) {
             if (false === $likes) {
                 update_post_meta($post_id, 'switch_like_status', 1);
             } else {
                 delete_post_meta($post_id, 'switch_like_status');
             }
         } else {
             if ($likes) {
                 update_post_meta($post_id, 'switch_like_status', 1);
             } else {
                 delete_post_meta($post_id, 'switch_like_status');
             }
         }
     } else {
         if (isset($likes)) {
             if ($sitewide_likes_enabled) {
                 if (false === $likes) {
                     update_post_meta($post_id, 'switch_like_status', 1);
                 } else {
                     delete_post_meta($post_id, 'switch_like_status');
                 }
             } else {
                 if (true === $likes) {
                     update_post_meta($post_id, 'switch_like_status', 1);
                 } else {
                     delete_post_meta($post_id, 'switch_like_status');
                 }
             }
         }
     }
     // Set sharing status of the post
     if ($new) {
         $sharing_enabled = isset($sharing) ? (bool) $sharing : true;
         if (false === $sharing_enabled) {
             update_post_meta($post_id, 'sharing_disabled', 1);
         }
     } else {
         if (isset($sharing) && true === $sharing) {
             delete_post_meta($post_id, 'sharing_disabled');
         } else {
             if (isset($sharing) && false == $sharing) {
                 update_post_meta($post_id, 'sharing_disabled', 1);
             }
         }
     }
     if (isset($sticky)) {
         if (true === $sticky) {
             stick_post($post_id);
         } else {
             unstick_post($post_id);
         }
     }
     // WPCOM Specific (Jetpack's will get bumped elsewhere
     // Tracks how many posts are published and sets meta
     // so we can track some other cool stats (like likes & comments on posts published)
     if (defined('IS_WPCOM') && IS_WPCOM) {
         if ($new && 'publish' == $input['status'] || !$new && isset($last_status) && 'publish' != $last_status && isset($new_status) && 'publish' == $new_status) {
             do_action('jetpack_bump_stats_extras', 'api-insights-posts', $this->api->token_details['client_id']);
             update_post_meta($post_id, '_rest_api_published', 1);
             update_post_meta($post_id, '_rest_api_client_id', $this->api->token_details['client_id']);
         }
     }
     // We ask the user/dev to pass Publicize services he/she wants activated for the post, but Publicize expects us
     // to instead flag the ones we don't want to be skipped. proceed with said logic.
     // any posts coming from Path (client ID 25952) should also not publicize
     if ($publicize === false || isset($this->api->token_details['client_id']) && 25952 == $this->api->token_details['client_id']) {
         // No publicize at all, skip all by ID
         foreach ($GLOBALS['publicize_ui']->publicize->get_services('all') as $name => $service) {
             delete_post_meta($post_id, $GLOBALS['publicize_ui']->publicize->POST_SKIP . $name);
             $service_connections = $GLOBALS['publicize_ui']->publicize->get_connections($name);
             if (!$service_connections) {
                 continue;
             }
             foreach ($service_connections as $service_connection) {
                 update_post_meta($post_id, $GLOBALS['publicize_ui']->publicize->POST_SKIP . $service_connection->unique_id, 1);
             }
         }
     } else {
         if (is_array($publicize) && count($publicize) > 0) {
             foreach ($GLOBALS['publicize_ui']->publicize->get_services('all') as $name => $service) {
                 /*
                  * We support both indexed and associative arrays:
                  * * indexed are to pass entire services
                  * * associative are to pass specific connections per service
                  *
                  * We do support mixed arrays: mixed integer and string keys (see 3rd example below).
                  *
                  * EG: array( 'twitter', 'facebook') will only publicize to those, ignoring the other available services
                  * 		Form data: publicize[]=twitter&publicize[]=facebook
                  * EG: array( 'twitter' => '(int) $pub_conn_id_0, (int) $pub_conn_id_3', 'facebook' => (int) $pub_conn_id_7 ) will publicize to two Twitter accounts, and one Facebook connection, of potentially many.
                  * 		Form data: publicize[twitter]=$pub_conn_id_0,$pub_conn_id_3&publicize[facebook]=$pub_conn_id_7
                  * EG: array( 'twitter', 'facebook' => '(int) $pub_conn_id_0, (int) $pub_conn_id_3' ) will publicize to all available Twitter accounts, but only 2 of potentially many Facebook connections
                  * 		Form data: publicize[]=twitter&publicize[facebook]=$pub_conn_id_0,$pub_conn_id_3
                  */
                 // Delete any stale SKIP value for the service by name. We'll add it back by ID.
                 delete_post_meta($post_id, $GLOBALS['publicize_ui']->publicize->POST_SKIP . $name);
                 // Get the user's connections
                 $service_connections = $GLOBALS['publicize_ui']->publicize->get_connections($name);
                 // if the user doesn't have any connections for this service, move on
                 if (!$service_connections) {
                     continue;
                 }
                 if (!in_array($name, $publicize) && !array_key_exists($name, $publicize)) {
                     // Skip the whole service by adding each connection ID
                     foreach ($service_connections as $service_connection) {
                         update_post_meta($post_id, $GLOBALS['publicize_ui']->publicize->POST_SKIP . $service_connection->unique_id, 1);
                     }
                 } else {
                     if (!empty($publicize[$name])) {
                         // Seems we're being asked to only push to [a] specific connection[s].
                         // Explode the list on commas, which will also support a single passed ID
                         $requested_connections = explode(',', preg_replace('/[\\s]*/', '', $publicize[$name]));
                         // Flag the connections we can't match with the requested list to be skipped.
                         foreach ($service_connections as $service_connection) {
                             if (!in_array($service_connection->meta['connection_data']->id, $requested_connections)) {
                                 update_post_meta($post_id, $GLOBALS['publicize_ui']->publicize->POST_SKIP . $service_connection->unique_id, 1);
                             } else {
                                 delete_post_meta($post_id, $GLOBALS['publicize_ui']->publicize->POST_SKIP . $service_connection->unique_id);
                             }
                         }
                     } else {
                         // delete all SKIP values; it's okay to publish to all connected IDs for this service
                         foreach ($service_connections as $service_connection) {
                             delete_post_meta($post_id, $GLOBALS['publicize_ui']->publicize->POST_SKIP . $service_connection->unique_id);
                         }
                     }
                 }
             }
         }
     }
     if (!is_null($publicize_custom_message)) {
         if (empty($publicize_custom_message)) {
             delete_post_meta($post_id, $GLOBALS['publicize_ui']->publicize->POST_MESS);
         } else {
             update_post_meta($post_id, $GLOBALS['publicize_ui']->publicize->POST_MESS, trim($publicize_custom_message));
         }
     }
     if (!empty($insert['post_format'])) {
         if ('default' !== strtolower($insert['post_format'])) {
             set_post_format($post_id, $insert['post_format']);
         } else {
             set_post_format($post_id, get_option('default_post_format'));
         }
     }
     if (isset($featured_image)) {
         $this->parse_and_set_featured_image($post_id, $delete_featured_image, $featured_image);
     }
     if (!empty($metadata)) {
         foreach ((array) $metadata as $meta) {
             $meta = (object) $meta;
             $existing_meta_item = new stdClass();
             if (empty($meta->operation)) {
                 $meta->operation = 'update';
             }
             if (!empty($meta->value)) {
                 if ('true' == $meta->value) {
                     $meta->value = true;
                 }
                 if ('false' == $meta->value) {
                     $meta->value = false;
                 }
             }
             if (!empty($meta->id)) {
                 $meta->id = absint($meta->id);
                 $existing_meta_item = get_metadata_by_mid('post', $meta->id);
             }
             $unslashed_meta_key = wp_unslash($meta->key);
             // should match what the final key will be
             $meta->key = wp_slash($meta->key);
             $unslashed_existing_meta_key = wp_unslash($existing_meta_item->meta_key);
             $existing_meta_item->meta_key = wp_slash($existing_meta_item->meta_key);
             // make sure that the meta id passed matches the existing meta key
             if (!empty($meta->id) && !empty($meta->key)) {
                 $meta_by_id = get_metadata_by_mid('post', $meta->id);
                 if ($meta_by_id->meta_key !== $meta->key) {
                     continue;
                     // skip this meta
                 }
             }
             switch ($meta->operation) {
                 case 'delete':
                     if (!empty($meta->id) && !empty($existing_meta_item->meta_key) && current_user_can('delete_post_meta', $post_id, $unslashed_existing_meta_key)) {
                         delete_metadata_by_mid('post', $meta->id);
                     } elseif (!empty($meta->key) && !empty($meta->previous_value) && current_user_can('delete_post_meta', $post_id, $unslashed_meta_key)) {
                         delete_post_meta($post_id, $meta->key, $meta->previous_value);
                     } elseif (!empty($meta->key) && current_user_can('delete_post_meta', $post_id, $unslashed_meta_key)) {
                         delete_post_meta($post_id, $meta->key);
                     }
                     break;
                 case 'add':
                     if (!empty($meta->id) || !empty($meta->previous_value)) {
                         continue;
                     } elseif (!empty($meta->key) && !empty($meta->value) && current_user_can('add_post_meta', $post_id, $unslashed_meta_key) || $this->is_metadata_public($meta->key)) {
                         add_post_meta($post_id, $meta->key, $meta->value);
                     }
                     break;
                 case 'update':
                     if (!isset($meta->value)) {
                         continue;
                     } elseif (!empty($meta->id) && !empty($existing_meta_item->meta_key) && (current_user_can('edit_post_meta', $post_id, $unslashed_existing_meta_key) || $this->is_metadata_public($meta->key))) {
                         update_metadata_by_mid('post', $meta->id, $meta->value);
                     } elseif (!empty($meta->key) && !empty($meta->previous_value) && (current_user_can('edit_post_meta', $post_id, $unslashed_meta_key) || $this->is_metadata_public($meta->key))) {
                         update_post_meta($post_id, $meta->key, $meta->value, $meta->previous_value);
                     } elseif (!empty($meta->key) && (current_user_can('edit_post_meta', $post_id, $unslashed_meta_key) || $this->is_metadata_public($meta->key))) {
                         update_post_meta($post_id, $meta->key, $meta->value);
                     }
                     break;
             }
         }
     }
     /**
      * Fires when a post is created via the REST API.
      *
      * @since 2.3.0
      *
      * @param int $post_id Post ID.
      * @param array $insert Data used to build the post.
      * @param string $new New post URL suffix.
      */
     do_action('rest_api_inserted_post', $post_id, $insert, $new);
     $return = $this->get_post_by('ID', $post_id, $args['context']);
     if (!$return || is_wp_error($return)) {
         return $return;
     }
     if (isset($input['type']) && 'revision' === $input['type']) {
         $return['preview_nonce'] = wp_create_nonce('post_preview_' . $input['parent']);
     }
     if (isset($sticky)) {
         // workaround for sticky test occasionally failing, maybe a race condition with stick_post() above
         $return['sticky'] = true === $sticky;
     }
     /** This action is documented in json-endpoints/class.wpcom-json-api-site-settings-endpoint.php */
     do_action('wpcom_json_api_objects', 'posts');
     return $return;
 }
 /**
  * Set custom fields for post.
  *
  * @since 2.5.0
  *
  * @param int $post_id Post ID.
  * @param array $fields Custom fields.
  */
 public function set_custom_fields($post_id, $fields)
 {
     $post_id = (int) $post_id;
     foreach ((array) $fields as $meta) {
         if (isset($meta['id'])) {
             $meta['id'] = (int) $meta['id'];
             $pmeta = get_metadata_by_mid('post', $meta['id']);
             if (isset($meta['key'])) {
                 $meta['key'] = wp_unslash($meta['key']);
                 if ($meta['key'] !== $pmeta->meta_key) {
                     continue;
                 }
                 $meta['value'] = wp_unslash($meta['value']);
                 if (current_user_can('edit_post_meta', $post_id, $meta['key'])) {
                     update_metadata_by_mid('post', $meta['id'], $meta['value']);
                 }
             } elseif (current_user_can('delete_post_meta', $post_id, $pmeta->meta_key)) {
                 delete_metadata_by_mid('post', $meta['id']);
             }
         } elseif (current_user_can('add_post_meta', $post_id, wp_unslash($meta['key']))) {
             add_post_meta($post_id, $meta['key'], $meta['value']);
         }
     }
 }
Beispiel #30
0
function wpmu_delete_user($id)
{
    global $wpdb;
    $id = (int) $id;
    $user = new WP_User($id);
    do_action('wpmu_delete_user', $id);
    $blogs = get_blogs_of_user($id);
    if (!empty($blogs)) {
        foreach ($blogs as $blog) {
            switch_to_blog($blog->userblog_id);
            remove_user_from_blog($id, $blog->userblog_id);
            $post_ids = $wpdb->get_col($wpdb->prepare("SELECT ID FROM {$wpdb->posts} WHERE post_author = %d", $id));
            foreach ((array) $post_ids as $post_id) {
                wp_delete_post($post_id);
            }
            // Clean links
            $link_ids = $wpdb->get_col($wpdb->prepare("SELECT link_id FROM {$wpdb->links} WHERE link_owner = %d", $id));
            if ($link_ids) {
                foreach ($link_ids as $link_id) {
                    wp_delete_link($link_id);
                }
            }
            restore_current_blog();
        }
    }
    $meta = $wpdb->get_col($wpdb->prepare("SELECT umeta_id FROM {$wpdb->usermeta} WHERE user_id = %d", $id));
    foreach ($meta as $mid) {
        delete_metadata_by_mid('user', $mid);
    }
    $wpdb->delete($wpdb->users, array('ID' => $id));
    clean_user_cache($user);
    // allow for commit transaction
    do_action('deleted_user', $id);
    return true;
}