ch[1]) >= 534 ) )
$wp_rich_edit = true;
} elseif ( $is_gecko || $is_opera || $is_chrome || $is_IE ) {
$wp_rich_edit = true;
}
}
}
return apply_filters('user_can_richedit', $wp_rich_edit);
}
/**
* Find out which editor should be displayed by default.
*
* Works out which of the two editors to display as the current editor for a
* user.
*
* @since 2.5.0
*
* @return string Either 'tinymce', or 'html', or 'test'
*/
function wp_default_editor() {
$r = user_can_richedit() ? 'tinymce' : 'html'; // defaults
if ( $user = wp_get_current_user() ) { // look for cookie
$ed = get_user_setting('editor', 'tinymce');
$r = ( in_array($ed, array('tinymce', 'html', 'test') ) ) ? $ed : $r;
}
return apply_filters( 'wp_default_editor', $r ); // filter
}
/**
* Renders an editor.
*
* Using this function is the proper way to output all needed components for both TinyMCE and Quicktags.
* _WP_Editors should not be used directly. See http://core.trac.wordpress.org/ticket/17144.
*
* NOTE: Once initialized the TinyMCE editor cannot be safely moved in the DOM. For that reason
* running wp_editor() inside of a metabox is not a good idea unless only Quicktags is used.
* On the post edit screen several actions can be used to include additional editors
* containing TinyMCE: 'edit_page_form', 'edit_form_advanced' and 'dbx_post_sidebar'.
* See http://core.trac.wordpress.org/ticket/19173 for more information.
*
* @see wp-includes/class-wp-editor.php
* @since 3.3
*
* @param string $content Initial content for the editor.
* @param string $editor_id HTML ID attribute value for the textarea and TinyMCE. Can only be /[a-z]+/.
* @param array $settings See _WP_Editors::editor().
*/
function wp_editor( $content, $editor_id, $settings = array() ) {
if ( ! class_exists( '_WP_Editors' ) )
require( ABSPATH . WPINC . '/class-wp-editor.php' );
_WP_Editors::editor($content, $editor_id, $settings);
}
/**
* Retrieve the contents of the search WordPress query variable.
*
* The search query string is passed through {@link esc_attr()}
* to ensure that it is safe for placing in an html attribute.
*
* @since 2.3.0
* @uses esc_attr()
*
* @param bool $escaped Whether the result is escaped. Default true.
* Only use when you are later escaping it. Do not use unescaped.
* @return string
*/
function get_search_query( $escaped = true ) {
$query = apply_filters( 'get_search_query', get_query_var( 's' ) );
if ( $escaped )
$query = esc_attr( $query );
return $query;
}
/**
* Display the contents of the search query variable.
*
* The search query string is passed through {@link esc_attr()}
* to ensure that it is safe for placing in an html attribute.
*
* @uses esc_attr()
* @since 2.1.0
*/
function the_search_query() {
echo esc_attr( apply_filters( 'the_search_query', get_search_query( false ) ) );
}
/**
* Display the language attributes for the html tag.
*
* Builds up a set of html attributes containing the text direction and language
* information for the page.
*
* @since 2.1.0
*
* @param string $doctype The type of html document (xhtml|html).
*/
function language_attributes($doctype = 'html') {
$attributes = array();
$output = '';
if ( function_exists( 'is_rtl' ) )
$attributes[] = 'dir="' . ( is_rtl() ? 'rtl' : 'ltr' ) . '"';
if ( $lang = get_bloginfo('language') ) {
if ( get_option('html_type') == 'text/html' || $doctype == 'html' )
$attributes[] = "lang=\"$lang\"";
if ( get_option('html_type') != 'text/html' || $doctype == 'xhtml' )
$attributes[] = "xml:lang=\"$lang\"";
}
$output = implode(' ', $attributes);
$output = apply_filters('language_attributes', $output);
echo $output;
}
/**
* Retrieve paginated link for archive post pages.
*
* Technically, the function can be used to create paginated link list for any
* area. The 'base' argument is used to reference the url, which will be used to
* create the paginated links. The 'format' argument is then used for replacing
* the page number. It is however, most likely and by default, to be used on the
* archive post pages.
*
* The 'type' argument controls format of the returned value. The default is
* 'plain', which is just a string with the links separated by a newline
* character. The other possible values are either 'array' or 'list'. The
* 'array' value will return an array of the paginated link list to offer full
* control of display. The 'list' value will place all of the paginated links in
* an unordered HTML list.
*
* The 'total' argument is the total amount of pages and is an integer. The
* 'current' argument is the current page number and is also an integer.
*
* An example of the 'base' argument is "http://example.com/all_posts.php%_%"
* and the '%_%' is required. The '%_%' will be replaced by the contents of in
* the 'format' argument. An example for the 'format' argument is "?page=%#%"
* and the '%#%' is also required. The '%#%' will be replaced with the page
* number.
*
* You can include the previous and next links in the list by setting the
* 'prev_next' argument to true, which it is by default. You can set the
* previous text, by using the 'prev_text' argument. You can set the next text
* by setting the 'next_text' argument.
*
* If the 'show_all' argument is set to true, then it will show all of the pages
* instead of a short list of the pages near the current page. By default, the
* 'show_all' is set to false and controlled by the 'end_size' and 'mid_size'
* arguments. The 'end_size' argument is how many numbers on either the start
* and the end list edges, by default is 1. The 'mid_size' argument is how many
* numbers to either side of current page, but not including current page.
*
* It is possible to add query vars to the link by using the 'add_args' argument
* and see {@link add_query_arg()} for more information.
*
* @since 2.1.0
*
* @param string|array $args Optional. Override defaults.
* @return array|string String of page links or array of page links.
*/
function paginate_links( $args = '' ) {
$defaults = array(
'base' => '%_%', // http://example.com/all_posts.php%_% : %_% is replaced by format (below)
'format' => '?page=%#%', // ?page=%#% : %#% is replaced by the page number
'total' => 1,
'current' => 0,
'show_all' => false,
'prev_next' => true,
'prev_text' => __('« Previous'),
'next_text' => __('Next »'),
'end_size' => 1,
'mid_size' => 2,
'type' => 'plain',
'add_args' => false, // array of query args to add
'add_fragment' => ''
);
$args = wp_parse_args( $args, $defaults );
extract($args, EXTR_SKIP);
// Who knows what else people pass in $args
$total = (int) $total;
if ( $total < 2 )
return;
$current = (int) $current;
$end_size = 0 < (int) $end_size ? (int) $end_size : 1; // Out of bounds? Make it the default.
$mid_size = 0 <= (int) $mid_size ? (int) $mid_size : 2;
$add_args = is_array($add_args) ? $add_args : false;
$r = '';
$page_links = array();
$n = 0;
$dots = false;
if ( $prev_next && $current && 1 < $current ) :
$link = str_replace('%_%', 2 == $current ? '' : $format, $base);
$link = str_replace('%#%', $current - 1, $link);
if ( $add_args )
$link = add_query_arg( $add_args, $link );
$link .= $add_fragment;
$page_links[] = '' . $prev_text . '';
endif;
for ( $n = 1; $n <= $total; $n++ ) :
$n_display = number_format_i18n($n);
if ( $n == $current ) :
$page_links[] = "$n_display";
$dots = true;
else :
if ( $show_all || ( $n <= $end_size || ( $current && $n >= $current - $mid_size && $n <= $current + $mid_size ) || $n > $total - $end_size ) ) :
$link = str_replace('%_%', 1 == $n ? '' : $format, $base);
$link = str_replace('%#%', $n, $link);
if ( $add_args )
$link = add_query_arg( $add_args, $link );
$link .= $add_fragment;
$page_links[] = "$n_display";
$dots = true;
elseif ( $dots && !$show_all ) :
$page_links[] = '' . __( '…' ) . '';
$dots = false;
endif;
endif;
endfor;
if ( $prev_next && $current && ( $current < $total || -1 == $total ) ) :
$link = str_replace('%_%', $format, $base);
$link = str_replace('%#%', $current + 1, $link);
if ( $add_args )
$link = add_query_arg( $add_args, $link );
$link .= $add_fragment;
$page_links[] = '' . $next_text . '';
endif;
switch ( $type ) :
case 'array' :
return $page_links;
break;
case 'list' :
$r .= "
\n\t
";
$r .= join("
\n\t
", $page_links);
$r .= "
\n
\n";
break;
default :
$r = join("\n", $page_links);
break;
endswitch;
return $r;
}
/**
* Registers an admin colour scheme css file.
*
* Allows a plugin to register a new admin colour scheme. For example:
*
* wp_admin_css_color('classic', __('Classic'), admin_url("css/colors-classic.css"),
* array('#07273E', '#14568A', '#D54E21', '#2683AE'));
*
*
* @since 2.5.0
*
* @param string $key The unique key for this theme.
* @param string $name The name of the theme.
* @param string $url The url of the css file containing the colour scheme.
* @param array $colors Optional An array of CSS color definitions which are used to give the user a feel for the theme.
*/
function wp_admin_css_color($key, $name, $url, $colors = array()) {
global $_wp_admin_css_colors;
if ( !isset($_wp_admin_css_colors) )
$_wp_admin_css_colors = array();
$_wp_admin_css_colors[$key] = (object) array('name' => $name, 'url' => $url, 'colors' => $colors);
}
/**
* Registers the default Admin color schemes
*
* @since 3.0.0
*/
function register_admin_color_schemes() {
wp_admin_css_color( 'classic', _x( 'Blue', 'admin color scheme' ), admin_url( 'css/colors-classic.css' ),
array( '#5589aa', '#cfdfe9', '#d1e5ee', '#eff8ff' ) );
wp_admin_css_color( 'fresh', _x( 'Gray', 'admin color scheme' ), admin_url( 'css/colors-fresh.css' ),
array( '#7c7976', '#c6c6c6', '#e0e0e0', '#f1f1f1' ) );
}
/**
* Display the URL of a WordPress admin CSS file.
*
* @see WP_Styles::_css_href and its style_loader_src filter.
*
* @since 2.3.0
*
* @param string $file file relative to wp-admin/ without its ".css" extension.
*/
function wp_admin_css_uri( $file = 'wp-admin' ) {
if ( defined('WP_INSTALLING') ) {
$_file = "./$file.css";
} else {
$_file = admin_url("$file.css");
}
$_file = add_query_arg( 'version', get_bloginfo( 'version' ), $_file );
return apply_filters( 'wp_admin_css_uri', $_file, $file );
}
/**
* Enqueues or directly prints a stylesheet link to the specified CSS file.
*
* "Intelligently" decides to enqueue or to print the CSS file. If the
* 'wp_print_styles' action has *not* yet been called, the CSS file will be
* enqueued. If the wp_print_styles action *has* been called, the CSS link will
* be printed. Printing may be forced by passing TRUE as the $force_echo
* (second) parameter.
*
* For backward compatibility with WordPress 2.3 calling method: If the $file
* (first) parameter does not correspond to a registered CSS file, we assume
* $file is a file relative to wp-admin/ without its ".css" extension. A
* stylesheet link to that generated URL is printed.
*
* @package WordPress
* @since 2.3.0
* @uses $wp_styles WordPress Styles Object
*
* @param string $file Optional. Style handle name or file name (without ".css" extension) relative
* to wp-admin/. Defaults to 'wp-admin'.
* @param bool $force_echo Optional. Force the stylesheet link to be printed rather than enqueued.
*/
function wp_admin_css( $file = 'wp-admin', $force_echo = false ) {
global $wp_styles;
if ( !is_a($wp_styles, 'WP_Styles') )
$wp_styles = new WP_Styles();
// For backward compatibility
$handle = 0 === strpos( $file, 'css/' ) ? substr( $file, 4 ) : $file;
if ( $wp_styles->query( $handle ) ) {
if ( $force_echo || did_action( 'wp_print_styles' ) ) // we already printed the style queue. Print this one immediately
wp_print_styles( $handle );
else // Add to style queue
wp_enqueue_style( $handle );
return;
}
echo apply_filters( 'wp_admin_css', "\n", $file );
if ( is_rtl() )
echo apply_filters( 'wp_admin_css', "\n", "$file-rtl" );
}
/**
* Enqueues the default ThickBox js and css.
*
* If any of the settings need to be changed, this can be done with another js
* file similar to media-upload.js and theme-preview.js. That file should
* require array('thickbox') to ensure it is loaded after.
*
* @since 2.5.0
*/
function add_thickbox() {
wp_enqueue_script( 'thickbox' );
wp_enqueue_style( 'thickbox' );
if ( is_network_admin() )
add_action( 'admin_head', '_thickbox_path_admin_subfolder' );
}
/**
* Display the XHTML generator that is generated on the wp_head hook.
*
* @since 2.5.0
*/
function wp_generator() {
the_generator( apply_filters( 'wp_generator_type', 'xhtml' ) );
}
/**
* Display the generator XML or Comment for RSS, ATOM, etc.
*
* Returns the correct generator type for the requested output format. Allows
* for a plugin to filter generators overall the the_generator filter.
*
* @since 2.5.0
* @uses apply_filters() Calls 'the_generator' hook.
*
* @param string $type The type of generator to output - (html|xhtml|atom|rss2|rdf|comment|export).
*/
function the_generator( $type ) {
echo apply_filters('the_generator', get_the_generator($type), $type) . "\n";
}
/**
* Creates the generator XML or Comment for RSS, ATOM, etc.
*
* Returns the correct generator type for the requested output format. Allows
* for a plugin to filter generators on an individual basis using the
* 'get_the_generator_{$type}' filter.
*
* @since 2.5.0
* @uses apply_filters() Calls 'get_the_generator_$type' hook.
*
* @param string $type The type of generator to return - (html|xhtml|atom|rss2|rdf|comment|export).
* @return string The HTML content for the generator.
*/
function get_the_generator( $type = '' ) {
if ( empty( $type ) ) {
$current_filter = current_filter();
if ( empty( $current_filter ) )
return;
switch ( $current_filter ) {
case 'rss2_head' :
case 'commentsrss2_head' :
$type = 'rss2';
break;
case 'rss_head' :
case 'opml_head' :
$type = 'comment';
break;
case 'rdf_header' :
$type = 'rdf';
break;
case 'atom_head' :
case 'comments_atom_head' :
case 'app_head' :
$type = 'atom';
break;
}
}
switch ( $type ) {
case 'html':
$gen = '';
break;
case 'xhtml':
$gen = '';
break;
case 'atom':
$gen = 'WordPress';
break;
case 'rss2':
$gen = 'http://wordpress.org/?v=' . get_bloginfo_rss( 'version' ) . '';
break;
case 'rdf':
$gen = '';
break;
case 'comment':
$gen = '';
break;
case 'export':
$gen = '';
break;
}
return apply_filters( "get_the_generator_{$type}", $gen, $type );
}
/**
* Outputs the html checked attribute.
*
* Compares the first two arguments and if identical marks as checked
*
* @since 1.0.0
*
* @param mixed $checked One of the values to compare
* @param mixed $current (true) The other value to compare if not just true
* @param bool $echo Whether to echo or just return the string
* @return string html attribute or empty string
*/
function checked( $checked, $current = true, $echo = true ) {
return __checked_selected_helper( $checked, $current, $echo, 'checked' );
}
/**
* Outputs the html selected attribute.
*
* Compares the first two arguments and if identical marks as selected
*
* @since 1.0.0
*
* @param mixed $selected One of the values to compare
* @param mixed $current (true) The other value to compare if not just true
* @param bool $echo Whether to echo or just return the string
* @return string html attribute or empty string
*/
function selected( $selected, $current = true, $echo = true ) {
return __checked_selected_helper( $selected, $current, $echo, 'selected' );
}
/**
* Outputs the html disabled attribute.
*
* Compares the first two arguments and if identical marks as disabled
*
* @since 3.0.0
*
* @param mixed $disabled One of the values to compare
* @param mixed $current (true) The other value to compare if not just true
* @param bool $echo Whether to echo or just return the string
* @return string html attribute or empty string
*/
function disabled( $disabled, $current = true, $echo = true ) {
return __checked_selected_helper( $disabled, $current, $echo, 'disabled' );
}
/**
* Private helper function for checked, selected, and disabled.
*
* Compares the first two arguments and if identical marks as $type
*
* @since 2.8.0
* @access private
*
* @param any $helper One of the values to compare
* @param any $current (true) The other value to compare if not just true
* @param bool $echo Whether to echo or just return the string
* @param string $type The type of checked|selected|disabled we are doing
* @return string html attribute or empty string
*/
function __checked_selected_helper( $helper, $current, $echo, $type ) {
if ( (string) $helper === (string) $current )
$result = " $type='$type'";
else
$result = '';
if ( $echo )
echo $result;
return $result;
}
?>
) )
return;
$id = (int) $id;
if ( 0 === $id )
return;
wp_cache_delete($id, 'posts');
wp_cache_delete($id, 'post_meta');
clean_object_term_cache($id, 'post');
wp_cache_delete( 'wp_get_archives', 'general' );
do_action('clean_post_cache', $id);
if ( $children = $wpdb->get_col( $wpdb->prepare("SELECT ID FROM $wpdb->posts WHERE post_parent = %d", $id) ) ) {
foreach ( $children as $cid ) {
// Loop detection
if ( $cid == $id )
continue;
clean_post_cache( $cid );
}
}
if ( is_multisite() )
wp_cache_delete( $wpdb->blogid . '-' . $id, 'global-posts' );
}
/**
* Alias of update_post_cache().
*
* @see update_post_cache() Posts and pages are the same, alias is intentional
*
* @package WordPress
* @subpackage Cache
* @since 1.5.1
*
* @param array $pages list of page objects
*/
function update_page_cache(&$pages) {
update_post_cache($pages);
}
/**
* Will clean the page in the cache.
*
* Clean (read: delete) page from cache that matches $id. Will also clean cache
* associated with 'all_page_ids' and 'get_pages'.
*
* @package WordPress
* @subpackage Cache
* @since 2.0.0
*
* @uses do_action() Will call the 'clean_page_cache' hook action.
*
* @param int $id Page ID to clean
*/
function clean_page_cache($id) {
clean_post_cache($id);
wp_cache_delete( 'all_page_ids', 'posts' );
wp_cache_delete( 'get_pages', 'posts' );
do_action('clean_page_cache', $id);
}
/**
* Call major cache updating functions for list of Post objects.
*
* @package WordPress
* @subpackage Cache
* @since 1.5.0
*
* @uses $wpdb
* @uses update_post_cache()
* @uses update_object_term_cache()
* @uses update_postmeta_cache()
*
* @param array $posts Array of Post objects
* @param string $post_type The post type of the posts in $posts. Default is 'post'.
* @param bool $update_term_cache Whether to update the term cache. Default is true.
* @param bool $update_meta_cache Whether to update the meta cache. Default is true.
*/
function update_post_caches(&$posts, $post_type = 'post', $update_term_cache = true, $update_meta_cache = true) {
// No point in doing all this work if we didn't match any posts.
if ( !$posts )
return;
update_post_cache($posts);
$post_ids = array();
foreach ( $posts as $post )
$post_ids[] = $post->ID;
if ( empty($post_type) )
$post_type = 'post';
if ( $update_term_cache ) {
if ( is_array($post_type) ) {
$ptypes = $post_type;
} elseif ( 'any' == $post_type ) {
// Just use the post_types in the supplied posts.
foreach ( $posts as $post )
$ptypes[] = $post->post_type;
$ptypes = array_unique($ptypes);
} else {
$ptypes = array($post_type);
}
if ( ! empty($ptypes) )
update_object_term_cache($post_ids, $ptypes);
}
if ( $update_meta_cache )
update_postmeta_cache($post_ids);
}
/**
* Updates metadata cache for list of post IDs.
*
* Performs SQL query to retrieve the metadata for the post IDs and updates the
* metadata cache for the posts. Therefore, the functions, which call this
* function, do not need to perform SQL queries on their own.
*
* @package WordPress
* @subpackage Cache
* @since 2.1.0
*
* @uses $wpdb
*
* @param array $post_ids List of post IDs.
* @return bool|array Returns false if there is nothing to update or an array of metadata.
*/
function update_postmeta_cache($post_ids) {
return update_meta_cache('post', $post_ids);
}
/**
* Will clean the attachment in the cache.
*
* Cleaning means delete from the cache. Optionally will clean the term
* object cache associated with the attachment ID.
*
* This function will not run if $_wp_suspend_cache_invalidation is not empty. See
* wp_suspend_cache_invalidation().
*
* @package WordPress
* @subpackage Cache
* @since 3.0.0
*
* @uses do_action() Calls 'clean_attachment_cache' on $id.
*
* @param int $id The attachment ID in the cache to clean
* @param bool $clean_terms optional. Whether to clean terms cache
*/
function clean_attachment_cache($id, $clean_terms = false) {
global $_wp_suspend_cache_invalidation;
if ( !empty($_wp_suspend_cache_invalidation) )
return;
$id = (int) $id;
wp_cache_delete($id, 'posts');
wp_cache_delete($id, 'post_meta');
if ( $clean_terms )
clean_object_term_cache($id, 'attachment');
do_action('clean_attachment_cache', $id);
}
//
// Hooks
//
/**
* Hook for managing future post transitions to published.
*
* @since 2.3.0
* @access private
* @uses $wpdb
* @uses do_action() Calls 'private_to_published' on post ID if this is a 'private_to_published' call.
* @uses wp_clear_scheduled_hook() with 'publish_future_post' and post ID.
*
* @param string $new_status New post status
* @param string $old_status Previous post status
* @param object $post Object type containing the post information
*/
function _transition_post_status($new_status, $old_status, $post) {
global $wpdb;
if ( $old_status != 'publish' && $new_status == 'publish' ) {
// Reset GUID if transitioning to publish and it is empty
if ( '' == get_the_guid($post->ID) )
$wpdb->update( $wpdb->posts, array( 'guid' => get_permalink( $post->ID ) ), array( 'ID' => $post->ID ) );
do_action('private_to_published', $post->ID); // Deprecated, use private_to_publish
}
// If published posts changed clear the lastpostmodified cache
if ( 'publish' == $new_status || 'publish' == $old_status) {
foreach ( array( 'server', 'gmt', 'blog' ) as $timezone ) {
wp_cache_delete( "lastpostmodified:$timezone", 'timeinfo' );
wp_cache_delete( "lastpostdate:$timezone", 'timeinfo' );
}
}
// Always clears the hook in case the post status bounced from future to draft.
wp_clear_scheduled_hook('publish_future_post', array( $post->ID ) );
}
/**
* Hook used to schedule publication for a post marked for the future.
*
* The $post properties used and must exist are 'ID' and 'post_date_gmt'.
*
* @since 2.3.0
* @access private
*
* @param int $deprecated Not used. Can be set to null. Never implemented.
* Not marked as deprecated with _deprecated_argument() as it conflicts with
* wp_transition_post_status() and the default filter for _future_post_hook().
* @param object $post Object type containing the post information
*/
function _future_post_hook( $deprecated = '', $post ) {
wp_clear_scheduled_hook( 'publish_future_post', array( $post->ID ) );
wp_schedule_single_event( strtotime( get_gmt_from_date( $post->post_date ) . ' GMT') , 'publish_future_post', array( $post->ID ) );
}
/**
* Hook to schedule pings and enclosures when a post is published.
*
* @since 2.3.0
* @access private
* @uses $wpdb
* @uses XMLRPC_REQUEST and APP_REQUEST constants.
* @uses do_action() Calls 'xmlprc_publish_post' on post ID if XMLRPC_REQUEST is defined.
* @uses do_action() Calls 'app_publish_post' on post ID if APP_REQUEST is defined.
*
* @param int $post_id The ID in the database table of the post being published
*/
function _publish_post_hook($post_id) {
global $wpdb;
if ( defined('XMLRPC_REQUEST') )
do_action('xmlrpc_publish_post', $post_id);
if ( defined('APP_REQUEST') )
do_action('app_publish_post', $post_id);
if ( defined('WP_IMPORTING') )
return;
$data = array( 'post_id' => $post_id, 'meta_value' => '1' );
if ( get_option('default_pingback_flag') ) {
$wpdb->insert( $wpdb->postmeta, $data + array( 'meta_key' => '_pingme' ) );
do_action( 'added_postmeta', $wpdb->insert_id, $post_id, '_pingme', 1 );
}
$wpdb->insert( $wpdb->postmeta, $data + array( 'meta_key' => '_encloseme' ) );
do_action( 'added_postmeta', $wpdb->insert_id, $post_id, '_encloseme', 1 );
wp_schedule_single_event(time(), 'do_pings');
}
/**
* Hook used to prevent page/post cache and rewrite rules from staying dirty.
*
* Does two things. If the post is a page and has a template then it will
* update/add that template to the meta. For both pages and posts, it will clean
* the post cache to make sure that the cache updates to the changes done
* recently. For pages, the rewrite rules of WordPress are flushed to allow for
* any changes.
*
* The $post parameter, only uses 'post_type' property and 'page_template'
* property.
*
* @since 2.3.0
* @access private
* @uses $wp_rewrite Flushes Rewrite Rules.
*
* @param int $post_id The ID in the database table for the $post
* @param object $post Object type containing the post information
*/
function _save_post_hook($post_id, $post) {
if ( $post->post_type == 'page' ) {
clean_page_cache($post_id);
// Avoid flushing rules for every post during import.
if ( !defined('WP_IMPORTING') ) {
global $wp_rewrite;
$wp_rewrite->flush_rules(false);
}
} else {
clean_post_cache($post_id);
}
}
/**
* Retrieve post ancestors and append to post ancestors property.
*
* Will only retrieve ancestors once, if property is already set, then nothing
* will be done. If there is not a parent post, or post ID and post parent ID
* are the same then nothing will be done.
*
* The parameter is passed by reference, so nothing needs to be returned. The
* property will be updated and can be referenced after the function is
* complete. The post parent will be an ancestor and the parent of the post
* parent will be an ancestor. There will only be two ancestors at the most.
*
* @since 2.5.0
* @access private
* @uses $wpdb
*
* @param object $_post Post data.
* @return null When nothing needs to be done.
*/
function _get_post_ancestors(&$_post) {
global $wpdb;
if ( isset($_post->ancestors) )
return;
$_post->ancestors = array();
if ( empty($_post->post_parent) || $_post->ID == $_post->post_parent )
return;
$id = $_post->ancestors[] = $_post->post_parent;
while ( $ancestor = $wpdb->get_var( $wpdb->prepare("SELECT `post_parent` FROM $wpdb->posts WHERE ID = %d LIMIT 1", $id) ) ) {
// Loop detection: If the ancestor has been seen before, break.
if ( ( $ancestor == $_post->ID ) || in_array($ancestor, $_post->ancestors) )
break;
$id = $_post->ancestors[] = $ancestor;
}
}
/**
* Determines which fields of posts are to be saved in revisions.
*
* Does two things. If passed a post *array*, it will return a post array ready
* to be inserted into the posts table as a post revision. Otherwise, returns
* an array whose keys are the post fields to be saved for post revisions.
*
* @package WordPress
* @subpackage Post_Revisions
* @since 2.6.0
* @access private
* @uses apply_filters() Calls '_wp_post_revision_fields' on 'title', 'content' and 'excerpt' fields.
*
* @param array $post Optional a post array to be processed for insertion as a post revision.
* @param bool $autosave optional Is the revision an autosave?
* @return array Post array ready to be inserted as a post revision or array of fields that can be versioned.
*/
function _wp_post_revision_fields( $post = null, $autosave = false ) {
static $fields = false;
if ( !$fields ) {
// Allow these to be versioned
$fields = array(
'post_title' => __( 'Title' ),
'post_content' => __( 'Content' ),
'post_excerpt' => __( 'Excerpt' ),
);
// Runs only once
$fields = apply_filters( '_wp_post_revision_fields', $fields );
// WP uses these internally either in versioning or elsewhere - they cannot be versioned
foreach ( array( 'ID', 'post_name', 'post_parent', 'post_date', 'post_date_gmt', 'post_status', 'post_type', 'comment_count', 'post_author' ) as $protect )
unset( $fields[$protect] );
}
if ( !is_array($post) )
return $fields;
$return = array();
foreach ( array_intersect( array_keys( $post ), array_keys( $fields ) ) as $field )
$return[$field] = $post[$field];
$return['post_parent'] = $post['ID'];
$return['post_status'] = 'inherit';
$return['post_type'] = 'revision';
$return['post_name'] = $autosave ? "$post[ID]-autosave" : "$post[ID]-revision";
$return['post_date'] = isset($post['post_modified']) ? $post['post_modified'] : '';
$return['post_date_gmt'] = isset($post['post_modified_gmt']) ? $post['post_modified_gmt'] : '';
return $return;
}
/**
* 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;
}
/**
* Retrieve the autosaved data of the specified post.
*
* Returns a post object containing the information that was autosaved for the
* specified post.
*
* @package WordPress
* @subpackage Post_Revisions
* @since 2.6.0
*
* @param int $post_id The post ID.
* @return object|bool The autosaved data or false on failure or when no autosave exists.
*/
function wp_get_post_autosave( $post_id ) {
if ( !$post = get_post( $post_id ) )
return false;
$q = array(
'name' => "{$post->ID}-autosave",
'post_parent' => $post->ID,
'post_type' => 'revision',
'post_status' => 'inherit'
);
// Use WP_Query so that the result gets cached
$autosave_query = new WP_Query;
add_action( 'parse_query', '_wp_get_post_autosave_hack' );
$autosave = $autosave_query->query( $q );
remove_action( 'parse_query', '_wp_get_post_autosave_hack' );
if ( $autosave && is_array($autosave) && is_object($autosave[0]) )
return $autosave[0];
return false;
}
/**
* Internally used to hack WP_Query into submission.
*
* @package WordPress
* @subpackage Post_Revisions
* @since 2.6.0
*
* @param object $query WP_Query object
*/
function _wp_get_post_autosave_hack( $query ) {
$query->is_single = false;
}
/**
* Determines if the specified post is a revision.
*
* @package WordPress
* @subpackage Post_Revisions
* @since 2.6.0
*
* @param int|object $post Post ID or post object.
* @return bool|int False if not a revision, ID of revision's parent otherwise.
*/
function wp_is_post_revision( $post ) {
if ( !$post = wp_get_post_revision( $post ) )
return false;
return (int) $post->post_parent;
}
/**
* Determines if the specified post is an autosave.
*
* @package WordPress
* @subpackage Post_Revisions
* @since 2.6.0
*
* @param int|object $post Post ID or post object.
* @return bool|int False if not a revision, ID of autosave's parent otherwise
*/
function wp_is_post_autosave( $post ) {
if ( !$post = wp_get_post_revision( $post ) )
return false;
if ( "{$post->post_parent}-autosave" !== $post->post_name )
return false;
return (int) $post->post_parent;
}
/**
* Inserts post data into the posts table as a post revision.
*
* @package WordPress
* @subpackage Post_Revisions
* @since 2.6.0
*
* @uses wp_insert_post()
*
* @param int|object|array $post Post ID, post object OR post array.
* @param bool $autosave Optional. Is the revision an autosave?
* @return mixed Null or 0 if error, new revision ID if success.
*/
function _wp_put_post_revision( $post = null, $autosave = false ) {
if ( is_object($post) )
$post = get_object_vars( $post );
elseif ( !is_array($post) )
$post = get_post($post, ARRAY_A);
if ( !$post || empty($post['ID']) )
return;
if ( isset($post['post_type']) && 'revision' == $post['post_type'] )
return new WP_Error( 'post_type', __( 'Cannot create a revision of a revision' ) );
$post = _wp_post_revision_fields( $post, $autosave );
$post = add_magic_quotes($post); //since data is from db
$revision_id = wp_insert_post( $post );
if ( is_wp_error($revision_id) )
return $revision_id;
if ( $revision_id )
do_action( '_wp_put_post_revision', $revision_id );
return $revision_id;
}
/**
* Gets a post revision.
*
* @package WordPress
* @subpackage Post_Revisions
* @since 2.6.0
*
* @uses get_post()
*
* @param int|object $post Post ID or post object
* @param string $output Optional. OBJECT, ARRAY_A, or ARRAY_N.
* @param string $filter Optional sanitation filter. @see sanitize_post()
* @return mixed Null if error or post object if success
*/
function &wp_get_post_revision(&$post, $output = OBJECT, $filter = 'raw') {
$null = null;
if ( !$revision = get_post( $post, OBJECT, $filter ) )
return $revision;
if ( 'revision' !== $revision->post_type )
return $null;
if ( $output == OBJECT ) {
return $revision;
} elseif ( $output == ARRAY_A ) {
$_revision = get_object_vars($revision);
return $_revision;
} elseif ( $output == ARRAY_N ) {
$_revision = array_values(get_object_vars($revision));
return $_revision;
}
return $revision;
}
/**
* Restores a post to the specified revision.
*
* Can restore a past revision using all fields of the post revision, or only selected fields.
*
* @package WordPress
* @subpackage Post_Revisions
* @since 2.6.0
*
* @uses wp_get_post_revision()
* @uses wp_update_post()
* @uses do_action() Calls 'wp_restore_post_revision' on post ID and revision ID if wp_update_post()
* is successful.
*
* @param int|object $revision_id Revision ID or revision object.
* @param array $fields Optional. What fields to restore from. Defaults to all.
* @return mixed Null if error, false if no fields to restore, (int) post ID if success.
*/
function wp_restore_post_revision( $revision_id, $fields = null ) {
if ( !$revision = wp_get_post_revision( $revision_id, ARRAY_A ) )
return $revision;
if ( !is_array( $fields ) )
$fields = array_keys( _wp_post_revision_fields() );
$update = array();
foreach( array_intersect( array_keys( $revision ), $fields ) as $field )
$update[$field] = $revision[$field];
if ( !$update )
return false;
$update['ID'] = $revision['post_parent'];
$update = add_magic_quotes( $update ); //since data is from db
$post_id = wp_update_post( $update );
if ( is_wp_error( $post_id ) )
return $post_id;
if ( $post_id )
do_action( 'wp_restore_post_revision', $post_id, $revision['ID'] );
return $post_id;
}
/**
* Deletes a revision.
*
* Deletes the row from the posts table corresponding to the specified revision.
*
* @package WordPress
* @subpackage Post_Revisions
* @since 2.6.0
*
* @uses wp_get_post_revision()
* @uses wp_delete_post()
*
* @param int|object $revision_id Revision ID or revision object.
* @return mixed Null or WP_Error if error, deleted post if success.
*/
function wp_delete_post_revision( $revision_id ) {
if ( !$revision = wp_get_post_revision( $revision_id ) )
return $revision;
$delete = wp_delete_post( $revision->ID );
if ( is_wp_error( $delete ) )
return $delete;
if ( $delete )
do_action( 'wp_delete_post_revision', $revision->ID, $revision );
return $delete;
}
/**
* Returns all revisions of specified post.
*
* @package WordPress
* @subpackage Post_Revisions
* @since 2.6.0
*
* @uses get_children()
*
* @param int|object $post_id Post ID or post object
* @return array empty if no revisions
*/
function wp_get_post_revisions( $post_id = 0, $args = null ) {
if ( ! WP_POST_REVISIONS )
return array();
if ( ( !$post = get_post( $post_id ) ) || empty( $post->ID ) )
return array();
$defaults = array( 'order' => 'DESC', 'orderby' => 'date' );
$args = wp_parse_args( $args, $defaults );
$args = array_merge( $args, array( 'post_parent' => $post->ID, 'post_type' => 'revision', 'post_status' => 'inherit' ) );
if ( !$revisions = get_children( $args ) )
return array();
return $revisions;
}
function _set_preview($post) {
if ( ! is_object($post) )
return $post;
$preview = wp_get_post_autosave($post->ID);
if ( ! is_object($preview) )
return $post;
$preview = sanitize_post($preview);
$post->post_content = $preview->post_content;
$post->post_title = $preview->post_title;
$post->post_excerpt = $preview->post_excerpt;
return $post;
}
function _show_post_preview() {
if ( isset($_GET['preview_id']) && isset($_GET['preview_nonce']) ) {
$id = (int) $_GET['preview_id'];
if ( false == wp_verify_nonce( $_GET['preview_nonce'], 'post_preview_' . $id ) )
wp_die( __('You do not have permission to preview drafts.') );
add_filter('the_preview', '_set_preview');
}
}
/**
* Returns the post's parent's post_ID
*
* @since 3.1.0
*
* @param int $post_id
*
* @return int|bool false on error
*/
function wp_get_post_parent_id( $post_ID ) {
$post = get_post( $post_ID );
if ( !$post || is_wp_error( $post ) )
return false;
return (int) $post->post_parent;
}
/**
* Checks the given subset of the post hierarchy for hierarchy loops.
* Prevents loops from forming and breaks those that it finds.
*
* Attached to the wp_insert_post_parent filter.
*
* @since 3.1.0
* @uses wp_find_hierarchy_loop()
*
* @param int $post_parent ID of the parent for the post we're checking.
* @parem int $post_ID ID of the post we're checking.
*
* @return int The new post_parent for the post.
*/
function wp_check_post_hierarchy_for_loops( $post_parent, $post_ID ) {
// Nothing fancy here - bail
if ( !$post_parent )
return 0;
// New post can't cause a loop
if ( empty( $post_ID ) )
return $post_parent;
// Can't be its own parent
if ( $post_parent == $post_ID )
return 0;
// Now look for larger loops
if ( !$loop = wp_find_hierarchy_loop( 'wp_get_post_parent_id', $post_ID, $post_parent ) )
return $post_parent; // No loop
// Setting $post_parent to the given value causes a loop
if ( isset( $loop[$post_ID] ) )
return 0;
// There's a loop, but it doesn't contain $post_ID. Break the loop.
foreach ( array_keys( $loop ) as $loop_member )
wp_update_post( array( 'ID' => $loop_member, 'post_parent' => 0 ) );
return $post_parent;
}
/**
* Returns an array of post format slugs to their translated and pretty display versions
*
* @since 3.1.0
*
* @return array The array of translations
*/
function get_post_format_strings() {
$strings = array(
'standard' => _x( 'Standard', 'Post format' ), // Special case. any value that evals to false will be considered standard
'aside' => _x( 'Aside', 'Post format' ),
'chat' => _x( 'Chat', 'Post format' ),
'gallery' => _x( 'Gallery', 'Post format' ),
'link' => _x( 'Link', 'Post format' ),
'image' => _x( 'Image', 'Post format' ),
'quote' => _x( 'Quote', 'Post format' ),
'status' => _x( 'Status', 'Post format' ),
'video' => _x( 'Video', 'Post format' ),
'audio' => _x( 'Audio', 'Post format' ),
);
return $strings;
}
/**
* Retrieves an array of post format slugs.
*
* @since 3.1.0
*
* @return array The array of post format slugs.
*/
function get_post_format_slugs() {
$slugs = array_keys( get_post_format_strings() );
return array_combine( $slugs, $slugs );
}
/**
* Returns a pretty, translated version of a post format slug
*
* @since 3.1.0
*
* @param string $slug A post format slug
* @return string The translated post format name
*/
function get_post_format_string( $slug ) {
$strings = get_post_format_strings();
if ( !$slug )
return $strings['standard'];
else
return ( isset( $strings[$slug] ) ) ? $strings[$slug] : '';
}
/**
* Sets a post thumbnail.
*
* @since 3.1.0
*
* @param int|object $post Post ID or object where thumbnail should be attached.
* @param int $thumbnail_id Thumbnail to attach.
* @return bool True on success, false on failure.
*/
function set_post_thumbnail( $post, $thumbnail_id ) {
$post = get_post( $post );
$thumbnail_id = absint( $thumbnail_id );
if ( $post && $thumbnail_id && get_post( $thumbnail_id ) ) {
$thumbnail_html = wp_get_attachment_image( $thumbnail_id, 'thumbnail' );
if ( ! empty( $thumbnail_html ) ) {
update_post_meta( $post->ID, '_thumbnail_id', $thumbnail_id );
return true;
}
}
return false;
}
/**
* Removes a post thumbnail.
*
* @since 3.3.0
*
* @param int|object $post Post ID or object where thumbnail should be removed from.
* @return bool True on success, false on failure.
*/
function delete_post_thumbnail( $post ) {
$post = get_post( $post );
if ( $post )
return delete_post_meta( $post->ID, '_thumbnail_id' );
return false;
}
/**
* Returns a link to a post format index.
*
* @since 3.1.0
*
* @param string $format Post format
* @return string Link
*/
function get_post_format_link( $format ) {
$term = get_term_by('slug', 'post-format-' . $format, 'post_format' );
if ( ! $term || is_wp_error( $term ) )
return false;
return get_term_link( $term );
}
/**
* Filters the request to allow for the format prefix.
*
* @access private
* @since 3.1.0
*/
function _post_format_request( $qvs ) {
if ( ! isset( $qvs['post_format'] ) )
return $qvs;
$slugs = get_post_format_slugs();
if ( isset( $slugs[ $qvs['post_format'] ] ) )
$qvs['post_format'] = 'post-format-' . $slugs[ $qvs['post_format'] ];
$tax = get_taxonomy( 'post_format' );
if ( ! is_admin() )
$qvs['post_type'] = $tax->object_type;
return $qvs;
}
add_filter( 'request', '_post_format_request' );
/**
* Filters the post format term link to remove the format prefix.
*
* @access private
* @since 3.1.0
*/
function _post_format_link( $link, $term, $taxonomy ) {
global $wp_rewrite;
if ( 'post_format' != $taxonomy )
return $link;
if ( $wp_rewrite->get_extra_permastruct( $taxonomy ) ) {
return str_replace( "/{$term->slug}", '/' . str_replace( 'post-format-', '', $term->slug ), $link );
} else {
$link = remove_query_arg( 'post_format', $link );
return add_query_arg( 'post_format', str_replace( 'post-format-', '', $term->slug ), $link );
}
}
add_filter( 'term_link', '_post_format_link', 10, 3 );
/**
* Remove the post format prefix from the name property of the term object created by get_term().
*
* @access private
* @since 3.1.0
*/
function _post_format_get_term( $term ) {
if ( isset( $term->slug ) ) {
$term->name = get_post_format_string( str_replace( 'post-format-', '', $term->slug ) );
}
return $term;
}
add_filter( 'get_post_format', '_post_format_get_term' );
/**
* Remove the post format prefix from the name property of the term objects created by get_terms().
*
* @access private
* @since 3.1.0
*/
function _post_format_get_terms( $terms, $taxonomies, $args ) {
if ( in_array( 'post_format', (array) $taxonomies ) ) {
if ( isset( $args['fields'] ) && 'names' == $args['fields'] ) {
foreach( $terms as $order => $name ) {
$terms[$order] = get_post_format_string( str_replace( 'post-format-', '', $name ) );
}
} else {
foreach ( (array) $terms as $order => $term ) {
if ( isset( $term->taxonomy ) && 'post_format' == $term->taxonomy ) {
$terms[$order]->name = get_post_format_string( str_replace( 'post-format-', '', $term->slug ) );
}
}
}
}
return $terms;
}
add_filter( 'get_terms', '_post_format_get_terms', 10, 3 );
/**
* Remove the post format prefix from the name property of the term objects created by wp_get_object_terms().
*
* @access private
* @since 3.1.0
*/
function _post_format_wp_get_object_terms( $terms ) {
foreach ( (array) $terms as $order => $term ) {
if ( isset( $term->taxonomy ) && 'post_format' == $term->taxonomy ) {
$terms[$order]->name = get_post_format_string( str_replace( 'post-format-', '', $term->slug ) );
}
}
return $terms;
}
add_filter( 'wp_get_object_terms', '_post_format_wp_get_object_terms' );
/**
* Update the custom taxonomies' term counts when a post's status is changed. For example, default posts term counts (for custom taxonomies) don't include private / draft posts.
*
* @access private
* @param string $new_status
* @param string $old_status
* @param object $post
* @since 3.3.0
*/
function _update_term_count_on_transition_post_status( $new_status, $old_status, $post ) {
// Update counts for the post's terms.
foreach ( (array) get_object_taxonomies( $post->post_type ) as $taxonomy ) {
$tt_ids = wp_get_object_terms( $post->ID, $taxonomy, array( 'fields' => 'tt_ids' ) );
wp_update_term_count( $tt_ids, $taxonomy );
}
}
?>
Warning: Cannot modify header information - headers already sent by (output started at /var/www/sam117/html/waerme/wp-includes/general-template.php:20) in /var/www/sam117/html/waerme/wp-includes/pluggable.php on line 866