function test_get_previous_revision() { $instance = $this->get_instance(); //start out with a softball $fork = $this->create_fork(true); $revs = wp_get_post_revisions(get_post($fork)->post_parent); $this->assertEquals(reset($revs)->ID, $instance->revisions->get_previous_revision($fork)); }
/** * @param WP_Post $post */ public function render(WP_Post $post) { $revisions = wp_get_post_revisions($post->ID); $nonceField = wp_nonce_field($this->getKey() . '_meta_box', $this->getKey() . '_meta_box_nonce', true, false); $items = array_reduce($this->items, function ($html, MetaboxItemInterface $item) use($post, $revisions) { return $html . $item->render($post, $revisions); }, ''); echo $nonceField . $items; }
function get_post_latest_revision($post_id) { // vars $revisions = wp_get_post_revisions($post_id); // shift off and return first revision (will return null if no revisions) $revision = array_shift($revisions); // return return $revision; }
function setUp() { parent::setUp(); $this->post_id = $this->factory->post->create(array('post_content' => 'edit1')); wp_insert_post(array('ID' => $this->post_id, 'post_content' => 'edit2')); $revisions = wp_get_post_revisions($this->post_id); $revision = array_shift($revisions); $this->revision_id = $revision->ID; }
public function setUp() { parent::setUp(); $revisions = wp_get_post_revisions(self::$post_id); $this->revision_1 = array_pop($revisions); $this->revision_id1 = $this->revision_1->ID; $this->revision_2 = array_pop($revisions); $this->revision_id2 = $this->revision_2->ID; }
public function test_is_revision_dont_flush_cache() { $post = $this->factory->post->create_and_get(); wp_update_post(array('post_status' => 'draft', 'post_title' => 'some-post', 'post_type' => 'post', 'post_content' => 'some_content', 'ID' => $post->ID)); $salt = $this->obj->cache_salt; $revisions = wp_get_post_revisions($post->ID); $revision = array_shift($revisions); $this->obj->clean_post_cache($revision->ID, $revision); $this->assertsame($salt, $this->obj->cache_salt); }
function test_get_previous_revision() { $instance = $this->get_instance(); //start out with a softball $fork = $this->create_fork(true); $revs = wp_get_post_revisions(get_post($fork)->post_parent); $this->assertEquals(reset($revs)->ID, $instance->revisions->get_previous_revision($fork)); //best guess approach, should return parent post $fork = $this->create_fork(false, false); $this->assertEquals(get_post($fork)->post_parent, $instance->revisions->get_previous_revision($fork)); }
function setUp() { parent::setUp(); $this->post_id = $this->factory->post->create(array('post_content' => 'edit1')); // Not saved as a revision // First saved revision on update, see https://core.trac.wordpress.org/changeset/24650 wp_insert_post(array('ID' => $this->post_id, 'post_content' => 'edit2')); $revisions = wp_get_post_revisions($this->post_id); //$revision = array_shift( $revisions ); // First revision is empty - https://core.trac.wordpress.org/changeset/23842 // First revision is NOT empty, see https://core.trac.wordpress.org/changeset/24650 $revision = array_shift($revisions); $this->revision_id = $revision->ID; }
function get_current_revision() { if (!($js = $this->get_js_post())) { return false; } if (!empty($js['ID'])) { $revisions = wp_get_post_revisions($js['ID'], 'orderby=ID&order=DESC&limit=1'); } if (empty($revisions)) { return $js; } return get_object_vars(array_shift($revisions)); }
/** * Get a collection of revisions * * @param WP_REST_Request $request Full data about the request. * @return WP_Error|WP_REST_Response */ public function get_items($request) { $parent = get_post($request['parent_id']); if (!$request['parent_id'] || !$parent || $this->parent_post_type !== $parent->post_type) { return new WP_Error('rest_post_invalid_parent_id', __('Invalid post parent ID.'), array('status' => 404)); } $revisions = wp_get_post_revisions($request['parent_id']); $struct = array(); foreach ($revisions as $revision) { $struct[] = $this->prepare_item_for_response($revision, $request); } return $struct; }
/** * Get a collection of revisions * * @param WP_REST_Request $request Full data about the request. * @return WP_Error|WP_REST_Response */ public function get_items($request) { $parent = get_post($request['parent_id']); if (!$request['parent_id'] || !$parent || $this->parent_post_type !== $parent->post_type) { return new WP_Error('rest_post_invalid_parent_id', __('Invalid post parent id.'), array('status' => 404)); } $revisions = wp_get_post_revisions($request['parent_id']); $response = array(); foreach ($revisions as $revision) { $data = $this->prepare_item_for_response($revision, $request); $response[] = $this->prepare_response_for_collection($data); } return rest_ensure_response($response); }
public function setUp() { parent::setUp(); $this->post_id = $this->factory->post->create(); $this->page_id = $this->factory->post->create(array('post_type' => 'page')); $this->editor_id = $this->factory->user->create(array('role' => 'editor')); $this->contributor_id = $this->factory->user->create(array('role' => 'contributor')); wp_update_post(array('post_content' => 'This content is better.', 'ID' => $this->post_id)); wp_update_post(array('post_content' => 'This content is marvelous.', 'ID' => $this->post_id)); $revisions = wp_get_post_revisions($this->post_id); $this->revision_1 = array_pop($revisions); $this->revision_id1 = $this->revision_1->ID; $this->revision_2 = array_pop($revisions); $this->revision_id2 = $this->revision_2->ID; }
/** * Get revisions for a post * * @since 0.9.5 * * @param array $data * * @return array */ public static function get($data) { $args = array(); if (isset($data['limit'])) { $args['posts_per_page'] = $data['limit']; } else { $args['posts_per_page'] = 6; // we start at revision 0 } $revisions = wp_get_post_revisions($data['postid'], $args); if (is_array($revisions) && !empty($revisions)) { self::set_revisions($data['postid'], $revisions); } return self::$revisions; }
/** * Conditionally hooks the filters needed to fetch a revision meta data. */ public function hook() { $is_event_revision = $this->is_previewing() || $this->is_saving_preview(); if ($is_event_revision) { $this->event_id = $this->get_event_id(); if (empty($this->event_id)) { return; } $revisions = wp_get_post_revisions($this->event_id); if (empty($revisions)) { return; } $this->latest_revision = reset($revisions); add_filter('get_post_metadata', array($this, 'intercept_post_metadata'), 50, 4); } }
/** * Get revisions for a specific post. * * @param int $id Post ID * @uses wp_get_post_revisions * @return WP_JSON_Response */ public function get_revisions($id) { $id = (int) $id; $parent = get_post($id, ARRAY_A); if (empty($id) || empty($parent['ID'])) { return new WP_Error('json_post_invalid_id', __('Invalid post ID.'), array('status' => 404)); } if (!json_check_post_permission($parent, 'edit')) { return new WP_Error('json_cannot_view', __('Sorry, you cannot view the revisions for this post.'), array('status' => 403)); } // Todo: Query args filter for wp_get_post_revisions $revisions = wp_get_post_revisions($id); $struct = array(); foreach ($revisions as $revision) { $post = get_object_vars($revision); $struct[] = $this->prepare_post($post, 'view-revision'); } return $struct; }
/** * Get revisions for a specific post. * * @param int $id Post ID * @uses wp_get_post_revisions * @return WP_JSON_Response */ public function get_revisions($id) { $id = (int) $id; $parent = get_post($id, ARRAY_A); if (empty($id) || empty($parent['ID'])) { json_error(BigAppErr::$post['code'], "Invalid post ID."); } if (!json_check_post_permission($parent, 'edit')) { json_error(BigAppErr::$post['code'], __("Sorry, you cannot view the revisions for this post.")); } // Todo: Query args filter for wp_get_post_revisions $revisions = wp_get_post_revisions($id); $struct = array(); foreach ($revisions as $revision) { $post = get_object_vars($revision); $struct[] = $this->prepare_post($post, 'view-revision'); } return $struct; }
function list_post_revisions($post) { if ($revisions = wp_get_post_revisions($post->ID)) { $items = ''; $revision_id = valid_revision_id() ? $revision_id = $_GET['revision'] : $post->ID; foreach ($revisions as $revision) { $date = wp_post_revision_title($revision, 0); $name = get_author_name($revision->post_author); $query_string = get_query_string($revision); $items .= "<li>"; if ($revision_id == $revision->ID) { $items .= "{$date} by {$name} (<em>displayed above</em>)"; } else { $items .= "<a href=\"{$query_string}\">{$date}</a> by {$name}"; } $items .= "</li>"; } return "<ul class='revision-list'>{$items}</ul>"; } }
/** * Saves an already existing post as a post revision. * * Typically used immediately prior to post updates. * * @package WordPress * @subpackage Post_Revisions * @since 2.6.0 * * @uses _wp_put_post_revision() * * @param int $post_id The ID of the post to save as a revision. * @return mixed Null or 0 if error, new revision ID, if success. */ function wp_save_post_revision($post_id) { // We do autosaves manually with wp_create_post_autosave() if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) { return; } // WP_POST_REVISIONS = 0, false if (!WP_POST_REVISIONS) { return; } if (!($post = get_post($post_id, ARRAY_A))) { return; } if (!post_type_supports($post['post_type'], 'revisions')) { return; } $return = _wp_put_post_revision($post); // WP_POST_REVISIONS = true (default), -1 if (!is_numeric(WP_POST_REVISIONS) || WP_POST_REVISIONS < 0) { return $return; } // all revisions and (possibly) one autosave $revisions = wp_get_post_revisions($post_id, array('order' => 'ASC')); // WP_POST_REVISIONS = (int) (# of autosaves to save) $delete = count($revisions) - WP_POST_REVISIONS; if ($delete < 1) { return $return; } $revisions = array_slice($revisions, 0, $delete); for ($i = 0; isset($revisions[$i]); $i++) { if (false !== strpos($revisions[$i]->post_name, 'autosave')) { continue; } wp_delete_post_revision($revisions[$i]->ID); } return $return; }
/** * Prepare revisions for JavaScript. * * @since 3.6.0 * * @param object $post The post object. * @param int $selected_revision_id The selected revision id. * @param int $from (optional) The revision id to compare from. * * @return array An associative array of revision data and related settings. */ function wp_prepare_revisions_for_js($post, $selected_revision_id, $from = null) { $post = get_post($post); $revisions = $authors = array(); $now_gmt = time(); $revisions = wp_get_post_revisions($post->ID, array('order' => 'ASC', 'check_enabled' => false)); // If revisions are disabled, we only want autosaves and the current post. if (!wp_revisions_enabled($post)) { foreach ($revisions as $revision_id => $revision) { if (!wp_is_post_autosave($revision)) { unset($revisions[$revision_id]); } } $revisions = array($post->ID => $post) + $revisions; } $show_avatars = get_option('show_avatars'); cache_users(wp_list_pluck($revisions, 'post_author')); $can_restore = current_user_can('edit_post', $post->ID); foreach ($revisions as $revision) { $modified = strtotime($revision->post_modified); $modified_gmt = strtotime($revision->post_modified_gmt); if ($can_restore) { $restore_link = str_replace('&', '&', wp_nonce_url(add_query_arg(array('revision' => $revision->ID, 'action' => 'restore'), admin_url('revision.php')), "restore-post_{$revision->ID}")); } if (!isset($authors[$revision->post_author])) { $authors[$revision->post_author] = array('id' => (int) $revision->post_author, 'avatar' => $show_avatars ? get_avatar($revision->post_author, 32) : '', 'name' => get_the_author_meta('display_name', $revision->post_author)); } $autosave = (bool) wp_is_post_autosave($revision); $current = !$autosave && $revision->post_modified_gmt === $post->post_modified_gmt; if ($current && !empty($current_id)) { // If multiple revisions have the same post_modified_gmt, highest ID is current. if ($current_id < $revision->ID) { $revisions[$current_id]['current'] = false; $current_id = $revision->ID; } else { $current = false; } } elseif ($current) { $current_id = $revision->ID; } $revisions[$revision->ID] = array('id' => $revision->ID, 'title' => get_the_title($post->ID), 'author' => $authors[$revision->post_author], 'date' => date_i18n(__('M j, Y @ G:i'), $modified), 'dateShort' => date_i18n(_x('j M @ G:i', 'revision date short format'), $modified), 'timeAgo' => sprintf(__('%s ago'), human_time_diff($modified_gmt, $now_gmt)), 'autosave' => $autosave, 'current' => $current, 'restoreUrl' => $can_restore ? $restore_link : false); } // If a post has been saved since the last revision (no revisioned fields were changed) // we may not have a "current" revision. Mark the latest revision as "current". if (empty($current_id)) { if ($revisions[$revision->ID]['autosave']) { $revision = end($revisions); while ($revision['autosave']) { $revision = prev($revisions); } $current_id = $revision['id']; } else { $current_id = $revision->ID; } $revisions[$current_id]['current'] = true; } // Now, grab the initial diff $compare_two_mode = is_numeric($from); if (!$compare_two_mode) { $found = array_search($selected_revision_id, array_keys($revisions)); if ($found) { $from = array_keys(array_slice($revisions, $found - 1, 1, true)); $from = reset($from); } else { $from = 0; } } $from = absint($from); $diffs = array(array('id' => $from . ':' . $selected_revision_id, 'fields' => wp_get_revision_ui_diff($post->ID, $from, $selected_revision_id))); return array('postId' => $post->ID, 'nonce' => wp_create_nonce('revisions-ajax-nonce'), 'revisionData' => array_values($revisions), 'to' => $selected_revision_id, 'from' => $from, 'diffData' => $diffs, 'baseUrl' => parse_url(admin_url('revision.php'), PHP_URL_PATH), 'compareTwoMode' => absint($compare_two_mode), 'revisionIds' => array_keys($revisions)); }
/** * Retrieve revisions for a specific post. * * @since 3.5.0 * * The optional $fields parameter specifies what fields will be included * in the response array. * * @uses wp_get_post_revisions() * @see wp_getPost() for more on $fields * * @param array $args Method parameters. Contains: * - int $blog_id (unused) * - string $username * - string $password * - int $post_id * - array $fields * @return array|IXR_Error contains a collection of posts. */ public function wp_getRevisions($args) { if (!$this->minimum_args($args, 4)) { return $this->error; } $this->escape($args); $username = $args[1]; $password = $args[2]; $post_id = (int) $args[3]; if (isset($args[4])) { $fields = $args[4]; } else { /** * Filter the default revision query fields used by the given XML-RPC method. * * @since 3.5.0 * * @param array $field An array of revision query fields. * @param string $method The method name. */ $fields = apply_filters('xmlrpc_default_revision_fields', array('post_date', 'post_date_gmt'), 'wp.getRevisions'); } if (!($user = $this->login($username, $password))) { return $this->error; } /** This action is documented in wp-includes/class-wp-xmlrpc-server.php */ do_action('xmlrpc_call', 'wp.getRevisions'); if (!($post = get_post($post_id))) { return new IXR_Error(404, __('Invalid post ID')); } if (!current_user_can('edit_post', $post_id)) { return new IXR_Error(401, __('Sorry, you are not allowed to edit posts.')); } // Check if revisions are enabled. if (!wp_revisions_enabled($post)) { return new IXR_Error(401, __('Sorry, revisions are disabled.')); } $revisions = wp_get_post_revisions($post_id); if (!$revisions) { return array(); } $struct = array(); foreach ($revisions as $revision) { if (!current_user_can('read_post', $revision->ID)) { continue; } // Skip autosaves if (wp_is_post_autosave($revision)) { continue; } $struct[] = $this->_prepare_post(get_object_vars($revision), $fields); } return $struct; }
/** * Ajax handler for getting revision diffs. * * @since 3.6.0 */ function wp_ajax_get_revision_diffs() { require ABSPATH . 'wp-admin/includes/revision.php'; if (!($post = get_post((int) $_REQUEST['post_id']))) { wp_send_json_error(); } if (!current_user_can('read_post', $post->ID)) { wp_send_json_error(); } // Really just pre-loading the cache here. if (!($revisions = wp_get_post_revisions($post->ID, array('check_enabled' => false)))) { wp_send_json_error(); } $return = array(); @set_time_limit(0); foreach ($_REQUEST['compare'] as $compare_key) { list($compare_from, $compare_to) = explode(':', $compare_key); // from:to $return[] = array('id' => $compare_key, 'fields' => wp_get_revision_ui_diff($post, $compare_from, $compare_to)); } wp_send_json_success($return); }
/** * Display list of a post's revisions. * * Can output either a UL with edit links or a TABLE with diff interface, and * restore action links. * * @since 2.6.0 * * @param int|WP_Post $post_id Optional. Post ID or WP_Post object. Default is global $post. * @param string $type 'all' (default), 'revision' or 'autosave' */ function wp_list_post_revisions($post_id = 0, $type = 'all') { if (!($post = get_post($post_id))) { return; } // $args array with (parent, format, right, left, type) deprecated since 3.6 if (is_array($type)) { $type = !empty($type['type']) ? $type['type'] : $type; _deprecated_argument(__FUNCTION__, '3.6.0'); } if (!($revisions = wp_get_post_revisions($post->ID))) { return; } $rows = ''; foreach ($revisions as $revision) { if (!current_user_can('read_post', $revision->ID)) { continue; } $is_autosave = wp_is_post_autosave($revision); if ('revision' === $type && $is_autosave || 'autosave' === $type && !$is_autosave) { continue; } $rows .= "\t<li>" . wp_post_revision_title_expanded($revision) . "</li>\n"; } echo "<div class='hide-if-js'><p>" . __('JavaScript must be enabled to use this feature.') . "</p></div>\n"; echo "<ul class='post-revisions hide-if-no-js'>\n"; echo $rows; echo "</ul>"; }
/** * Display list of a post's revisions. * * Can output either a UL with edit links or a TABLE with diff interface, and * restore action links. * * Second argument controls parameters: * (bool) parent : include the parent (the "Current Revision") in the list. * (string) format : 'list' or 'form-table'. 'list' outputs UL, 'form-table' * outputs TABLE with UI. * (int) right : what revision is currently being viewed - used in * form-table format. * (int) left : what revision is currently being diffed against right - * used in form-table format. * * @package WordPress * @subpackage Post_Revisions * @since 2.6.0 * * @uses wp_get_post_revisions() * @uses wp_post_revision_title() * @uses get_edit_post_link() * @uses get_the_author_meta() * * @todo split into two functions (list, form-table) ? * * @param int|object $post_id Post ID or post object. * @param string|array $args See description {@link wp_parse_args()}. * @return null */ function wp_list_post_revisions($post_id = 0, $args = null) { if (!($post = get_post($post_id))) { return; } $defaults = array('parent' => false, 'right' => false, 'left' => false, 'format' => 'list', 'type' => 'all'); extract(wp_parse_args($args, $defaults), EXTR_SKIP); switch ($type) { case 'autosave': if (!($autosave = wp_get_post_autosave($post->ID))) { return; } $revisions = array($autosave); break; case 'revision': // just revisions - remove autosave later // just revisions - remove autosave later case 'all': default: if (!($revisions = wp_get_post_revisions($post->ID))) { return; } break; } /* translators: post revision: 1: when, 2: author name */ $titlef = _x('%1$s by %2$s', 'post revision'); if ($parent) { array_unshift($revisions, $post); } $rows = $right_checked = ''; $class = false; $can_edit_post = current_user_can('edit_post', $post->ID); foreach ($revisions as $revision) { if (!current_user_can('read_post', $revision->ID)) { continue; } if ('revision' === $type && wp_is_post_autosave($revision)) { continue; } $date = wp_post_revision_title($revision); $name = get_the_author_meta('display_name', $revision->post_author); if ('form-table' == $format) { if ($left) { $left_checked = $left == $revision->ID ? ' checked="checked"' : ''; } else { $left_checked = $right_checked ? ' checked="checked"' : ''; } // [sic] (the next one) $right_checked = $right == $revision->ID ? ' checked="checked"' : ''; $class = $class ? '' : " class='alternate'"; if ($post->ID != $revision->ID && $can_edit_post) { $actions = '<a href="' . wp_nonce_url(add_query_arg(array('revision' => $revision->ID, 'action' => 'restore')), "restore-post_{$post->ID}|{$revision->ID}") . '">' . __('Restore') . '</a>'; } else { $actions = ''; } $rows .= "<tr{$class}>\n"; $rows .= "\t<th style='white-space: nowrap' scope='row'><input type='radio' name='left' value='{$revision->ID}'{$left_checked} /></th>\n"; $rows .= "\t<th style='white-space: nowrap' scope='row'><input type='radio' name='right' value='{$revision->ID}'{$right_checked} /></th>\n"; $rows .= "\t<td>{$date}</td>\n"; $rows .= "\t<td>{$name}</td>\n"; $rows .= "\t<td class='action-links'>{$actions}</td>\n"; $rows .= "</tr>\n"; } else { $title = sprintf($titlef, $date, $name); $rows .= "\t<li>{$title}</li>\n"; } } if ('form-table' == $format) { ?> <form action="revision.php" method="get"> <div class="tablenav"> <div class="alignleft"> <input type="submit" class="button-secondary" value="<?php esc_attr_e('Compare Revisions'); ?> " /> <input type="hidden" name="action" value="diff" /> <input type="hidden" name="post_type" value="<?php echo esc_attr($post->post_type); ?> " /> </div> </div> <br class="clear" /> <table class="widefat post-revisions" cellspacing="0" id="post-revisions"> <col /> <col /> <col style="width: 33%" /> <col style="width: 33%" /> <col style="width: 33%" /> <thead> <tr> <th scope="col"><?php /* translators: column name in revisons */ _ex('Old', 'revisions column name'); ?> </th> <th scope="col"><?php /* translators: column name in revisons */ _ex('New', 'revisions column name'); ?> </th> <th scope="col"><?php /* translators: column name in revisons */ _ex('Date Created', 'revisions column name'); ?> </th> <th scope="col"><?php _e('Author'); ?> </th> <th scope="col" class="action-links"><?php _e('Actions'); ?> </th> </tr> </thead> <tbody> <?php echo $rows; ?> </tbody> </table> </form> <?php } else { echo "<ul class='post-revisions'>\n"; echo $rows; echo "</ul>"; } }
/** * Retrieve the autosaved data of the specified post. * * Returns a post object containing the information that was autosaved for the * specified post. If the optional $user_id is passed, returns the autosave for that user * otherwise returns the latest autosave. * * @since 2.6.0 * * @param int $post_id The post ID. * @param int $user_id Optional The post author ID. * @return WP_Post|false The autosaved data or false on failure or when no autosave exists. */ function wp_get_post_autosave($post_id, $user_id = 0) { $revisions = wp_get_post_revisions($post_id, array('check_enabled' => false)); foreach ($revisions as $revision) { if (false !== strpos($revision->post_name, "{$post_id}-autosave")) { if ($user_id && $user_id != $revision->post_author) { continue; } return $revision; } } return false; }
/** * Retrieve revisions for a specific post. * * @since 3.5.0 * * The optional $fields parameter specifies what fields will be included * in the response array. * * @uses wp_get_post_revisions() * @see wp_getPost() for more on $fields * * @param array $args Method parameters. Contains: * - int $blog_id * - string $username * - string $password * - int $post_id * - array $fields * @return array contains a collection of posts. */ function wp_getRevisions($args) { if (!$this->minimum_args($args, 4)) { return $this->error; } $this->escape($args); $blog_id = (int) $args[0]; $username = $args[1]; $password = $args[2]; $post_id = (int) $args[3]; if (isset($args[4])) { $fields = $args[4]; } else { $fields = apply_filters('xmlrpc_default_revision_fields', array('post_date', 'post_date_gmt'), 'wp.getRevisions'); } if (!($user = $this->login($username, $password))) { return $this->error; } do_action('xmlrpc_call', 'wp.getRevisions'); if (!($post = get_post($post_id))) { return new IXR_Error(404, __('Invalid post ID')); } if (!current_user_can('edit_post', $post_id)) { return new IXR_Error(401, __('Sorry, you are not allowed to edit posts.')); } // Check if revisions are enabled. if (!wp_revisions_enabled($post)) { return new IXR_Error(401, __('Sorry, revisions are disabled.')); } $revisions = wp_get_post_revisions($post_id); if (!$revisions) { return array(); } $struct = array(); foreach ($revisions as $revision) { if (!current_user_can('read_post', $revision->ID)) { continue; } // Skip autosaves if (wp_is_post_autosave($revision)) { continue; } $struct[] = $this->_prepare_post(get_object_vars($revision), $fields); } return $struct; }
static function admin() { add_meta_box('submitdiv', __('Publish', 'jetpack'), array(__CLASS__, 'publish_box'), 'editcss', 'side'); add_action('custom_css_submitbox_misc_actions', array(__CLASS__, 'content_width_settings')); $safecss_post = Jetpack_Custom_CSS::get_post(); if (!empty($safecss_post) && 0 < $safecss_post['ID'] && wp_get_post_revisions($safecss_post['ID'])) { add_meta_box('revisionsdiv', __('CSS Revisions', 'jetpack'), array(__CLASS__, 'revisions_meta_box'), 'editcss', 'side'); } ?> <div class="wrap"> <?php /** * Fires right before the custom css page begins. * * @module custom-css * * @since 1.7.0 */ do_action('custom_design_header'); ?> <h1><?php _e('CSS Stylesheet Editor', 'jetpack'); ?> </h1> <form id="safecssform" action="" method="post"> <?php wp_nonce_field('safecss'); ?> <?php wp_nonce_field('meta-box-order', 'meta-box-order-nonce', false); ?> <?php wp_nonce_field('closedpostboxes', 'closedpostboxesnonce', false); ?> <input type="hidden" name="action" value="save" /> <div id="poststuff"> <p class="css-support"> <?php /** * Filter the intro text appearing above the Custom CSS Editor. * * @module custom-css * * @since 1.7.0 * * @param string $str Intro text appearing above the Custom CSS editor. */ echo apply_filters('safecss_intro_text', __('New to CSS? Start with a <a href="http://www.htmldog.com/guides/cssbeginner/">beginner tutorial</a>. Questions? Ask in the <a href="http://wordpress.org/support/forum/themes-and-templates">Themes and Templates forum</a>.', 'jetpack')); ?> </p> <p class="css-support"><?php echo __('Note: Custom CSS will be reset when changing themes.', 'jetpack'); ?> </p> <div id="post-body" class="metabox-holder columns-2"> <div id="post-body-content"> <div class="postarea"> <textarea id="safecss" name="safecss"<?php if (SAFECSS_USE_ACE) { echo ' class="hide-if-js"'; } ?> ><?php echo esc_textarea(Jetpack_Custom_CSS::get_css()); ?> </textarea> <div class="clear"></div> </div> </div> <div id="postbox-container-1" class="postbox-container"> <?php do_meta_boxes('editcss', 'side', $safecss_post); ?> </div> </div> <br class="clear" /> </div> </form> </div> <?php }
/** * Update an existing post with values provided in $_POST. * * @since 1.5.0 * * @global wpdb $wpdb WordPress database abstraction object. * * @param array $post_data Optional. * @return int Post ID. */ function edit_post($post_data = null) { global $wpdb; if (empty($post_data)) { $post_data =& $_POST; } // Clear out any data in internal vars. unset($post_data['filter']); $post_ID = (int) $post_data['post_ID']; $post = get_post($post_ID); $post_data['post_type'] = $post->post_type; $post_data['post_mime_type'] = $post->post_mime_type; if (!empty($post_data['post_status'])) { $post_data['post_status'] = sanitize_key($post_data['post_status']); if ('inherit' == $post_data['post_status']) { unset($post_data['post_status']); } } $ptype = get_post_type_object($post_data['post_type']); if (!current_user_can('edit_post', $post_ID)) { if ('page' == $post_data['post_type']) { wp_die(__('Sorry, you are not allowed to edit this page.')); } else { wp_die(__('Sorry, you are not allowed to edit this post.')); } } if (post_type_supports($ptype->name, 'revisions')) { $revisions = wp_get_post_revisions($post_ID, array('order' => 'ASC', 'posts_per_page' => 1)); $revision = current($revisions); // Check if the revisions have been upgraded if ($revisions && _wp_get_post_revision_version($revision) < 1) { _wp_upgrade_revisions_of_post($post, wp_get_post_revisions($post_ID)); } } if (isset($post_data['visibility'])) { switch ($post_data['visibility']) { case 'public': $post_data['post_password'] = ''; break; case 'password': unset($post_data['sticky']); break; case 'private': $post_data['post_status'] = 'private'; $post_data['post_password'] = ''; unset($post_data['sticky']); break; } } $post_data = _wp_translate_postdata(true, $post_data); if (is_wp_error($post_data)) { wp_die($post_data->get_error_message()); } // Post Formats if (isset($post_data['post_format'])) { set_post_format($post_ID, $post_data['post_format']); } $format_meta_urls = array('url', 'link_url', 'quote_source_url'); foreach ($format_meta_urls as $format_meta_url) { $keyed = '_format_' . $format_meta_url; if (isset($post_data[$keyed])) { update_post_meta($post_ID, $keyed, wp_slash(esc_url_raw(wp_unslash($post_data[$keyed])))); } } $format_keys = array('quote', 'quote_source_name', 'image', 'gallery', 'audio_embed', 'video_embed'); foreach ($format_keys as $key) { $keyed = '_format_' . $key; if (isset($post_data[$keyed])) { if (current_user_can('unfiltered_html')) { update_post_meta($post_ID, $keyed, $post_data[$keyed]); } else { update_post_meta($post_ID, $keyed, wp_filter_post_kses($post_data[$keyed])); } } } if ('attachment' === $post_data['post_type'] && preg_match('#^(audio|video)/#', $post_data['post_mime_type'])) { $id3data = wp_get_attachment_metadata($post_ID); if (!is_array($id3data)) { $id3data = array(); } foreach (wp_get_attachment_id3_keys($post, 'edit') as $key => $label) { if (isset($post_data['id3_' . $key])) { $id3data[$key] = sanitize_text_field(wp_unslash($post_data['id3_' . $key])); } } wp_update_attachment_metadata($post_ID, $id3data); } // Meta Stuff if (isset($post_data['meta']) && $post_data['meta']) { foreach ($post_data['meta'] as $key => $value) { if (!($meta = get_post_meta_by_id($key))) { continue; } if ($meta->post_id != $post_ID) { continue; } if (is_protected_meta($value['key'], 'post') || !current_user_can('edit_post_meta', $post_ID, $value['key'])) { continue; } update_meta($key, $value['key'], $value['value']); } } if (isset($post_data['deletemeta']) && $post_data['deletemeta']) { foreach ($post_data['deletemeta'] as $key => $value) { if (!($meta = get_post_meta_by_id($key))) { continue; } if ($meta->post_id != $post_ID) { continue; } if (is_protected_meta($meta->meta_key, 'post') || !current_user_can('delete_post_meta', $post_ID, $meta->meta_key)) { continue; } delete_meta($key); } } // Attachment stuff if ('attachment' == $post_data['post_type']) { if (isset($post_data['_wp_attachment_image_alt'])) { $image_alt = wp_unslash($post_data['_wp_attachment_image_alt']); if ($image_alt != get_post_meta($post_ID, '_wp_attachment_image_alt', true)) { $image_alt = wp_strip_all_tags($image_alt, true); // update_meta expects slashed. update_post_meta($post_ID, '_wp_attachment_image_alt', wp_slash($image_alt)); } } $attachment_data = isset($post_data['attachments'][$post_ID]) ? $post_data['attachments'][$post_ID] : array(); /** This filter is documented in wp-admin/includes/media.php */ $post_data = apply_filters('attachment_fields_to_save', $post_data, $attachment_data); } // Convert taxonomy input to term IDs, to avoid ambiguity. if (isset($post_data['tax_input'])) { foreach ((array) $post_data['tax_input'] as $taxonomy => $terms) { // Hierarchical taxonomy data is already sent as term IDs, so no conversion is necessary. if (is_taxonomy_hierarchical($taxonomy)) { continue; } /* * Assume that a 'tax_input' string is a comma-separated list of term names. * Some languages may use a character other than a comma as a delimiter, so we standardize on * commas before parsing the list. */ if (!is_array($terms)) { $comma = _x(',', 'tag delimiter'); if (',' !== $comma) { $terms = str_replace($comma, ',', $terms); } $terms = explode(',', trim($terms, " \n\t\r\v,")); } $clean_terms = array(); foreach ($terms as $term) { // Empty terms are invalid input. if (empty($term)) { continue; } $_term = get_terms($taxonomy, array('name' => $term, 'fields' => 'ids', 'hide_empty' => false)); if (!empty($_term)) { $clean_terms[] = intval($_term[0]); } else { // No existing term was found, so pass the string. A new term will be created. $clean_terms[] = $term; } } $post_data['tax_input'][$taxonomy] = $clean_terms; } } add_meta($post_ID); update_post_meta($post_ID, '_edit_last', get_current_user_id()); $success = wp_update_post($post_data); // If the save failed, see if we can sanity check the main fields and try again if (!$success && is_callable(array($wpdb, 'strip_invalid_text_for_column'))) { $fields = array('post_title', 'post_content', 'post_excerpt'); foreach ($fields as $field) { if (isset($post_data[$field])) { $post_data[$field] = $wpdb->strip_invalid_text_for_column($wpdb->posts, $field, $post_data[$field]); } } wp_update_post($post_data); } // Now that we have an ID we can fix any attachment anchor hrefs _fix_attachment_links($post_ID); wp_set_post_lock($post_ID); if (current_user_can($ptype->cap->edit_others_posts) && current_user_can($ptype->cap->publish_posts)) { if (!empty($post_data['sticky'])) { stick_post($post_ID); } else { unstick_post($post_ID); } } return $post_ID; }
static function admin() { add_meta_box('submitdiv', __('Publish', 'jetpack'), array(__CLASS__, 'publish_box'), 'editcss', 'side'); add_action('custom_css_submitbox_misc_actions', array(__CLASS__, 'content_width_settings')); $safecss_post = Jetpack_Custom_CSS::get_post(); if (!empty($safecss_post) && 0 < $safecss_post['ID'] && wp_get_post_revisions($safecss_post['ID'])) { add_meta_box('revisionsdiv', __('CSS Revisions', 'jetpack'), array(__CLASS__, 'revisions_meta_box'), 'editcss', 'side'); } ?> <div class="wrap columns-2"> <?php do_action('custom_design_header'); ?> <h2><?php _e('CSS Stylesheet Editor', 'jetpack'); ?> </h2> <form id="safecssform" action="" method="post"> <?php wp_nonce_field('safecss'); ?> <?php wp_nonce_field('meta-box-order', 'meta-box-order-nonce', false); ?> <?php wp_nonce_field('closedpostboxes', 'closedpostboxesnonce', false); ?> <input type="hidden" name="action" value="save" /> <div id="poststuff" class="metabox-holder has-right-sidebar"> <p class="css-support"><?php echo apply_filters('safecss_intro_text', __('New to CSS? Start with a <a href="http://www.htmldog.com/guides/cssbeginner/">beginner tutorial</a>. Questions? Ask in the <a href="http://wordpress.org/support/forum/themes-and-templates">Themes and Templates forum</a>.', 'jetpack')); ?> </p> <div id="postbox-container-1" class="inner-sidebar"> <?php do_meta_boxes('editcss', 'side', $safecss_post); ?> </div> <div id="post-body"> <div id="post-body-content"> <div class="postarea"> <?php if (defined('SAFECSS_USE_ACE') && SAFECSS_USE_ACE) { ?> <div id="safecss-container"> <div id="safecss-ace"></div> </div> <script type="text/javascript"> jQuery.fn.spin && jQuery("#safecss-container").spin( 'large' ); </script> <textarea id="safecss" name="safecss" class="hide-if-js"><?php echo esc_textarea(Jetpack_Custom_CSS::get_css()); ?> </textarea> <div class="clear"></div> <?php } else { ?> <p><textarea id="safecss" name="safecss"><?php echo str_replace('</textarea>', '</textarea>', Jetpack_Custom_CSS::get_css()); ?> </textarea></p> <?php } ?> </div> </div> </div> <br class="clear" /> </div> </form> </div> <?php }
/** * Return the revisions of the topic * * @since 2.0.0 bbPress (r2782) * * @param int $topic_id Optional. Topic id * @uses bbp_get_topic_id() To get the topic id * @uses wp_get_post_revisions() To get the topic revisions * @uses apply_filters() Calls 'bbp_get_topic_revisions' * with the revisions and topic id * @return string Topic revisions */ function bbp_get_topic_revisions($topic_id = 0) { $topic_id = bbp_get_topic_id($topic_id); $revisions = wp_get_post_revisions($topic_id, array('order' => 'ASC')); return apply_filters('bbp_get_topic_revisions', $revisions, $topic_id); }
/** * SyndicatedPost::freshness: check whether post is a new post to be * inserted, a previously syndicated post that needs to be updated to * match the latest revision, or a previously syndicated post that is * still up-to-date. * * @return int A status code representing the freshness of the post * -1 = post already syndicated; has a revision that needs to be stored, but not updated to * 0 = post already syndicated; no update needed * 1 = post already syndicated, but needs to be updated to latest * 2 = post has not yet been syndicated; needs to be created */ function freshness($format = 'number') { global $wpdb; if ($this->filtered()) { // This should never happen. FeedWordPress::critical_bug('SyndicatedPost', $this, __LINE__, __FILE__); } if (is_null($this->_freshness)) { // Not yet checked and cached. $guid = $this->post['guid']; $eguid = esc_sql($this->post['guid']); $q = new WP_Query(array('fields' => '_synfresh', 'ignore_sticky_posts' => true, 'guid' => $guid)); $old_post = NULL; if ($q->have_posts()) { while ($q->have_posts()) { $q->the_post(); $old_post = $q->post; } } if (is_null($old_post)) { // No post with this guid FeedWordPress::diagnostic('feed_items:freshness', 'Item [' . $guid . '] "' . $this->entry->get_title() . '" is a NEW POST.'); $this->_wp_id = NULL; $this->_freshness = 2; // New content } else { // Presume there is nothing new until we find // something new. $updated = false; $live = false; // Pull the list of existing revisions to get // timestamps. $revisions = wp_get_post_revisions($old_post->ID); foreach ($revisions as $rev) { $revisions_ts[] = mysql2date('G', $rev->post_modified_gmt); } $revisions_ts[] = mysql2date('G', $old_post->post_modified_gmt); $last_rev_ts = end($revisions_ts); $updated_ts = $this->updated(true, NULL); // If we have an explicit updated timestamp, // check that against existing stamps. if (!is_null($updated_ts)) { $updated = !in_array($updated_ts, $revisions_ts); // If this a newer revision, make it go // live. If an older one, just record // the contents. $live = ($updated and $updated_ts > $last_rev_ts); } // This is a revision we haven't seen before, judging by the date. $updatedReason = NULL; if ($updated) { $updatedReason = preg_replace("/\\s+/", " ", 'has been marked with a new timestamp (' . date('Y-m-d H:i:s', $updated_ts) . " > " . date('Y-m-d H:i:s', $last_rev_ts) . ')'); // The date does not indicate a new revision, so // let's check the hash. } else { // Or the hash... $hash = $this->update_hash(); $seen = $this->stored_hashes($old_post->ID); if (count($seen) > 0) { $updated = !in_array($hash, $seen); // Not seen yet? } else { $updated = true; // Can't find syndication meta-data } if ($updated and FeedWordPress::diagnostic_on('feed_items:freshness:reasons')) { // In the absence of definitive // timestamp information, we // just have to assume that a // hash we haven't seen before // is a newer version. $live = true; $updatedReason = ' has a not-yet-seen update hash: ' . MyPHP::val($hash) . ' not in {' . implode(", ", array_map(array('FeedWordPress', 'val'), $seen)) . '}. Basis: ' . MyPHP::val(array_keys($this->update_hash(false))); } } $frozen = false; if ($updated) { // Ignore if the post is frozen $frozen = 'yes' == $this->link->setting('freeze updates', 'freeze_updates', NULL); if (!$frozen) { $frozen_values = get_post_custom_values('_syndication_freeze_updates', $old_post->ID); $frozen = (count($frozen_values) > 0 and 'yes' == $frozen_values[0]); if ($frozen) { $updatedReason = ' IS BLOCKED FROM BEING UPDATED BY A UPDATE LOCK ON THIS POST, EVEN THOUGH IT ' . $updatedReason; } } else { $updatedReason = ' IS BLOCKED FROM BEING UPDATED BY A FEEDWORDPRESS UPDATE LOCK, EVEN THOUGH IT ' . $updatedReason; } } $live = ($live and !$frozen); if ($updated) { FeedWordPress::diagnostic('feed_items:freshness', 'Item [' . $guid . '] "' . $this->entry->get_title() . '" is an update of an existing post.'); if (!is_null($updatedReason)) { $updatedReason = preg_replace('/\\s+/', ' ', $updatedReason); FeedWordPress::diagnostic('feed_items:freshness:reasons', 'Item [' . $guid . '] "' . $this->entry->get_title() . '" ' . $updatedReason); } $this->_freshness = apply_filters('syndicated_item_freshness', $live ? 1 : -1, $updated, $frozen, $updated_ts, $last_rev_ts, $this); $this->_wp_id = $old_post->ID; $this->_wp_post = $old_post; // We want this to keep a running list of all the // processed update hashes. $this->post['meta']['syndication_item_hash'] = array_merge($this->stored_hashes(), array($this->update_hash())); } else { FeedWordPress::diagnostic('feed_items:freshness', 'Item [' . $guid . '] "' . $this->entry->get_title() . '" is a duplicate of an existing post.'); $this->_freshness = 0; // Same old, same old $this->_wp_id = $old_post->ID; } } } switch ($format) { case 'status': switch ($this->_freshness) { case -1: $ret = 'stored'; break; case 0: $ret = NULL; break; case 1: $ret = 'updated'; break; case 2: default: $ret = 'new'; break; } break; case 'number': default: $ret = $this->_freshness; } return $ret; }