3 * Post functions and post utility function
11 * get_attached_file() - Get metadata for an attached file
13 * {@internal Missing Long Description}}
19 * @param int $attachment_id Attachment ID
20 * @param bool $unfiltered Whether to apply filters or not
21 * @return array {@internal Missing Description}}
23 function get_attached_file( $attachment_id, $unfiltered = false ) {
24 $file = get_post_meta( $attachment_id, '_wp_attached_file', true );
27 return apply_filters( 'get_attached_file', $file, $attachment_id );
31 * update_attached_file() - Update attached file metadata
33 * {@internal Missing Long Description}}
39 * @param int $attachment_id Attachment ID
40 * @param string $file {@internal Missing Description}}
41 * @return bool|mixed {@internal Missing Description}}
43 function update_attached_file( $attachment_id, $file ) {
44 if ( !get_post( $attachment_id ) )
47 $old_file = get_attached_file( $attachment_id, true );
49 $file = apply_filters( 'update_attached_file', $file, $attachment_id );
52 return update_post_meta( $attachment_id, '_wp_attached_file', $file, $old_file );
54 return add_post_meta( $attachment_id, '_wp_attached_file', $file );
58 * get_children() - Get post children
60 * {@internal Missing Long Description}}
66 * @param mixed $args {@internal Missing Description}}
67 * @param string $output {@internal Missing Description}}
68 * @return mixed {@internal Missing Description}}
70 function &get_children($args = '', $output = OBJECT) {
71 if ( empty( $args ) ) {
72 if ( isset( $GLOBALS['post'] ) ) {
73 $args = 'post_parent=' . (int) $GLOBALS['post']->post_parent;
77 } elseif ( is_object( $args ) ) {
78 $args = 'post_parent=' . (int) $args->post_parent;
79 } elseif ( is_numeric( $args ) ) {
80 $args = 'post_parent=' . (int) $args;
84 'numberposts' => -1, 'post_type' => '',
85 'post_status' => '', 'post_parent' => 0
88 $r = wp_parse_args( $args, $defaults );
90 $children = get_posts( $r );
95 update_post_cache($children);
97 foreach ( $children as $key => $child )
98 $kids[$child->ID] =& $children[$key];
100 if ( $output == OBJECT ) {
102 } elseif ( $output == ARRAY_A ) {
103 foreach ( $kids as $kid )
104 $weeuns[$kid->ID] = get_object_vars($kids[$kid->ID]);
106 } elseif ( $output == ARRAY_N ) {
107 foreach ( $kids as $kid )
108 $babes[$kid->ID] = array_values(get_object_vars($kids[$kid->ID]));
116 * get_extended() - get extended entry info (<!--more-->)
118 * {@internal Missing Long Description}}
124 * @param string $post {@internal Missing Description}}
125 * @return array {@internal Missing Description}}
127 function get_extended($post) {
128 //Match the new style more links
129 if ( preg_match('/<!--more(.*?)?-->/', $post, $matches) ) {
130 list($main, $extended) = explode($matches[0], $post, 2);
136 // Strip leading and trailing whitespace
137 $main = preg_replace('/^[\s]*(.*)[\s]*$/', '\\1', $main);
138 $extended = preg_replace('/^[\s]*(.*)[\s]*$/', '\\1', $extended);
140 return array('main' => $main, 'extended' => $extended);
144 * get_post() - Retrieves post data given a post ID or post object.
146 * {@internal Missing Long Description}}
153 * @param int|object &$post post ID or post object
154 * @param string $output {@internal Missing Description}}
155 * @param string $filter {@internal Missing Description}}
156 * @return mixed {@internal Missing Description}}
158 function &get_post(&$post, $output = OBJECT, $filter = 'raw') {
162 if ( empty($post) ) {
163 if ( isset($GLOBALS['post']) )
164 $_post = & $GLOBALS['post'];
167 } elseif ( is_object($post) ) {
168 _get_post_ancestors($post);
169 wp_cache_add($post->ID, $post, 'posts');
173 if ( ! $_post = wp_cache_get($post, 'posts') ) {
174 $_post = & $wpdb->get_row($wpdb->prepare("SELECT * FROM $wpdb->posts WHERE ID = %d LIMIT 1", $post));
175 _get_post_ancestors($_post);
176 wp_cache_add($_post->ID, $_post, 'posts');
180 $_post = sanitize_post($_post, $filter);
182 if ( $output == OBJECT ) {
184 } elseif ( $output == ARRAY_A ) {
185 $__post = get_object_vars($_post);
187 } elseif ( $output == ARRAY_N ) {
188 $__post = array_values(get_object_vars($_post));
196 * get_post_ancestors() - Retrieve ancestors for a post
202 * @param string $field {@internal Missing Description}}
203 * @param int|object &$post post ID or post object
204 * @return array of ancestor IDs
206 function get_post_ancestors($post) {
209 if ( !empty($post->ancestors) )
210 return $post->ancestors;
216 * get_post_field() - Retrieve a field based on a post ID.
222 * @param string $field {@internal Missing Description}}
223 * @param id $post Post ID
224 * @param string $context Optional. How to filter the field
225 * @return WP_Error|string Value in post field or WP_Error on failure
227 function get_post_field( $field, $post, $context = 'display' ) {
229 $post = get_post( $post );
231 if ( is_wp_error($post) )
234 if ( !is_object($post) )
237 if ( !isset($post->$field) )
240 return sanitize_post_field($field, $post->$field, $post->ID, $context);
244 * get_post_mime_type() - Takes a post ID, returns its mime type.
250 * @param int $ID Post ID
251 * @return bool|string False on failure or returns the mime type
253 function get_post_mime_type($ID = '') {
254 $post = & get_post($ID);
256 if ( is_object($post) )
257 return $post->post_mime_type;
263 * get_post_status() - Takes a post ID and returns its status
265 * {@internal Missing Long Description}}
271 * @param int $ID {@internal Missing Description}}
272 * @return string|bool post status or false
274 function get_post_status($ID = '') {
275 $post = get_post($ID);
277 if ( is_object($post) ) {
278 if ( ('attachment' == $post->post_type) && $post->post_parent && ($post->ID != $post->post_parent) )
279 return get_post_status($post->post_parent);
281 return $post->post_status;
288 * get_post_statuses( ) - Retuns the possible user post status values
290 * Posts have a limited set of valid status values, this provides the
291 * post_status values and descriptions.
299 function get_post_statuses( ) {
301 'draft' => __('Draft'),
302 'pending' => __('Pending Review'),
303 'private' => __('Private'),
304 'publish' => __('Published')
311 * get_page_statuses( ) - Retuns the possible user page status values
313 * Pages have a limited set of valid status values, this provides the
314 * post_status values and descriptions.
322 function get_page_statuses( ) {
324 'draft' => __('Draft'),
325 'private' => __('Private'),
326 'publish' => __('Published')
333 * get_post_type() - Returns post type
335 * {@internal Missing Long Description}}
342 * @uses $posts {@internal Missing Description}}
344 * @param mixed $post post object or post ID
345 * @return mixed post type or false
347 function get_post_type($post = false) {
350 if ( false === $post )
352 elseif ( (int) $post )
353 $post = get_post($post, OBJECT);
355 if ( is_object($post) )
356 return $post->post_type;
362 * set_post_type() - Set post type
364 * {@internal Missing Long Description}}
371 * @uses $posts {@internal Missing Description}}
373 * @param mixed $post_id post ID
374 * @param mixed post type
375 * @return bool {@internal Missing Description}}
377 function set_post_type( $post_id = 0, $post_type = 'post' ) {
380 $post_type = sanitize_post_field('post_type', $post_type, $post_id, 'db');
381 $return = $wpdb->query( $wpdb->prepare("UPDATE $wpdb->posts SET post_type = %s WHERE ID = %d", $post_type, $post_id) );
383 if ( 'page' == $post_type )
384 clean_page_cache($post_id);
386 clean_post_cache($post_id);
392 * get_posts() - Returns a number of posts
394 * {@internal Missing Long Description}}
401 * @param array $args {@internal Missing Description}}
402 * @return array {@internal Missing Description}}
404 function get_posts($args = null) {
408 'numberposts' => 5, 'offset' => 0,
409 'category' => 0, 'orderby' => 'post_date',
410 'order' => 'DESC', 'include' => '',
411 'exclude' => '', 'meta_key' => '',
412 'meta_value' =>'', 'post_type' => 'post',
413 'post_status' => 'publish', 'post_parent' => 0
416 $r = wp_parse_args( $args, $defaults );
417 extract( $r, EXTR_SKIP );
419 $numberposts = (int) $numberposts;
420 $offset = (int) $offset;
421 $category = (int) $category;
422 $post_parent = (int) $post_parent;
425 if ( !empty($include) ) {
426 $offset = 0; //ignore offset, category, exclude, meta_key, and meta_value, post_parent if using include
432 $incposts = preg_split('/[\s,]+/',$include);
433 $numberposts = count($incposts); // only the number of posts included
434 if ( count($incposts) ) {
435 foreach ( $incposts as $incpost ) {
436 if (empty($inclusions))
437 $inclusions = $wpdb->prepare(' AND ( ID = %d ', $incpost);
439 $inclusions .= $wpdb->prepare(' OR ID = %d ', $incpost);
443 if (!empty($inclusions))
447 if ( !empty($exclude) ) {
448 $exposts = preg_split('/[\s,]+/',$exclude);
449 if ( count($exposts) ) {
450 foreach ( $exposts as $expost ) {
451 if (empty($exclusions))
452 $exclusions = $wpdb->prepare(' AND ( ID <> %d ', $expost);
454 $exclusions .= $wpdb->prepare(' AND ID <> %d ', $expost);
458 if (!empty($exclusions))
462 if ( preg_match( '/.+ +(ASC|DESC)/i', $orderby ) )
463 $order = ''; // orderby has its own order, so we'll use that
465 $query = "SELECT DISTINCT * FROM $wpdb->posts ";
466 $query .= empty( $category ) ? '' : ", $wpdb->term_relationships, $wpdb->term_taxonomy ";
467 $query .= empty( $meta_key ) ? '' : ", $wpdb->postmeta ";
468 $query .= " WHERE 1=1 ";
469 $query .= empty( $post_type ) ? '' : $wpdb->prepare("AND post_type = %s ", $post_type);
470 $query .= empty( $post_status ) ? '' : $wpdb->prepare("AND post_status = %s ", $post_status);
471 $query .= "$exclusions $inclusions " ;
472 $query .= empty( $category ) ? '' : $wpdb->prepare("AND ($wpdb->posts.ID = $wpdb->term_relationships.object_id AND $wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id AND $wpdb->term_taxonomy.term_id = %d AND $wpdb->term_taxonomy.taxonomy = 'category')", $category);
473 $query .= empty( $post_parent ) ? '' : $wpdb->prepare("AND $wpdb->posts.post_parent = %d ", $post_parent);
474 // expected_slashed ($meta_key, $meta_value) -- Also, this looks really funky, doesn't seem like it works
475 $query .= empty( $meta_key ) | empty($meta_value) ? '' : " AND ($wpdb->posts.ID = $wpdb->postmeta.post_id AND $wpdb->postmeta.meta_key = '$meta_key' AND $wpdb->postmeta.meta_value = '$meta_value' )";
476 $query .= empty( $post_mime_type ) ? '' : wp_post_mime_type_where($post_mime_type);
477 $query .= " GROUP BY $wpdb->posts.ID ORDER BY " . $orderby . ' ' . $order;
478 if ( 0 < $numberposts )
479 $query .= $wpdb->prepare(" LIMIT %d,%d", $offset, $numberposts);
481 $posts = $wpdb->get_results($query);
483 update_post_caches($posts);
489 // Post meta functions
493 * add_post_meta() - adds metadata for post
495 * {@internal Missing Long Description}}
502 * @param int $post_id post ID
503 * @param string $key {@internal Missing Description}}
504 * @param mixed $value {@internal Missing Description}}
505 * @param bool $unique whether to check for a value with the same key
506 * @return bool {@internal Missing Description}}
508 function add_post_meta($post_id, $meta_key, $meta_value, $unique = false) {
511 // expected_slashed ($meta_key)
512 $meta_key = stripslashes($meta_key);
514 if ( $unique && $wpdb->get_var( $wpdb->prepare( "SELECT meta_key FROM $wpdb->postmeta WHERE meta_key = %s AND post_id = %d", $meta_key, $post_id ) ) )
517 $meta_value = maybe_serialize($meta_value);
519 $wpdb->insert( $wpdb->postmeta, compact( 'post_id', 'meta_key', 'meta_value' ) );
521 wp_cache_delete($post_id, 'post_meta');
527 * delete_post_meta() - delete post metadata
529 * {@internal Missing Long Description}}
536 * @param int $post_id post ID
537 * @param string $key {@internal Missing Description}}
538 * @param mixed $value {@internal Missing Description}}
539 * @return bool {@internal Missing Description}}
541 function delete_post_meta($post_id, $key, $value = '') {
544 $post_id = absint( $post_id );
546 // expected_slashed ($key, $value)
547 $key = stripslashes( $key );
548 $value = stripslashes( $value );
550 if ( empty( $value ) )
551 $meta_id = $wpdb->get_var( $wpdb->prepare( "SELECT meta_id FROM $wpdb->postmeta WHERE post_id = %d AND meta_key = %s", $post_id, $key ) );
553 $meta_id = $wpdb->get_var( $wpdb->prepare( "SELECT meta_id FROM $wpdb->postmeta WHERE post_id = %d AND meta_key = %s AND meta_value = %s", $post_id, $key, $value ) );
558 if ( empty( $value ) )
559 $wpdb->query( $wpdb->prepare( "DELETE FROM $wpdb->postmeta WHERE post_id = %d AND meta_key = %s", $post_id, $key ) );
561 $wpdb->query( $wpdb->prepare( "DELETE FROM $wpdb->postmeta WHERE post_id = %d AND meta_key = %s AND meta_value = %s", $post_id, $key, $value ) );
563 wp_cache_delete($post_id, 'post_meta');
569 * get_post_meta() - Get a post meta field
571 * {@internal Missing Long Description}}
578 * @param int $post_id post ID
579 * @param string $key The meta key to retrieve
580 * @param bool $single Whether to return a single value
581 * @return mixed {@internal Missing Description}}
583 function get_post_meta($post_id, $key, $single = false) {
584 $post_id = (int) $post_id;
586 $meta_cache = wp_cache_get($post_id, 'post_meta');
588 if ( isset($meta_cache[$key]) ) {
590 return maybe_unserialize( $meta_cache[$key][0] );
592 return maybe_unserialize( $meta_cache[$key] );
596 if ( !$meta_cache ) {
597 update_postmeta_cache($post_id);
598 $meta_cache = wp_cache_get($post_id, 'post_meta');
602 if ( isset($meta_cache[$key][0]) )
603 return maybe_unserialize($meta_cache[$key][0]);
607 return maybe_unserialize($meta_cache[$key]);
612 * update_post_meta() - Update a post meta field
614 * {@internal Missing Long Description}}
621 * @param int $post_id post ID
622 * @param string $key {@internal Missing Description}}
623 * @param mixed $value {@internal Missing Description}}
624 * @param mixed $prev_value previous value (for differentiating between meta fields with the same key and post ID)
625 * @return bool {@internal Missing Description}}
627 function update_post_meta($post_id, $meta_key, $meta_value, $prev_value = '') {
630 $meta_value = maybe_serialize($meta_value);
631 $prev_value = maybe_serialize($prev_value);
633 // expected_slashed ($meta_key)
634 $meta_key = stripslashes($meta_key);
636 if ( ! $wpdb->get_var( $wpdb->prepare( "SELECT meta_key FROM $wpdb->postmeta WHERE meta_key = %s AND post_id = %d", $meta_key, $post_id ) ) )
639 $data = compact( 'meta_value' );
640 $where = compact( 'meta_key', 'post_id' );
642 if ( !empty( $prev_value ) )
643 $where['meta_value'] = $prev_value;
645 $wpdb->update( $wpdb->postmeta, $data, $where );
646 wp_cache_delete($post_id, 'post_meta');
651 * delete_post_meta_by_key() - Delete everything from post meta matching $post_meta_key
658 * @param string $post_meta_key What to search for when deleting
659 * @return bool Whether the post meta key was deleted from the database
661 function delete_post_meta_by_key($post_meta_key) {
663 if ( $wpdb->query($wpdb->prepare("DELETE FROM $wpdb->postmeta WHERE meta_key = %s", $post_meta_key)) ) {
664 /** @todo Get post_ids and delete cache */
665 // wp_cache_delete($post_id, 'post_meta');
672 * get_post_custom() - Retrieve post custom fields
674 * {@internal Missing Long Description}}
683 * @param int $post_id post ID
684 * @return array {@internal Missing Description}}
686 function get_post_custom($post_id = 0) {
690 $post_id = (int) $id;
692 $post_id = (int) $post_id;
694 if ( ! wp_cache_get($post_id, 'post_meta') )
695 update_postmeta_cache($post_id);
697 return wp_cache_get($post_id, 'post_meta');
701 * get_post_custom_keys() - Retrieve post custom field names
707 * @param int $post_id post ID
708 * @return array|null Either array of the keys, or null if keys would not be retrieved
710 function get_post_custom_keys( $post_id = 0 ) {
711 $custom = get_post_custom( $post_id );
713 if ( !is_array($custom) )
716 if ( $keys = array_keys($custom) )
721 function get_post_custom_values( $key = '', $post_id = 0 ) {
722 $custom = get_post_custom($post_id);
724 return $custom[$key];
727 function sanitize_post($post, $context = 'display') {
728 if ( 'raw' == $context )
730 if ( is_object($post) ) {
731 foreach ( array_keys(get_object_vars($post)) as $field )
732 $post->$field = sanitize_post_field($field, $post->$field, $post->ID, $context);
734 foreach ( array_keys($post) as $field )
735 $post[$field] = sanitize_post_field($field, $post[$field], $post['ID'], $context);
741 * sanitize_post_field() - Sanitize post field based on context
743 * {@internal Missing Long Description}}
749 * @param string $field The Post Object field name
750 * @param string $value The Post Object value
751 * @param int $postid Post ID
752 * @param string $context How to sanitize post fields
753 * @return string Sanitized value
755 function sanitize_post_field($field, $value, $post_id, $context) {
756 $int_fields = array('ID', 'post_parent', 'menu_order');
757 if ( in_array($field, $int_fields) )
758 $value = (int) $value;
760 if ( 'raw' == $context )
764 if ( false !== strpos($field, 'post_') ) {
766 $field_no_prefix = str_replace('post_', '', $field);
769 if ( 'edit' == $context ) {
770 $format_to_edit = array('post_content', 'post_excerpt', 'post_title', 'post_password');
773 $value = apply_filters("edit_$field", $value, $post_id);
775 $value = apply_filters("${field_no_prefix}_edit_pre", $value, $post_id);
777 $value = apply_filters("edit_post_$field", $value, $post_id);
780 if ( in_array($field, $format_to_edit) ) {
781 if ( 'post_content' == $field )
782 $value = format_to_edit($value, user_can_richedit());
784 $value = format_to_edit($value);
786 $value = attribute_escape($value);
788 } else if ( 'db' == $context ) {
790 $value = apply_filters("pre_$field", $value);
791 $value = apply_filters("${field_no_prefix}_save_pre", $value);
793 $value = apply_filters("pre_post_$field", $value);
794 $value = apply_filters("${field}_pre", $value);
797 // Use display filters by default.
799 $value = apply_filters($field, $value, $post_id, $context);
801 $value = apply_filters("post_$field", $value, $post_id, $context);
804 if ( 'attribute' == $context )
805 $value = attribute_escape($value);
806 else if ( 'js' == $context )
807 $value = js_escape($value);
813 * wp_count_posts() - Count number of posts with a given type
815 * {@internal Missing Long Description}}
821 * @param string $type Post type
822 * @return array Number of posts for each status
824 function wp_count_posts( $type = 'post', $perm = '' ) {
827 $user = wp_get_current_user();
831 $query = "SELECT post_status, COUNT( * ) AS num_posts FROM {$wpdb->posts} WHERE post_type = %s";
832 if ( 'readable' == $perm && is_user_logged_in() ) {
833 if ( !current_user_can("read_private_{$type}s") ) {
834 $cache_key .= '_' . $perm . '_' . $user->ID;
835 $query .= " AND (post_status != 'private' OR ( post_author = '$user->ID' AND post_status = 'private' ))";
838 $query .= ' GROUP BY post_status';
840 $count = wp_cache_get($cache_key, 'counts');
841 if ( false !== $count )
844 $count = $wpdb->get_results( $wpdb->prepare( $query, $type ), ARRAY_A );
847 foreach( (array) $count as $row_num => $row ) {
848 $stats[$row['post_status']] = $row['num_posts'];
851 $stats = (object) $stats;
852 wp_cache_set($cache_key, $stats, 'counts');
859 * wp_count_attachments() - Count number of attachments
861 * {@internal Missing Long Description}}
867 * @param string|array $post_mime_type Array or comma-separated list of MIME patterns
868 * @return array Number of posts for each post_mime_type
871 function wp_count_attachments( $mime_type = '' ) {
874 $and = wp_post_mime_type_where( $mime_type );
875 $count = $wpdb->get_results( "SELECT post_mime_type, COUNT( * ) AS num_posts FROM $wpdb->posts WHERE post_type = 'attachment' $and GROUP BY post_mime_type", ARRAY_A );
878 foreach( (array) $count as $row ) {
879 $stats[$row['post_mime_type']] = $row['num_posts'];
882 return (object) $stats;
886 * wp_match_mime_type() - Check a MIME-Type against a list
888 * {@internal Missing Long Description}}
894 * @param string|array $wildcard_mime_types e.g. audio/mpeg or image (same as image/*) or flash (same as *flash*)
895 * @param string|array $real_mime_types post_mime_type values
896 * @return array array(wildcard=>array(real types))
898 function wp_match_mime_types($wildcard_mime_types, $real_mime_types) {
900 if ( is_string($wildcard_mime_types) )
901 $wildcard_mime_types = array_map('trim', explode(',', $wildcard_mime_types));
902 if ( is_string($real_mime_types) )
903 $real_mime_types = array_map('trim', explode(',', $real_mime_types));
904 $wild = '[-._a-z0-9]*';
905 foreach ( (array) $wildcard_mime_types as $type ) {
906 $type = str_replace('*', $wild, $type);
907 $patternses[1][$type] = "^$type$";
908 if ( false === strpos($type, '/') ) {
909 $patternses[2][$type] = "^$type/";
910 $patternses[3][$type] = $type;
914 foreach ( $patternses as $patterns )
915 foreach ( $patterns as $type => $pattern )
916 foreach ( (array) $real_mime_types as $real )
917 if ( preg_match("#$pattern#", $real) && ( empty($matches[$type]) || false === array_search($real, $matches[$type]) ) )
918 $matches[$type][] = $real;
923 * wp_get_post_mime_type_where() - Convert MIME types into SQL
929 * @param string|array $mime_types MIME types
930 * @return string SQL AND clause
932 function wp_post_mime_type_where($post_mime_types) {
934 $wildcards = array('', '%', '%/%');
935 if ( is_string($post_mime_types) )
936 $post_mime_types = array_map('trim', explode(',', $post_mime_types));
937 foreach ( (array) $post_mime_types as $mime_type ) {
938 $mime_type = preg_replace('/\s/', '', $mime_type);
939 $slashpos = strpos($mime_type, '/');
940 if ( false !== $slashpos ) {
941 $mime_group = preg_replace('/[^-*.a-zA-Z0-9]/', '', substr($mime_type, 0, $slashpos));
942 $mime_subgroup = preg_replace('/[^-*.a-zA-Z0-9]/', '', substr($mime_type, $slashpos + 1));
943 if ( empty($mime_subgroup) )
944 $mime_subgroup = '*';
946 $mime_subgroup = str_replace('/', '', $mime_subgroup);
947 $mime_pattern = "$mime_group/$mime_subgroup";
949 $mime_pattern = preg_replace('/[^-*.a-zA-Z0-9]/', '', $mime_type);
950 if ( false === strpos($mime_pattern, '*') )
951 $mime_pattern .= '/*';
954 $mime_pattern = preg_replace('/\*+/', '%', $mime_pattern);
956 if ( in_array( $mime_type, $wildcards ) )
959 if ( false !== strpos($mime_pattern, '%') )
960 $wheres[] = "post_mime_type LIKE '$mime_pattern'";
962 $wheres[] = "post_mime_type = '$mime_pattern'";
964 if ( !empty($wheres) )
965 $where = ' AND (' . join(' OR ', $wheres) . ') ';
970 * wp_delete_post() - Deletes a Post
972 * {@internal Missing Long Description}}
978 * @param int $postid post ID
979 * @return mixed {@internal Missing Description}}
981 function wp_delete_post($postid = 0) {
982 global $wpdb, $wp_rewrite;
984 if ( !$post = $wpdb->get_row($wpdb->prepare("SELECT * FROM $wpdb->posts WHERE ID = %d", $postid)) )
987 if ( 'attachment' == $post->post_type )
988 return wp_delete_attachment($postid);
990 do_action('delete_post', $postid);
992 /** @todo delete for pluggable post taxonomies too */
993 wp_delete_object_term_relationships($postid, array('category', 'post_tag'));
995 $parent_data = array( 'post_parent' => $post->post_parent );
996 $parent_where = array( 'post_parent' => $postid );
998 if ( 'page' == $post->post_type) {
999 // if the page is defined in option page_on_front or post_for_posts,
1000 // adjust the corresponding options
1001 if ( get_option('page_on_front') == $postid ) {
1002 update_option('show_on_front', 'posts');
1003 delete_option('page_on_front');
1005 if ( get_option('page_for_posts') == $postid ) {
1006 delete_option('page_for_posts');
1009 // Point children of this page to its parent, also clean the cache of affected children
1010 $children_query = $wpdb->prepare("SELECT * FROM $wpdb->posts WHERE post_parent = %d AND post_type='page'", $postid);
1011 $children = $wpdb->get_results($children_query);
1013 $wpdb->update( $wpdb->posts, $parent_data, $parent_where + array( 'post_type' => 'page' ) );
1016 // Point all attachments to this post up one level
1017 $wpdb->update( $wpdb->posts, $parent_data, $parent_where + array( 'post_type' => 'attachment' ) );
1019 $wpdb->query( $wpdb->prepare( "DELETE FROM $wpdb->posts WHERE ID = %d", $postid ));
1021 $wpdb->query( $wpdb->prepare( "DELETE FROM $wpdb->comments WHERE comment_post_ID = %d", $postid ));
1023 $wpdb->query( $wpdb->prepare( "DELETE FROM $wpdb->postmeta WHERE post_id = %d", $postid ));
1025 if ( 'page' == $post->post_type ) {
1026 clean_page_cache($postid);
1028 foreach ( (array) $children as $child )
1029 clean_page_cache($child->ID);
1031 $wp_rewrite->flush_rules();
1033 clean_post_cache($postid);
1036 do_action('deleted_post', $postid);
1042 * wp_get_post_categories() - Retrieve the list of categories for a post
1044 * Compatibility layer for themes and plugins. Also an easy layer of abstraction
1045 * away from the complexity of the taxonomy layer.
1047 * @package WordPress
1051 * @uses wp_get_object_terms() Retrieves the categories. Args details can be found here
1053 * @param int $post_id Optional. The Post ID
1054 * @param array $args Optional. Overwrite the defaults
1055 * @return array {@internal Missing Description}}
1057 function wp_get_post_categories( $post_id = 0, $args = array() ) {
1058 $post_id = (int) $post_id;
1060 $defaults = array('fields' => 'ids');
1061 $args = wp_parse_args( $args, $defaults );
1063 $cats = wp_get_object_terms($post_id, 'category', $args);
1068 * wp_get_post_tags() - Retrieve the post tags
1070 * @package WordPress
1074 * @uses wp_get_object_terms() Gets the tags for returning. Args can be found here
1076 * @param int $post_id Optional. The Post ID
1077 * @param array $args Optional. Overwrite the defaults
1078 * @return mixed The tags the post has currently
1080 function wp_get_post_tags( $post_id = 0, $args = array() ) {
1081 $post_id = (int) $post_id;
1083 $defaults = array('fields' => 'all');
1084 $args = wp_parse_args( $args, $defaults );
1086 $tags = wp_get_object_terms($post_id, 'post_tag', $args);
1092 * wp_get_recent_posts() - Get the $num most recent posts
1094 * {@internal Missing Long Description}}
1096 * @package WordPress
1100 * @param int $num number of posts to get
1101 * @return array {@internal Missing Description}}
1103 function wp_get_recent_posts($num = 10) {
1106 // Set the limit clause, if we got a limit
1109 $limit = "LIMIT $num";
1112 $sql = "SELECT * FROM $wpdb->posts WHERE post_type = 'post' ORDER BY post_date DESC $limit";
1113 $result = $wpdb->get_results($sql,ARRAY_A);
1115 return $result?$result:array();
1119 * wp_get_single_post() - Get one post
1121 * {@internal Missing Long Description}}
1123 * @package WordPress
1128 * @param int $postid post ID
1129 * @param string $mode How to return result, either OBJECT, ARRAY_N, or ARRAY_A
1130 * @return object|array Post object or array holding post contents and information
1132 function wp_get_single_post($postid = 0, $mode = OBJECT) {
1133 $postid = (int) $postid;
1135 $post = get_post($postid, $mode);
1137 // Set categories and tags
1138 if($mode == OBJECT) {
1139 $post->post_category = wp_get_post_categories($postid);
1140 $post->tags_input = wp_get_post_tags($postid, array('fields' => 'names'));
1143 $post['post_category'] = wp_get_post_categories($postid);
1144 $post['tags_input'] = wp_get_post_tags($postid, array('fields' => 'names'));
1151 * wp_insert_post() - Insert a post
1153 * {@internal Missing Long Description}}
1155 * @package WordPress
1162 * @uses $allowedtags
1164 * @param array $postarr post contents
1165 * @return int post ID or 0 on error
1167 function wp_insert_post($postarr = array()) {
1168 global $wpdb, $wp_rewrite, $user_ID;
1170 $defaults = array('post_status' => 'draft', 'post_type' => 'post', 'post_author' => $user_ID,
1171 'ping_status' => get_option('default_ping_status'), 'post_parent' => 0,
1172 'menu_order' => 0, 'to_ping' => '', 'pinged' => '', 'post_password' => '',
1173 'guid' => '', 'post_content_filtered' => '', 'post_excerpt' => '');
1175 $postarr = wp_parse_args($postarr, $defaults);
1176 $postarr = sanitize_post($postarr, 'db');
1178 // export array as variables
1179 extract($postarr, EXTR_SKIP);
1181 // Are we updating or creating?
1183 if ( !empty($ID) ) {
1185 $previous_status = get_post_field('post_status', $ID);
1187 $previous_status = 'new';
1190 if ( ('' == $post_content) && ('' == $post_title) && ('' == $post_excerpt) )
1193 // Make sure we set a valid category
1194 if (0 == count($post_category) || !is_array($post_category)) {
1195 $post_category = array(get_option('default_category'));
1198 if ( empty($post_author) )
1199 $post_author = $user_ID;
1201 if ( empty($post_status) )
1202 $post_status = 'draft';
1204 if ( empty($post_type) )
1205 $post_type = 'post';
1207 // Get the post ID and GUID
1209 $post_ID = (int) $ID;
1210 $guid = get_post_field( 'guid', $post_ID );
1213 // Create a valid post name. Drafts are allowed to have an empty
1215 if ( empty($post_name) ) {
1216 if ( 'draft' != $post_status )
1217 $post_name = sanitize_title($post_title);
1219 $post_name = sanitize_title($post_name);
1222 // If the post date is empty (due to having been new or a draft) and status is not 'draft', set date to now
1223 if (empty($post_date)) {
1224 if ( !in_array($post_status, array('draft', 'pending')) )
1225 $post_date = current_time('mysql');
1227 $post_date = '0000-00-00 00:00:00';
1230 if (empty($post_date_gmt)) {
1231 if ( !in_array($post_status, array('draft', 'pending')) )
1232 $post_date_gmt = get_gmt_from_date($post_date);
1234 $post_date_gmt = '0000-00-00 00:00:00';
1237 if ( $update || '0000-00-00 00:00:00' == $post_date ) {
1238 $post_modified = current_time( 'mysql' );
1239 $post_modified_gmt = current_time( 'mysql', 1 );
1241 $post_modified = $post_date;
1242 $post_modified_gmt = $post_date_gmt;
1245 if ( 'publish' == $post_status ) {
1246 $now = gmdate('Y-m-d H:i:59');
1247 if ( mysql2date('U', $post_date_gmt) > mysql2date('U', $now) )
1248 $post_status = 'future';
1251 if ( empty($comment_status) ) {
1253 $comment_status = 'closed';
1255 $comment_status = get_option('default_comment_status');
1257 if ( empty($ping_status) )
1258 $ping_status = get_option('default_ping_status');
1260 if ( isset($to_ping) )
1261 $to_ping = preg_replace('|\s+|', "\n", $to_ping);
1265 if ( ! isset($pinged) )
1268 if ( isset($post_parent) )
1269 $post_parent = (int) $post_parent;
1273 if ( isset($menu_order) )
1274 $menu_order = (int) $menu_order;
1278 if ( !isset($post_password) )
1279 $post_password = '';
1281 if ( 'draft' != $post_status ) {
1282 $post_name_check = $wpdb->get_var($wpdb->prepare("SELECT post_name FROM $wpdb->posts WHERE post_name = %s AND post_type = %s AND ID != %d AND post_parent = %d LIMIT 1", $post_name, $post_type, $post_ID, $post_parent));
1284 if ($post_name_check || in_array($post_name, $wp_rewrite->feeds) ) {
1287 $alt_post_name = substr($post_name, 0, 200-(strlen($suffix)+1)). "-$suffix";
1288 // expected_slashed ($alt_post_name, $post_name, $post_type)
1289 $post_name_check = $wpdb->get_var($wpdb->prepare("SELECT post_name FROM $wpdb->posts WHERE post_name = '$alt_post_name' AND post_type = '$post_type' AND ID != %d AND post_parent = %d LIMIT 1", $post_ID, $post_parent));
1291 } while ($post_name_check);
1292 $post_name = $alt_post_name;
1296 // expected_slashed (everything!)
1297 $data = compact( array( 'post_author', 'post_date', 'post_date_gmt', 'post_content', 'post_content_filtered', 'post_title', 'post_excerpt', 'post_status', 'post_type', 'comment_status', 'ping_status', 'post_password', 'post_name', 'to_ping', 'pinged', 'post_modified', 'post_modified_gmt', 'post_parent', 'menu_order', 'guid' ) );
1298 $data = stripslashes_deep( $data );
1299 $where = array( 'ID' => $post_ID );
1302 do_action( 'pre_post_update', $post_ID );
1303 $wpdb->update( $wpdb->posts, $data, $where );
1305 $data['post_mime_type'] = stripslashes( $post_mime_type ); // This isn't in the update
1306 $wpdb->insert( $wpdb->posts, $data );
1307 $post_ID = (int) $wpdb->insert_id;
1309 // use the newly generated $post_ID
1310 $where = array( 'ID' => $post_ID );
1313 if ( empty($post_name) && 'draft' != $post_status ) {
1314 $post_name = sanitize_title($post_title, $post_ID);
1315 $wpdb->update( $wpdb->posts, compact( 'post_name' ), $where );
1318 wp_set_post_categories( $post_ID, $post_category );
1319 wp_set_post_tags( $post_ID, $tags_input );
1321 $current_guid = get_post_field( 'guid', $post_ID );
1323 if ( 'page' == $post_type ) {
1324 clean_page_cache($post_ID);
1326 clean_post_cache($post_ID);
1330 if ( !$update && '' == $current_guid )
1331 $wpdb->update( $wpdb->posts, array( 'guid' => get_permalink( $post_ID ) ), $where );
1333 $post = get_post($post_ID);
1334 if ( !empty($page_template) )
1335 $post->page_template = $page_template;
1337 wp_transition_post_status($post_status, $previous_status, $post);
1340 do_action('edit_post', $post_ID, $post);
1342 do_action('save_post', $post_ID, $post);
1343 do_action('wp_insert_post', $post_ID, $post);
1349 * wp_update_post() - Update a post
1351 * {@internal Missing Long Description}}
1353 * @package WordPress
1358 * @param array $postarr post data
1359 * @return int {@internal Missing Description}}
1361 function wp_update_post($postarr = array()) {
1362 if ( is_object($postarr) )
1363 $postarr = get_object_vars($postarr);
1365 // First, get all of the original fields
1366 $post = wp_get_single_post($postarr['ID'], ARRAY_A);
1368 // Escape data pulled from DB.
1369 $post = add_magic_quotes($post);
1371 // Passed post category list overwrites existing category list if not empty.
1372 if ( isset($postarr['post_category']) && is_array($postarr['post_category'])
1373 && 0 != count($postarr['post_category']) )
1374 $post_cats = $postarr['post_category'];
1376 $post_cats = $post['post_category'];
1378 // Drafts shouldn't be assigned a date unless explicitly done so by the user
1379 if ( in_array($post['post_status'], array('draft', 'pending')) && empty($postarr['edit_date']) && empty($postarr['post_date']) &&
1380 ('0000-00-00 00:00:00' == $post['post_date']) )
1383 $clear_date = false;
1385 // Merge old and new fields with new fields overwriting old ones.
1386 $postarr = array_merge($post, $postarr);
1387 $postarr['post_category'] = $post_cats;
1388 if ( $clear_date ) {
1389 $postarr['post_date'] = '';
1390 $postarr['post_date_gmt'] = '';
1393 if ($postarr['post_type'] == 'attachment')
1394 return wp_insert_attachment($postarr);
1396 return wp_insert_post($postarr);
1400 * wp_publish_post() - Mark a post as "published"
1402 * {@internal Missing Long Description}}
1404 * @package WordPress
1409 * @param int $post_id Post ID
1410 * @return int|null {@internal Missing Description}}
1412 function wp_publish_post($post_id) {
1415 $post = get_post($post_id);
1420 if ( 'publish' == $post->post_status )
1423 $wpdb->update( $wpdb->posts, array( 'post_status' => 'publish' ), array( 'ID' => $post_id ) );
1425 $old_status = $post->post_status;
1426 $post->post_status = 'publish';
1427 wp_transition_post_status('publish', $old_status, $post);
1429 // Update counts for the post's terms.
1430 foreach ( get_object_taxonomies('post') as $taxonomy ) {
1431 $terms = wp_get_object_terms($post_id, $taxonomy, 'fields=tt_ids');
1432 wp_update_term_count($terms, $taxonomy);
1435 do_action('edit_post', $post_id, $post);
1436 do_action('save_post', $post_id, $post);
1437 do_action('wp_insert_post', $post_id, $post);
1441 * check_and_publish_future_post() - check to make sure post has correct status before
1442 * passing it on to be published. Invoked by cron 'publish_future_post' event
1443 * This safeguard prevents cron from publishing drafts, etc.
1445 * {@internal Missing Long Description}}
1447 * @package WordPress
1452 * @param int $post_id Post ID
1453 * @return int|null {@internal Missing Description}}
1455 function check_and_publish_future_post($post_id) {
1457 $post = get_post($post_id);
1462 if ( 'future' != $post->post_status )
1465 return wp_publish_post($post_id);
1468 function wp_add_post_tags($post_id = 0, $tags = '') {
1469 return wp_set_post_tags($post_id, $tags, true);
1472 function wp_set_post_tags( $post_id = 0, $tags = '', $append = false ) {
1473 /* $append - true = don't delete existing tags, just add on, false = replace the tags with the new tags */
1475 $post_id = (int) $post_id;
1482 $tags = (is_array($tags)) ? $tags : explode( ',', trim($tags, " \n\t\r\0\x0B,") );
1483 wp_set_object_terms($post_id, $tags, 'post_tag', $append);
1487 * wp_set_post_categories() - Set categories for a post
1489 * {@internal Missing Long Description}}
1491 * @package WordPress
1496 * @param int $post_ID post ID
1497 * @param array $post_categories
1498 * @return bool|mixed {@internal Missing Description}}
1500 function wp_set_post_categories($post_ID = 0, $post_categories = array()) {
1501 $post_ID = (int) $post_ID;
1502 // If $post_categories isn't already an array, make it one:
1503 if (!is_array($post_categories) || 0 == count($post_categories) || empty($post_categories))
1504 $post_categories = array(get_option('default_category'));
1505 else if ( 1 == count($post_categories) && '' == $post_categories[0] )
1508 $post_categories = array_map('intval', $post_categories);
1509 $post_categories = array_unique($post_categories);
1511 return wp_set_object_terms($post_ID, $post_categories, 'category');
1512 } // wp_set_post_categories()
1515 * wp_transition_post_status() - Change the post transition status
1517 * {@internal Missing Long Description}}
1519 * @package WordPress
1523 * @param string $new_status {@internal Missing Description}}
1524 * @param string $old_status {@internal Missing Description}}
1525 * @param int $post {@internal Missing Description}}
1527 function wp_transition_post_status($new_status, $old_status, $post) {
1528 if ( $new_status != $old_status ) {
1529 do_action('transition_post_status', $new_status, $old_status, $post);
1530 do_action("${old_status}_to_$new_status", $post);
1532 do_action("${new_status}_$post->post_type", $post->ID, $post);
1536 // Trackback and ping functions
1540 * add_ping() - Add a URL to those already pung
1542 * {@internal Missing Long Description}}
1544 * @package WordPress
1549 * @param int $post_id post ID
1550 * @param string $uri {@internal Missing Description}}
1551 * @return mixed {@internal Missing Description}}
1553 function add_ping($post_id, $uri) {
1555 $pung = $wpdb->get_var( $wpdb->prepare( "SELECT pinged FROM $wpdb->posts WHERE ID = %d", $post_id ));
1556 $pung = trim($pung);
1557 $pung = preg_split('/\s/', $pung);
1559 $new = implode("\n", $pung);
1560 $new = apply_filters('add_ping', $new);
1561 // expected_slashed ($new)
1562 $new = stripslashes($new);
1563 return $wpdb->update( $wpdb->posts, array( 'pinged' => $new ), array( 'ID' => $post_id ) );
1566 function get_enclosed($post_id) { // Get enclosures already enclosed for a post
1567 $custom_fields = get_post_custom( $post_id );
1569 if ( !is_array( $custom_fields ) )
1572 foreach ( $custom_fields as $key => $val ) {
1573 if ( 'enclosure' != $key || !is_array( $val ) )
1575 foreach( $val as $enc ) {
1576 $enclosure = split( "\n", $enc );
1577 $pung[] = trim( $enclosure[ 0 ] );
1580 $pung = apply_filters('get_enclosed', $pung);
1585 * get_pung() - Get URLs already pinged for a post
1587 * {@internal Missing Long Description}}
1589 * @package WordPress
1594 * @param int $post_id post ID
1595 * @return array {@internal Missing Description}}
1597 function get_pung($post_id) {
1599 $pung = $wpdb->get_var( $wpdb->prepare( "SELECT pinged FROM $wpdb->posts WHERE ID = %d", $post_id ));
1600 $pung = trim($pung);
1601 $pung = preg_split('/\s/', $pung);
1602 $pung = apply_filters('get_pung', $pung);
1607 * get_to_ping() - Get any URLs in the todo list
1609 * {@internal Missing Long Description}}
1611 * @package WordPress
1616 * @param int $post_id post ID
1617 * @return array {@internal Missing Description}}
1619 function get_to_ping($post_id) {
1621 $to_ping = $wpdb->get_var( $wpdb->prepare( "SELECT to_ping FROM $wpdb->posts WHERE ID = %d", $post_id ));
1622 $to_ping = trim($to_ping);
1623 $to_ping = preg_split('/\s/', $to_ping, -1, PREG_SPLIT_NO_EMPTY);
1624 $to_ping = apply_filters('get_to_ping', $to_ping);
1629 * trackback_url_list() - Do trackbacks for a list of urls
1631 * {@internal Missing Long Description}}
1633 * @package WordPress
1637 * @param string $tb_list comma separated list of URLs
1638 * @param int $post_id post ID
1640 function trackback_url_list($tb_list, $post_id) {
1641 if (!empty($tb_list)) {
1643 $postdata = wp_get_single_post($post_id, ARRAY_A);
1645 // import postdata as variables
1646 extract($postdata, EXTR_SKIP);
1649 $excerpt = strip_tags($post_excerpt?$post_excerpt:$post_content);
1651 if (strlen($excerpt) > 255) {
1652 $excerpt = substr($excerpt,0,252) . '...';
1655 $trackback_urls = explode(',', $tb_list);
1656 foreach($trackback_urls as $tb_url) {
1657 $tb_url = trim($tb_url);
1658 trackback($tb_url, stripslashes($post_title), $excerpt, $post_id);
1668 * get_all_page_ids() - Get a list of page IDs
1670 * {@internal Missing Long Description}}
1672 * @package WordPress
1677 * @return array {@internal Missing Description}}
1679 function get_all_page_ids() {
1682 if ( ! $page_ids = wp_cache_get('all_page_ids', 'posts') ) {
1683 $page_ids = $wpdb->get_col("SELECT ID FROM $wpdb->posts WHERE post_type = 'page'");
1684 wp_cache_add('all_page_ids', $page_ids, 'posts');
1691 * get_page() - Retrieves page data given a page ID or page object
1693 * {@internal Missing Long Description}}
1695 * @package WordPress
1699 * @param mixed &$page page object or page ID
1700 * @param string $output what to output
1701 * @param string $filter How the return value should be filtered.
1702 * @return mixed {@internal Missing Description}}
1704 function &get_page(&$page, $output = OBJECT, $filter = 'raw') {
1705 if ( empty($page) ) {
1706 if ( isset( $GLOBALS['page'] ) && isset( $GLOBALS['page']->ID ) )
1707 return get_post($GLOBALS['page'], $output, $filter);
1712 return get_post($page, $output, $filter);
1716 * get_page_by_path() - Retrieves a page given its path
1718 * {@internal Missing Long Description}}
1720 * @package WordPress
1725 * @param string $page_path page path
1726 * @param string $output output type
1727 * @return mixed {@internal Missing Description}}
1729 function get_page_by_path($page_path, $output = OBJECT) {
1731 $page_path = rawurlencode(urldecode($page_path));
1732 $page_path = str_replace('%2F', '/', $page_path);
1733 $page_path = str_replace('%20', ' ', $page_path);
1734 $page_paths = '/' . trim($page_path, '/');
1735 $leaf_path = sanitize_title(basename($page_paths));
1736 $page_paths = explode('/', $page_paths);
1737 foreach($page_paths as $pathdir)
1738 $full_path .= ($pathdir!=''?'/':'') . sanitize_title($pathdir);
1740 $pages = $wpdb->get_results( $wpdb->prepare( "SELECT ID, post_name, post_parent FROM $wpdb->posts WHERE post_name = %s AND (post_type = 'page' OR post_type = 'attachment')", $leaf_path ));
1742 if ( empty($pages) )
1745 foreach ($pages as $page) {
1746 $path = '/' . $leaf_path;
1748 while ($curpage->post_parent != 0) {
1749 $curpage = $wpdb->get_row( $wpdb->prepare( "SELECT ID, post_name, post_parent FROM $wpdb->posts WHERE ID = %d and post_type='page'", $curpage->post_parent ));
1750 $path = '/' . $curpage->post_name . $path;
1753 if ( $path == $full_path )
1754 return get_page($page->ID, $output);
1761 * get_page_by_title() - Retrieve a page given its title
1763 * {@internal Missing Long Description}}
1765 * @package WordPress
1770 * @param string $page_title page title
1771 * @param string $output output type
1772 * @return mixed {@internal Missing Description}}
1774 function get_page_by_title($page_title, $output = OBJECT) {
1776 $page = $wpdb->get_var( $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE post_title = %s AND post_type='page'", $page_title ));
1778 return get_page($page, $output);
1784 * get_page_children() - Retrieve child pages
1786 * {@internal Missing Long Description}}
1788 * @package WordPress
1792 * @param int $page_id page ID
1793 * @param array $pages list of pages
1794 * @return array {@internal Missing Description}}
1796 function &get_page_children($page_id, $pages) {
1797 $page_list = array();
1798 foreach ( $pages as $page ) {
1799 if ( $page->post_parent == $page_id ) {
1800 $page_list[] = $page;
1801 if ( $children = get_page_children($page->ID, $pages) )
1802 $page_list = array_merge($page_list, $children);
1809 * get_page_hierarchy() - {@internal Missing Short Description}}
1811 * Fetches the pages returned as a FLAT list, but arranged in order of their hierarchy,
1812 * i.e., child parents immediately follow their parents.
1814 * @package WordPress
1818 * @param array $posts posts array
1819 * @param int $parent parent page ID
1820 * @return array {@internal Missing Description}}
1822 function get_page_hierarchy($posts, $parent = 0) {
1823 $result = array ( );
1824 if ($posts) { foreach ($posts as $post) {
1825 if ($post->post_parent == $parent) {
1826 $result[$post->ID] = $post->post_name;
1827 $children = get_page_hierarchy($posts, $post->ID);
1828 $result += $children; //append $children to $result
1835 * get_page_uri() - Builds a page URI
1837 * {@internal Missing Long Description}}
1839 * @package WordPress
1843 * @param int $page_id page ID
1844 * @return string {@internal Missing Description}}
1846 function get_page_uri($page_id) {
1847 $page = get_page($page_id);
1848 $uri = urldecode($page->post_name);
1850 // A page cannot be it's own parent.
1851 if ( $page->post_parent == $page->ID )
1854 while ($page->post_parent != 0) {
1855 $page = get_page($page->post_parent);
1856 $uri = urldecode($page->post_name) . "/" . $uri;
1863 * get_pages() - Retrieve a list of pages
1865 * {@internal Missing Long Description}}
1867 * @package WordPress
1872 * @param mixed $args Optional. Array or string of options
1873 * @return array List of pages matching defaults or $args
1875 function &get_pages($args = '') {
1879 'child_of' => 0, 'sort_order' => 'ASC',
1880 'sort_column' => 'post_title', 'hierarchical' => 1,
1881 'exclude' => '', 'include' => '',
1882 'meta_key' => '', 'meta_value' => '',
1886 $r = wp_parse_args( $args, $defaults );
1887 extract( $r, EXTR_SKIP );
1889 $key = md5( serialize( $r ) );
1890 if ( $cache = wp_cache_get( 'get_pages', 'posts' ) )
1891 if ( isset( $cache[ $key ] ) )
1892 return apply_filters('get_pages', $cache[ $key ], $r );
1895 if ( !empty($include) ) {
1896 $child_of = 0; //ignore child_of, exclude, meta_key, and meta_value params if using include
1900 $hierarchical = false;
1901 $incpages = preg_split('/[\s,]+/',$include);
1902 if ( count($incpages) ) {
1903 foreach ( $incpages as $incpage ) {
1904 if (empty($inclusions))
1905 $inclusions = $wpdb->prepare(' AND ( ID = %d ', $incpage);
1907 $inclusions .= $wpdb->prepare(' OR ID = %d ', $incpage);
1911 if (!empty($inclusions))
1915 if ( !empty($exclude) ) {
1916 $expages = preg_split('/[\s,]+/',$exclude);
1917 if ( count($expages) ) {
1918 foreach ( $expages as $expage ) {
1919 if (empty($exclusions))
1920 $exclusions = $wpdb->prepare(' AND ( ID <> %d ', $expage);
1922 $exclusions .= $wpdb->prepare(' AND ID <> %d ', $expage);
1926 if (!empty($exclusions))
1930 if (!empty($authors)) {
1931 $post_authors = preg_split('/[\s,]+/',$authors);
1933 if ( count($post_authors) ) {
1934 foreach ( $post_authors as $post_author ) {
1935 //Do we have an author id or an author login?
1936 if ( 0 == intval($post_author) ) {
1937 $post_author = get_userdatabylogin($post_author);
1938 if ( empty($post_author) )
1940 if ( empty($post_author->ID) )
1942 $post_author = $post_author->ID;
1945 if ( '' == $author_query )
1946 $author_query = $wpdb->prepare(' post_author = %d ', $post_author);
1948 $author_query .= $wpdb->prepare(' OR post_author = %d ', $post_author);
1950 if ( '' != $author_query )
1951 $author_query = " AND ($author_query)";
1955 $query = "SELECT * FROM $wpdb->posts " ;
1956 $query .= ( empty( $meta_key ) ? "" : ", $wpdb->postmeta " ) ;
1957 $query .= " WHERE (post_type = 'page' AND post_status = 'publish') $exclusions $inclusions " ;
1958 // expected_slashed ($meta_key, $meta_value) -- also, it looks funky
1959 $query .= ( empty( $meta_key ) | empty($meta_value) ? "" : " AND ($wpdb->posts.ID = $wpdb->postmeta.post_id AND $wpdb->postmeta.meta_key = '$meta_key' AND $wpdb->postmeta.meta_value = '$meta_value' )" ) ;
1960 $query .= $author_query;
1961 $query .= " ORDER BY " . $sort_column . " " . $sort_order ;
1963 $pages = $wpdb->get_results($query);
1965 if ( empty($pages) )
1966 return apply_filters('get_pages', array(), $r);
1969 update_page_cache($pages);
1971 if ( $child_of || $hierarchical )
1972 $pages = & get_page_children($child_of, $pages);
1974 $cache[ $key ] = $pages;
1975 wp_cache_set( 'get_pages', $cache, 'posts' );
1977 $pages = apply_filters('get_pages', $pages, $r);
1983 // Attachment functions
1987 * is_local_attachment() - Check if the attachment URI is local one and is really an attachment.
1989 * {@internal Missing Long Description}}
1991 * @package WordPress
1995 * @param string $url URL to check
1996 * @return bool {@internal Missing Description}}
1998 function is_local_attachment($url) {
1999 if (strpos($url, get_bloginfo('url')) === false)
2001 if (strpos($url, get_bloginfo('url') . '/?attachment_id=') !== false)
2003 if ( $id = url_to_postid($url) ) {
2004 $post = & get_post($id);
2005 if ( 'attachment' == $post->post_type )
2012 * wp_insert_attachment() - Insert an attachment
2014 * {@internal Missing Long Description}}
2016 * @package WordPress
2023 * @param object $object attachment object
2024 * @param string $file filename
2025 * @param int $post_parent parent post ID
2026 * @return int {@internal Missing Description}}
2028 function wp_insert_attachment($object, $file = false, $parent = 0) {
2029 global $wpdb, $user_ID;
2031 $defaults = array('post_status' => 'draft', 'post_type' => 'post', 'post_author' => $user_ID,
2032 'ping_status' => get_option('default_ping_status'), 'post_parent' => 0,
2033 'menu_order' => 0, 'to_ping' => '', 'pinged' => '', 'post_password' => '',
2034 'guid' => '', 'post_content_filtered' => '', 'post_excerpt' => '');
2036 $object = wp_parse_args($object, $defaults);
2037 if ( !empty($parent) )
2038 $object['post_parent'] = $parent;
2040 $object = sanitize_post($object, 'db');
2042 // export array as variables
2043 extract($object, EXTR_SKIP);
2045 // Make sure we set a valid category
2046 if (0 == count($post_category) || !is_array($post_category)) {
2047 $post_category = array(get_option('default_category'));
2050 if ( empty($post_author) )
2051 $post_author = $user_ID;
2053 $post_type = 'attachment';
2054 $post_status = 'inherit';
2056 // Are we updating or creating?
2058 if ( !empty($ID) ) {
2060 $post_ID = (int) $ID;
2063 // Create a valid post name.
2064 if ( empty($post_name) )
2065 $post_name = sanitize_title($post_title);
2067 $post_name = sanitize_title($post_name);
2069 // expected_slashed ($post_name)
2070 $post_name_check = $wpdb->get_var( $wpdb->prepare( "SELECT post_name FROM $wpdb->posts WHERE post_name = '$post_name' AND post_status = 'inherit' AND ID != %d LIMIT 1", $post_ID));
2072 if ($post_name_check) {
2074 while ($post_name_check) {
2075 $alt_post_name = $post_name . "-$suffix";
2076 // expected_slashed ($alt_post_name, $post_name)
2077 $post_name_check = $wpdb->get_var( $wpdb->prepare( "SELECT post_name FROM $wpdb->posts WHERE post_name = '$alt_post_name' AND post_status = 'inherit' AND ID != %d AND post_parent = %d LIMIT 1", $post_ID, $post_parent));
2080 $post_name = $alt_post_name;
2083 if ( empty($post_date) )
2084 $post_date = current_time('mysql');
2085 if ( empty($post_date_gmt) )
2086 $post_date_gmt = current_time('mysql', 1);
2088 if ( empty($post_modified) )
2089 $post_modified = $post_date;
2090 if ( empty($post_modified_gmt) )
2091 $post_modified_gmt = $post_date_gmt;
2093 if ( empty($comment_status) ) {
2095 $comment_status = 'closed';
2097 $comment_status = get_option('default_comment_status');
2099 if ( empty($ping_status) )
2100 $ping_status = get_option('default_ping_status');
2102 if ( isset($to_ping) )
2103 $to_ping = preg_replace('|\s+|', "\n", $to_ping);
2107 if ( isset($post_parent) )
2108 $post_parent = (int) $post_parent;
2112 if ( isset($menu_order) )
2113 $menu_order = (int) $menu_order;
2117 if ( !isset($post_password) )
2118 $post_password = '';
2120 if ( ! isset($pinged) )
2123 // expected_slashed (everything!)
2124 $data = compact( array( 'post_author', 'post_date', 'post_date_gmt', 'post_content', 'post_content_filtered', 'post_title', 'post_excerpt', 'post_status', 'post_type', 'comment_status', 'ping_status', 'post_password', 'post_name', 'to_ping', 'pinged', 'post_modified', 'post_modified_gmt', 'post_parent', 'menu_order', 'post_mime_type', 'guid' ) );
2125 $data = stripslashes_deep( $data );
2128 $wpdb->update( $wpdb->posts, $data, array( 'ID' => $post_ID ) );
2130 $wpdb->insert( $wpdb->posts, $data );
2131 $post_ID = (int) $wpdb->insert_id;
2134 if ( empty($post_name) ) {
2135 $post_name = sanitize_title($post_title, $post_ID);
2136 $wpdb->update( $wpdb->posts, compact("post_name"), array( 'ID' => $post_ID ) );
2139 wp_set_post_categories($post_ID, $post_category);
2142 update_attached_file( $post_ID, $file );
2144 clean_post_cache($post_ID);
2147 do_action('edit_attachment', $post_ID);
2149 do_action('add_attachment', $post_ID);
2156 * wp_delete_attachment() - Delete an attachment
2158 * {@internal Missing Long Description}}
2160 * @package WordPress
2165 * @param int $postid attachment Id
2166 * @return mixed {@internal Missing Description}}
2168 function wp_delete_attachment($postid) {
2171 if ( !$post = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->posts WHERE ID = %d", $postid)) )
2174 if ( 'attachment' != $post->post_type )
2177 $meta = wp_get_attachment_metadata( $postid );
2178 $file = get_attached_file( $postid );
2180 /** @todo Delete for pluggable post taxonomies too */
2181 wp_delete_object_term_relationships($postid, array('category', 'post_tag'));
2183 $wpdb->query( $wpdb->prepare( "DELETE FROM $wpdb->posts WHERE ID = %d", $postid ));
2185 $wpdb->query( $wpdb->prepare( "DELETE FROM $wpdb->comments WHERE comment_post_ID = %d", $postid ));
2187 $wpdb->query( $wpdb->prepare( "DELETE FROM $wpdb->postmeta WHERE post_id = %d ", $postid ));
2189 if ( ! empty($meta['thumb']) ) {
2190 // Don't delete the thumb if another attachment uses it
2191 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'].'%', $postid)) ) {
2192 $thumbfile = str_replace(basename($file), $meta['thumb'], $file);
2193 $thumbfile = apply_filters('wp_delete_file', $thumbfile);
2194 @ unlink($thumbfile);
2198 // remove intermediate images if there are any
2199 $sizes = apply_filters('intermediate_image_sizes', array('thumbnail', 'medium'));
2200 foreach ( $sizes as $size ) {
2201 if ( $intermediate = image_get_intermediate_size($postid, $size) ) {
2202 $intermediate_file = apply_filters('wp_delete_file', $intermediate['path']);
2203 @ unlink($intermediate_file);
2207 $file = apply_filters('wp_delete_file', $file);
2209 if ( ! empty($file) )
2212 clean_post_cache($postid);
2214 do_action('delete_attachment', $postid);
2220 * wp_get_attachment_metadata() - Retrieve metadata for an attachment
2222 * {@internal Missing Long Description}}
2224 * @package WordPress
2228 * @param int $post_id attachment ID
2229 * @param bool $unfiltered Optional, default is false. If true, filters are not run
2230 * @return array {@internal Missing Description}}
2232 function wp_get_attachment_metadata( $post_id, $unfiltered = false ) {
2233 $post_id = (int) $post_id;
2234 if ( !$post =& get_post( $post_id ) )
2237 $data = get_post_meta( $post->ID, '_wp_attachment_metadata', true );
2240 return apply_filters( 'wp_get_attachment_metadata', $data, $post->ID );
2244 * wp_update_attachment_metadata() - Update metadata for an attachment
2246 * {@internal Missing Long Description}}
2248 * @package WordPress
2252 * @param int $post_id attachment ID
2253 * @param array $data attachment data
2254 * @return int {@internal Missing Description}}
2256 function wp_update_attachment_metadata( $post_id, $data ) {
2257 $post_id = (int) $post_id;
2258 if ( !$post =& get_post( $post_id ) )
2261 $old_data = wp_get_attachment_metadata( $post->ID, true );
2263 $data = apply_filters( 'wp_update_attachment_metadata', $data, $post->ID );
2266 return update_post_meta( $post->ID, '_wp_attachment_metadata', $data, $old_data );
2268 return add_post_meta( $post->ID, '_wp_attachment_metadata', $data );
2272 * wp_get_attachment_url() - Retrieve the URL for an attachment
2274 * {@internal Missing Long Description}}
2276 * @package WordPress
2280 * @param int $post_id attachment ID
2281 * @return string {@internal Missing Description}}
2283 function wp_get_attachment_url( $post_id = 0 ) {
2284 $post_id = (int) $post_id;
2285 if ( !$post =& get_post( $post_id ) )
2288 $url = get_the_guid( $post->ID );
2290 if ( 'attachment' != $post->post_type || !$url )
2293 return apply_filters( 'wp_get_attachment_url', $url, $post->ID );
2297 * wp_get_attachment_thumb_file() - Retrieve thumbnail for an attachment
2299 * {@internal Missing Long Description}}
2301 * @package WordPress
2305 * @param int $post_id attachment ID
2306 * @return mixed {@internal Missing Description}}
2308 function wp_get_attachment_thumb_file( $post_id = 0 ) {
2309 $post_id = (int) $post_id;
2310 if ( !$post =& get_post( $post_id ) )
2312 if ( !$imagedata = wp_get_attachment_metadata( $post->ID ) )
2315 $file = get_attached_file( $post->ID );
2317 if ( !empty($imagedata['thumb']) && ($thumbfile = str_replace(basename($file), $imagedata['thumb'], $file)) && file_exists($thumbfile) )
2318 return apply_filters( 'wp_get_attachment_thumb_file', $thumbfile, $post->ID );
2323 * wp_get_attachment_thumb_url() - Retrieve URL for an attachment thumbnail
2325 * {@internal Missing Long Description}}
2327 * @package WordPress
2331 * @param int $post_id attachment ID
2332 * @return string {@internal Missing Description}}
2334 function wp_get_attachment_thumb_url( $post_id = 0 ) {
2335 $post_id = (int) $post_id;
2336 if ( !$post =& get_post( $post_id ) )
2338 if ( !$url = wp_get_attachment_url( $post->ID ) )
2341 $sized = image_downsize( $post_id, 'thumbnail' );
2345 if ( !$thumb = wp_get_attachment_thumb_file( $post->ID ) )
2348 $url = str_replace(basename($url), basename($thumb), $url);
2350 return apply_filters( 'wp_get_attachment_thumb_url', $url, $post->ID );
2354 * wp_attachment_is_image() - Check if the attachment is an image
2356 * {@internal Missing Long Description}}
2358 * @package WordPress
2362 * @param int $post_id attachment ID
2363 * @return bool {@internal Missing Description}}
2365 function wp_attachment_is_image( $post_id = 0 ) {
2366 $post_id = (int) $post_id;
2367 if ( !$post =& get_post( $post_id ) )
2370 if ( !$file = get_attached_file( $post->ID ) )
2373 $ext = preg_match('/\.([^.]+)$/', $file, $matches) ? strtolower($matches[1]) : false;
2375 $image_exts = array('jpg', 'jpeg', 'gif', 'png');
2377 if ( 'image/' == substr($post->post_mime_type, 0, 6) || $ext && 'import' == $post->post_mime_type && in_array($ext, $image_exts) )
2383 * wp_mime_type_icon() - Retrieve the icon for a MIME type
2385 * {@internal Missing Long Description}}
2387 * @package WordPress
2391 * @param string $mime MIME type
2392 * @return string|bool {@internal Missing Description}}
2394 function wp_mime_type_icon( $mime = 0 ) {
2395 if ( !is_numeric($mime) )
2396 $icon = wp_cache_get("mime_type_icon_$mime");
2397 if ( empty($icon) ) {
2399 $post_mimes = array();
2400 if ( is_numeric($mime) ) {
2401 $mime = (int) $mime;
2402 if ( $post =& get_post( $mime ) ) {
2403 $post_id = (int) $post->ID;
2404 $ext = preg_replace('/^.+?\.([^.]+)$/', '$1', $post->guid);
2405 if ( !empty($ext) ) {
2406 $post_mimes[] = $ext;
2407 if ( $ext_type = wp_ext2type( $ext ) )
2408 $post_mimes[] = $ext_type;
2410 $mime = $post->post_mime_type;
2415 $post_mimes[] = $mime;
2418 $icon_files = wp_cache_get('icon_files');
2420 if ( !is_array($icon_files) ) {
2421 $icon_dir = apply_filters( 'icon_dir', ABSPATH . WPINC . '/images/crystal' );
2422 $icon_dir_uri = apply_filters( 'icon_dir_uri', trailingslashit(get_option('siteurl')) . WPINC . '/images/crystal' );
2423 $dirs = apply_filters( 'icon_dirs', array($icon_dir => $icon_dir_uri) );
2424 $icon_files = array();
2426 $dir = array_shift($keys = array_keys($dirs));
2427 $uri = array_shift($dirs);
2428 if ( $dh = opendir($dir) ) {
2429 while ( false !== $file = readdir($dh) ) {
2430 $file = basename($file);
2431 if ( substr($file, 0, 1) == '.' )
2433 if ( !in_array(strtolower(substr($file, -4)), array('.png', '.gif', '.jpg') ) ) {
2434 if ( is_dir("$dir/$file") )
2435 $dirs["$dir/$file"] = "$uri/$file";
2438 $icon_files["$dir/$file"] = "$uri/$file";
2443 wp_cache_set('icon_files', $icon_files, 600);
2446 // Icon basename - extension = MIME wildcard
2447 foreach ( $icon_files as $file => $uri )
2448 $types[ preg_replace('/^([^.]*).*$/', '$1', basename($file)) ] =& $icon_files[$file];
2450 if ( ! empty($mime) ) {
2451 $post_mimes[] = substr($mime, 0, strpos($mime, '/'));
2452 $post_mimes[] = substr($mime, strpos($mime, '/') + 1);
2453 $post_mimes[] = str_replace('/', '_', $mime);
2456 $matches = wp_match_mime_types(array_keys($types), $post_mimes);
2457 $matches['default'] = array('default');
2459 foreach ( $matches as $match => $wilds ) {
2460 if ( isset($types[$wilds[0]])) {
2461 $icon = $types[$wilds[0]];
2462 if ( !is_numeric($mime) )
2463 wp_cache_set("mime_type_icon_$mime", $icon);
2469 return apply_filters( 'wp_mime_type_icon', $icon, $mime, $post_id ); // Last arg is 0 if function pass mime type.
2473 * wp_check_for_changed_slugs() - {@internal Missing Short Description}}
2475 * {@internal Missing Long Description}}
2477 * @package WordPress
2481 * @param int $post_id The Post ID
2482 * @return int Same as $post_id
2484 function wp_check_for_changed_slugs($post_id) {
2485 if ( !isset($_POST['wp-old-slug']) || !strlen($_POST['wp-old-slug']) )
2488 $post = &get_post($post_id);
2490 // we're only concerned with published posts
2491 if ( $post->post_status != 'publish' || $post->post_type != 'post' )
2494 // only bother if the slug has changed
2495 if ( $post->post_name == $_POST['wp-old-slug'] )
2498 $old_slugs = (array) get_post_meta($post_id, '_wp_old_slug');
2500 // if we haven't added this old slug before, add it now
2501 if ( !count($old_slugs) || !in_array($_POST['wp-old-slug'], $old_slugs) )
2502 add_post_meta($post_id, '_wp_old_slug', $_POST['wp-old-slug']);
2504 // if the new slug was used previously, delete it from the list
2505 if ( in_array($post->post_name, $old_slugs) )
2506 delete_post_meta($post_id, '_wp_old_slug', $post->post_name);
2512 * get_private_posts_cap_sql() - {@internal Missing Short Description}}
2514 * This function provides a standardized way to appropriately select on
2515 * the post_status of posts/pages. The function will return a piece of
2516 * SQL code that can be added to a WHERE clause; this SQL is constructed
2517 * to allow all published posts, and all private posts to which the user
2520 * @package WordPress
2525 * @uses apply_filters() Call 'pub_priv_sql_capability' filter for plugins with different post types
2527 * @param string $post_type currently only supports 'post' or 'page'.
2528 * @return string SQL code that can be added to a where clause.
2530 function get_private_posts_cap_sql($post_type) {
2535 if ($post_type == 'post') {
2536 $cap = 'read_private_posts';
2538 } elseif ($post_type == 'page') {
2539 $cap = 'read_private_pages';
2540 // Dunno what it is, maybe plugins have their own post type?
2542 $cap = apply_filters('pub_priv_sql_capability', $cap);
2545 // We don't know what it is, filters don't change anything,
2546 // so set the SQL up to return nothing.
2551 $sql = '(post_status = \'publish\'';
2553 if (current_user_can($cap)) {
2554 // Does the user have the capability to view private posts? Guess so.
2555 $sql .= ' OR post_status = \'private\'';
2556 } elseif (is_user_logged_in()) {
2557 // Users can view their own private posts.
2558 $sql .= ' OR post_status = \'private\' AND post_author = \'' . $user_ID . '\'';
2567 * get_lastpostdate() - {@internal Missing Short Description}}
2569 * {@internal Missing Long Description}}
2571 * @package WordPress
2577 * @uses apply_filters() Calls 'get_lastpostdate' filter
2579 * @global mixed $cache_lastpostdate Stores the last post date
2580 * @global mixed $pagenow The current page being viewed
2582 * @param string $timezone The location to get the time. Can be 'gmt', 'blog', or 'server'.
2583 * @return string The date of the last post.
2585 function get_lastpostdate($timezone = 'server') {
2586 global $cache_lastpostdate, $wpdb, $blog_id;
2587 $add_seconds_server = date('Z');
2588 if ( !isset($cache_lastpostdate[$blog_id][$timezone]) ) {
2589 switch(strtolower($timezone)) {
2591 $lastpostdate = $wpdb->get_var("SELECT post_date_gmt FROM $wpdb->posts WHERE post_status = 'publish' ORDER BY post_date_gmt DESC LIMIT 1");
2594 $lastpostdate = $wpdb->get_var("SELECT post_date FROM $wpdb->posts WHERE post_status = 'publish' ORDER BY post_date_gmt DESC LIMIT 1");
2597 $lastpostdate = $wpdb->get_var("SELECT DATE_ADD(post_date_gmt, INTERVAL '$add_seconds_server' SECOND) FROM $wpdb->posts WHERE post_status = 'publish' ORDER BY post_date_gmt DESC LIMIT 1");
2600 $cache_lastpostdate[$blog_id][$timezone] = $lastpostdate;
2602 $lastpostdate = $cache_lastpostdate[$blog_id][$timezone];
2604 return apply_filters( 'get_lastpostdate', $lastpostdate, $timezone );
2608 * get_lastpostmodified() - {@internal Missing Short Description}}
2610 * {@internal Missing Long Description}}
2612 * @package WordPress
2618 * @uses apply_filters() Calls 'get_lastpostmodified' filter
2620 * @global mixed $cache_lastpostmodified Stores the date the last post was modified
2621 * @global mixed $pagenow The current page being viewed
2623 * @param string $timezone The location to get the time. Can be 'gmt', 'blog', or 'server'.
2624 * @return string The date the post was last modified.
2626 function get_lastpostmodified($timezone = 'server') {
2627 global $cache_lastpostmodified, $wpdb, $blog_id;
2628 $add_seconds_server = date('Z');
2629 if ( !isset($cache_lastpostmodified[$blog_id][$timezone]) ) {
2630 switch(strtolower($timezone)) {
2632 $lastpostmodified = $wpdb->get_var("SELECT post_modified_gmt FROM $wpdb->posts WHERE post_status = 'publish' ORDER BY post_modified_gmt DESC LIMIT 1");
2635 $lastpostmodified = $wpdb->get_var("SELECT post_modified FROM $wpdb->posts WHERE post_status = 'publish' ORDER BY post_modified_gmt DESC LIMIT 1");
2638 $lastpostmodified = $wpdb->get_var("SELECT DATE_ADD(post_modified_gmt, INTERVAL '$add_seconds_server' SECOND) FROM $wpdb->posts WHERE post_status = 'publish' ORDER BY post_modified_gmt DESC LIMIT 1");
2641 $lastpostdate = get_lastpostdate($timezone);
2642 if ( $lastpostdate > $lastpostmodified ) {
2643 $lastpostmodified = $lastpostdate;
2645 $cache_lastpostmodified[$blog_id][$timezone] = $lastpostmodified;
2647 $lastpostmodified = $cache_lastpostmodified[$blog_id][$timezone];
2649 return apply_filters( 'get_lastpostmodified', $lastpostmodified, $timezone );
2653 * update_post_cache() - Updates posts in cache
2655 * @usedby update_page_cache() update_page_cache() aliased by this function.
2657 * @package WordPress
2661 * @param array $posts Array of post objects
2663 function update_post_cache(&$posts) {
2667 foreach ( $posts as $post )
2668 wp_cache_add($post->ID, $post, 'posts');
2672 * clean_post_cache() - Will clean the post in the cache
2674 * Cleaning means delete from the cache of the post. Will call to clean
2675 * the term object cache associated with the post ID.
2677 * @package WordPress
2681 * @uses do_action() Will call the 'clean_post_cache' hook action.
2683 * @param int $id The Post ID in the cache to clean
2685 function clean_post_cache($id) {
2689 wp_cache_delete($id, 'posts');
2690 wp_cache_delete($id, 'post_meta');
2692 clean_object_term_cache($id, 'post');
2694 wp_cache_delete( 'wp_get_archives', 'general' );
2696 do_action('clean_post_cache', $id);
2698 if ( $children = $wpdb->get_col( $wpdb->prepare("SELECT ID FROM $wpdb->posts WHERE post_parent = %d", $id) ) ) {
2699 foreach( $children as $cid )
2700 clean_post_cache( $cid );
2705 * update_page_cache() - Alias of update_post_cache()
2707 * @see update_post_cache() Posts and pages are the same, alias is intentional
2709 * @package WordPress
2713 * @param array $pages list of page objects
2715 function update_page_cache(&$pages) {
2716 update_post_cache($pages);
2720 * clean_page_cache() - Will clean the page in the cache
2722 * Clean (read: delete) page from cache that matches $id. Will also clean
2723 * cache associated with 'all_page_ids' and 'get_pages'.
2725 * @package WordPress
2729 * @uses do_action() Will call the 'clean_page_cache' hook action.
2731 * @param int $id Page ID to clean
2733 function clean_page_cache($id) {
2734 clean_post_cache($id);
2736 wp_cache_delete( 'all_page_ids', 'posts' );
2737 wp_cache_delete( 'get_pages', 'posts' );
2739 do_action('clean_page_cache', $id);
2743 * update_post_caches() - Call major cache updating functions for list of Post objects.
2745 * @package WordPress
2750 * @uses update_post_cache()
2751 * @uses update_object_term_cache()
2752 * @uses update_postmeta_cache()
2754 * @param array $posts Array of Post objects
2756 function update_post_caches(&$posts) {
2757 // No point in doing all this work if we didn't match any posts.
2761 update_post_cache($posts);
2763 $post_ids = array();
2765 for ($i = 0; $i < count($posts); $i++)
2766 $post_ids[] = $posts[$i]->ID;
2768 update_object_term_cache($post_ids, 'post');
2770 update_postmeta_cache($post_ids);
2774 * update_postmeta_cache() - {@internal Missing Short Description}}
2776 * {@internal Missing Long Description}}
2778 * @package WordPress
2784 * @param array $post_ids {@internal Missing Description}}
2785 * @return bool|array Returns false if there is nothing to update or an array of metadata
2787 function update_postmeta_cache($post_ids) {
2790 if ( empty( $post_ids ) )
2793 if ( !is_array($post_ids) ) {
2794 $post_ids = preg_replace('|[^0-9,]|', '', $post_ids);
2795 $post_ids = explode(',', $post_ids);
2798 $post_ids = array_map('intval', $post_ids);
2801 foreach ( (array) $post_ids as $id ) {
2802 if ( false === wp_cache_get($id, 'post_meta') )
2806 if ( empty( $ids ) )
2809 // Get post-meta info
2810 $id_list = join(',', $ids);
2812 if ( $meta_list = $wpdb->get_results("SELECT post_id, meta_key, meta_value FROM $wpdb->postmeta WHERE post_id IN ($id_list) ORDER BY post_id, meta_key", ARRAY_A) ) {
2813 foreach ( (array) $meta_list as $metarow) {
2814 $mpid = (int) $metarow['post_id'];
2815 $mkey = $metarow['meta_key'];
2816 $mval = $metarow['meta_value'];
2818 // Force subkeys to be array type:
2819 if ( !isset($cache[$mpid]) || !is_array($cache[$mpid]) )
2820 $cache[$mpid] = array();
2821 if ( !isset($cache[$mpid][$mkey]) || !is_array($cache[$mpid][$mkey]) )
2822 $cache[$mpid][$mkey] = array();
2824 // Add a value to the current pid/key:
2825 $cache[$mpid][$mkey][] = $mval;
2829 foreach ( (array) $ids as $id ) {
2830 if ( ! isset($cache[$id]) )
2831 $cache[$id] = array();
2834 foreach ( array_keys($cache) as $post)
2835 wp_cache_set($post, $cache[$post], 'post_meta');
2845 * _transition_post_status() - Hook {@internal Missing Short Description}}
2847 * {@internal Missing Long Description}}
2849 * @package WordPress
2855 * @param string $new_status {@internal Missing Description}}
2856 * @param string $old_status {@internal Missing Description}}
2857 * @param object $post Object type containing the post information
2859 function _transition_post_status($new_status, $old_status, $post) {
2862 if ( $old_status != 'publish' && $new_status == 'publish' ) {
2863 // Reset GUID if transitioning to publish and it is empty
2864 if ( '' == get_the_guid($post->ID) )
2865 $wpdb->update( $wpdb->posts, array( 'guid' => get_permalink( $post->ID ) ), array( 'ID' => $post->ID ) );
2866 do_action('private_to_published', $post->ID); // Deprecated, use private_to_publish
2869 // Always clears the hook in case the post status bounced from future to draft.
2870 wp_clear_scheduled_hook('publish_future_post', $post->ID);
2874 * _future_post_hook() - Hook used to schedule publication for a post marked for the future.
2876 * The $post properties used and must exist are 'ID' and 'post_date_gmt'.
2878 * @package WordPress
2882 * @param int $post_id Not Used. Can be set to null.
2883 * @param object $post Object type containing the post information
2885 function _future_post_hook($deprecated = '', $post) {
2886 wp_clear_scheduled_hook( 'publish_future_post', $post->ID );
2887 wp_schedule_single_event(strtotime($post->post_date_gmt. ' GMT'), 'publish_future_post', array($post->ID));
2891 * _publish_post_hook() - Hook {@internal Missing Short Description}}
2893 * {@internal Missing Long Description}}
2895 * @package WordPress
2900 * @uses XMLRPC_REQUEST
2902 * @uses do_action Calls 'xmlprc_publish_post' action if XMLRPC_REQUEST is defined. Calls 'app_publish_post'
2903 * action if APP_REQUEST is defined.
2905 * @param int $post_id The ID in the database table of the post being published
2907 function _publish_post_hook($post_id) {
2910 if ( defined('XMLRPC_REQUEST') )
2911 do_action('xmlrpc_publish_post', $post_id);
2912 if ( defined('APP_REQUEST') )
2913 do_action('app_publish_post', $post_id);
2915 if ( defined('WP_IMPORTING') )
2918 $data = array( 'post_id' => $post_id, 'meta_value' => '1' );
2919 if ( get_option('default_pingback_flag') )
2920 $wpdb->insert( $wpdb->postmeta, $data + array( 'meta_key' => '_pingme' ) );
2921 $wpdb->insert( $wpdb->postmeta, $data + array( 'meta_key' => '_encloseme' ) );
2922 wp_schedule_single_event(time(), 'do_pings');
2926 * _save_post_hook() - Hook used to prevent page/post cache and rewrite rules from staying dirty
2928 * Does two things. If the post is a page and has a template then it will update/add that
2929 * template to the meta. For both pages and posts, it will clean the post cache to make sure
2930 * that the cache updates to the changes done recently. For pages, the rewrite rules of
2931 * WordPress are flushed to allow for any changes.
2933 * The $post parameter, only uses 'post_type' property and 'page_template' property.
2935 * @package WordPress
2939 * @uses $wp_rewrite Flushes Rewrite Rules.
2941 * @param int $post_id The ID in the database table for the $post
2942 * @param object $post Object type containing the post information
2944 function _save_post_hook($post_id, $post) {
2945 if ( $post->post_type == 'page' ) {
2946 if ( !empty($post->page_template) )
2947 if ( ! update_post_meta($post_id, '_wp_page_template', $post->page_template))
2948 add_post_meta($post_id, '_wp_page_template', $post->page_template, true);
2950 clean_page_cache($post_id);
2952 $wp_rewrite->flush_rules();
2954 clean_post_cache($post_id);
2962 function _get_post_ancestors(&$_post) {
2965 if ( isset($_post->ancestors) )
2968 $_post->ancestors = array();
2970 if ( empty($_post->post_parent) || $_post->ID == $_post->post_parent )
2973 $id = $_post->ancestors[] = $_post->post_parent;
2974 while ( $ancestor = $wpdb->get_var( $wpdb->prepare("SELECT `post_parent` FROM $wpdb->posts WHERE ID = %d LIMIT 1", $id) ) ) {
2975 if ( $id == $ancestor )
2977 $id = $_post->ancestors[] = $ancestor;