/** * 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); } }
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')); }
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); } }
/** * 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(); }
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); }
/** * 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); }
/** * 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')); }
/** * 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; }
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; }
/** * 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; }
/** * 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); } } } }
/** * 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; }
/** * @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))); }
/** * 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']); } } }
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; }