PageRenderTime 53ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 1ms

/wp-includes/post.php

https://github.com/localshred/dtraders
PHP | 3445 lines | 1618 code | 461 blank | 1366 comment | 465 complexity | de5cedc51a7936a8f6f0db6b11c88bf8 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

  1. <?php
  2. /**
  3. * Post functions and post utility function.
  4. *
  5. * Warning: The inline documentation for the functions contained
  6. * in this file might be inaccurate, so the documentation is not
  7. * authoritative at the moment.
  8. *
  9. * @package WordPress
  10. * @subpackage Post
  11. * @since 1.5
  12. */
  13. /**
  14. * Retrieve attached file path based on attachment ID.
  15. *
  16. * You can optionally send it through the 'get_attached_file' filter, but by
  17. * default it will just return the file path unfiltered.
  18. *
  19. * The function works by getting the single post meta name, named
  20. * '_wp_attached_file' and returning it. This is a convenience function to
  21. * prevent looking up the meta name and provide a mechanism for sending the
  22. * attached filename through a filter.
  23. *
  24. * @package WordPress
  25. * @subpackage Post
  26. * @since 2.0
  27. * @uses apply_filters() Calls 'get_attached_file' on file path and attachment ID
  28. *
  29. * @param int $attachment_id Attachment ID
  30. * @param bool $unfiltered Whether to apply filters or not
  31. * @return string The file path to the attached file.
  32. */
  33. function get_attached_file( $attachment_id, $unfiltered = false ) {
  34. $file = get_post_meta( $attachment_id, '_wp_attached_file', true );
  35. if ( $unfiltered )
  36. return $file;
  37. return apply_filters( 'get_attached_file', $file, $attachment_id );
  38. }
  39. /**
  40. * Update attachment file path based on attachment ID.
  41. *
  42. * Used to update the file path of the attachment, which uses post meta name
  43. * '_wp_attached_file' to store the path of the attachment.
  44. *
  45. * @package WordPress
  46. * @subpackage Post
  47. * @since 2.1
  48. * @uses apply_filters() Calls 'update_attached_file' on file path and attachment ID
  49. *
  50. * @param int $attachment_id Attachment ID
  51. * @param string $file File path for the attachment
  52. * @return bool False on failure, true on success.
  53. */
  54. function update_attached_file( $attachment_id, $file ) {
  55. if ( !get_post( $attachment_id ) )
  56. return false;
  57. $file = apply_filters( 'update_attached_file', $file, $attachment_id );
  58. return update_post_meta( $attachment_id, '_wp_attached_file', $file );
  59. }
  60. /**
  61. * Retrieve all children of the post parent ID.
  62. *
  63. * Normally, without any enhancements, the children would apply to pages. In the
  64. * context of the inner workings of WordPress, pages, posts, and attachments
  65. * share the same table, so therefore the functionality could apply to any one
  66. * of them. It is then noted that while this function does not work on posts, it
  67. * does not mean that it won't work on posts. It is recommended that you know
  68. * what context you wish to retrieve the children of.
  69. *
  70. * Attachments may also be made the child of a post, so if that is an accurate
  71. * statement (which needs to be verified), it would then be possible to get
  72. * all of the attachments for a post. Attachments have since changed since
  73. * version 2.5, so this is most likely unaccurate, but serves generally as an
  74. * example of what is possible.
  75. *
  76. * The arguments listed as defaults are for this function and also of the
  77. * get_posts() function. The arguments are combined with the get_children
  78. * defaults and are then passed to the get_posts() function, which accepts
  79. * additional arguments. You can replace the defaults in this function, listed
  80. * below and the additional arguments listed in the get_posts() function.
  81. *
  82. * The 'post_parent' is the most important argument and important attention
  83. * needs to be paid to the $args parameter. If you pass either an object or an
  84. * integer (number), then just the 'post_parent' is grabbed and everything else
  85. * is lost. If you don't specify any arguments, then it is assumed that you are
  86. * in The Loop and the post parent will be grabbed for from the current post.
  87. *
  88. * The 'post_parent' argument is the ID to get the children. The 'numberposts'
  89. * is the amount of posts to retrieve that has a default of '-1', which is
  90. * used to get all of the posts. Giving a number higher than 0 will only
  91. * retrieve that amount of posts.
  92. *
  93. * The 'post_type' and 'post_status' arguments can be used to choose what
  94. * criteria of posts to retrieve. The 'post_type' can be anything, but WordPress
  95. * post types are 'post', 'pages', and 'attachments'. The 'post_status'
  96. * argument will accept any post status within the write administration panels.
  97. *
  98. * @see get_posts() Has additional arguments that can be replaced.
  99. * @internal Claims made in the long description might be inaccurate.
  100. *
  101. * @package WordPress
  102. * @subpackage Post
  103. * @since 2.0
  104. *
  105. * @param mixed $args Optional. User defined arguments for replacing the defaults.
  106. * @param string $output Optional. Constant for return type, either OBJECT (default), ARRAY_A, ARRAY_N.
  107. * @return array|bool False on failure and the type will be determined by $output parameter.
  108. */
  109. function &get_children($args = '', $output = OBJECT) {
  110. if ( empty( $args ) ) {
  111. if ( isset( $GLOBALS['post'] ) ) {
  112. $args = array('post_parent' => (int) $GLOBALS['post']->post_parent );
  113. } else {
  114. return false;
  115. }
  116. } elseif ( is_object( $args ) ) {
  117. $args = array('post_parent' => (int) $args->post_parent );
  118. } elseif ( is_numeric( $args ) ) {
  119. $args = array('post_parent' => (int) $args);
  120. }
  121. $defaults = array(
  122. 'numberposts' => -1, 'post_type' => '',
  123. 'post_status' => '', 'post_parent' => 0
  124. );
  125. $r = wp_parse_args( $args, $defaults );
  126. $children = get_posts( $r );
  127. if ( !$children )
  128. return false;
  129. update_post_cache($children);
  130. foreach ( $children as $key => $child )
  131. $kids[$child->ID] =& $children[$key];
  132. if ( $output == OBJECT ) {
  133. return $kids;
  134. } elseif ( $output == ARRAY_A ) {
  135. foreach ( $kids as $kid )
  136. $weeuns[$kid->ID] = get_object_vars($kids[$kid->ID]);
  137. return $weeuns;
  138. } elseif ( $output == ARRAY_N ) {
  139. foreach ( $kids as $kid )
  140. $babes[$kid->ID] = array_values(get_object_vars($kids[$kid->ID]));
  141. return $babes;
  142. } else {
  143. return $kids;
  144. }
  145. }
  146. /**
  147. * get_extended() - Get extended entry info (<!--more-->)
  148. *
  149. * {@internal Missing Long Description}}
  150. *
  151. * @package WordPress
  152. * @subpackage Post
  153. * @since 1.0.0
  154. *
  155. * @param string $post {@internal Missing Description}}
  156. * @return array {@internal Missing Description}}
  157. */
  158. function get_extended($post) {
  159. //Match the new style more links
  160. if ( preg_match('/<!--more(.*?)?-->/', $post, $matches) ) {
  161. list($main, $extended) = explode($matches[0], $post, 2);
  162. } else {
  163. $main = $post;
  164. $extended = '';
  165. }
  166. // Strip leading and trailing whitespace
  167. $main = preg_replace('/^[\s]*(.*)[\s]*$/', '\\1', $main);
  168. $extended = preg_replace('/^[\s]*(.*)[\s]*$/', '\\1', $extended);
  169. return array('main' => $main, 'extended' => $extended);
  170. }
  171. /**
  172. * get_post() - Retrieves post data given a post ID or post object.
  173. *
  174. * {@internal Missing Long Description}}
  175. *
  176. * @package WordPress
  177. * @subpackage Post
  178. * @since 1.5.1
  179. * @uses $wpdb
  180. * @link http://codex.wordpress.org/Function_Reference/get_post
  181. *
  182. * @param int|object &$post post ID or post object
  183. * @param string $output {@internal Missing Description}}
  184. * @param string $filter {@internal Missing Description}}
  185. * @return mixed {@internal Missing Description}}
  186. */
  187. function &get_post(&$post, $output = OBJECT, $filter = 'raw') {
  188. global $wpdb;
  189. $null = null;
  190. if ( empty($post) ) {
  191. if ( isset($GLOBALS['post']) )
  192. $_post = & $GLOBALS['post'];
  193. else
  194. return $null;
  195. } elseif ( is_object($post) ) {
  196. _get_post_ancestors($post);
  197. wp_cache_add($post->ID, $post, 'posts');
  198. $_post = &$post;
  199. } else {
  200. $post = (int) $post;
  201. if ( ! $_post = wp_cache_get($post, 'posts') ) {
  202. $_post = & $wpdb->get_row($wpdb->prepare("SELECT * FROM $wpdb->posts WHERE ID = %d LIMIT 1", $post));
  203. if ( ! $_post )
  204. return $null;
  205. _get_post_ancestors($_post);
  206. wp_cache_add($_post->ID, $_post, 'posts');
  207. }
  208. }
  209. $_post = sanitize_post($_post, $filter);
  210. if ( $output == OBJECT ) {
  211. return $_post;
  212. } elseif ( $output == ARRAY_A ) {
  213. $__post = get_object_vars($_post);
  214. return $__post;
  215. } elseif ( $output == ARRAY_N ) {
  216. $__post = array_values(get_object_vars($_post));
  217. return $__post;
  218. } else {
  219. return $_post;
  220. }
  221. }
  222. /**
  223. * Retrieve ancestors of a post.
  224. *
  225. * @package WordPress
  226. * @subpackage Post
  227. * @since 2.5
  228. *
  229. * @param int|object $post Post ID or post object
  230. * @return array Ancestor IDs or empty array if none are found.
  231. */
  232. function get_post_ancestors($post) {
  233. $post = get_post($post);
  234. if ( !empty($post->ancestors) )
  235. return $post->ancestors;
  236. return array();
  237. }
  238. /**
  239. * Retrieve data from a post field based on Post ID.
  240. *
  241. * Examples of the post field will be, 'post_type', 'post_status', 'content',
  242. * etc and based off of the post object property or key names.
  243. *
  244. * The context values are based off of the taxonomy filter functions and
  245. * supported values are found within those functions.
  246. *
  247. * @package WordPress
  248. * @subpackage Post
  249. * @since 2.3
  250. * @uses sanitize_post_field() See for possible $context values.
  251. *
  252. * @param string $field Post field name
  253. * @param id $post Post ID
  254. * @param string $context Optional. How to filter the field. Default is display.
  255. * @return WP_Error|string Value in post field or WP_Error on failure
  256. */
  257. function get_post_field( $field, $post, $context = 'display' ) {
  258. $post = (int) $post;
  259. $post = get_post( $post );
  260. if ( is_wp_error($post) )
  261. return $post;
  262. if ( !is_object($post) )
  263. return '';
  264. if ( !isset($post->$field) )
  265. return '';
  266. return sanitize_post_field($field, $post->$field, $post->ID, $context);
  267. }
  268. /**
  269. * Retrieve the mime type of an attachment based on the ID.
  270. *
  271. * This function can be used with any post type, but it makes more sense with
  272. * attachments.
  273. *
  274. * @package WordPress
  275. * @subpackage Post
  276. * @since 2.0
  277. *
  278. * @param int $ID Optional. Post ID.
  279. * @return bool|string False on failure or returns the mime type
  280. */
  281. function get_post_mime_type($ID = '') {
  282. $post = & get_post($ID);
  283. if ( is_object($post) )
  284. return $post->post_mime_type;
  285. return false;
  286. }
  287. /**
  288. * Retrieve the post status based on the Post ID.
  289. *
  290. * If the post ID is of an attachment, then the parent post status will be given
  291. * instead.
  292. *
  293. * @package WordPress
  294. * @subpackage Post
  295. * @since 2.0
  296. *
  297. * @param int $ID Post ID
  298. * @return string|bool Post status or false on failure.
  299. */
  300. function get_post_status($ID = '') {
  301. $post = get_post($ID);
  302. if ( is_object($post) ) {
  303. if ( ('attachment' == $post->post_type) && $post->post_parent && ($post->ID != $post->post_parent) )
  304. return get_post_status($post->post_parent);
  305. else
  306. return $post->post_status;
  307. }
  308. return false;
  309. }
  310. /**
  311. * Retrieve all of the WordPress supported post statuses.
  312. *
  313. * Posts have a limited set of valid status values, this provides the
  314. * post_status values and descriptions.
  315. *
  316. * @package WordPress
  317. * @subpackage Post
  318. * @since 2.5
  319. *
  320. * @return array List of post statuses.
  321. */
  322. function get_post_statuses( ) {
  323. $status = array(
  324. 'draft' => __('Draft'),
  325. 'pending' => __('Pending Review'),
  326. 'private' => __('Private'),
  327. 'publish' => __('Published')
  328. );
  329. return $status;
  330. }
  331. /**
  332. * Retrieve all of the WordPress support page statuses.
  333. *
  334. * Pages have a limited set of valid status values, this provides the
  335. * post_status values and descriptions.
  336. *
  337. * @package WordPress
  338. * @subpackage Page
  339. * @since 2.5
  340. *
  341. * @return array List of page statuses.
  342. */
  343. function get_page_statuses( ) {
  344. $status = array(
  345. 'draft' => __('Draft'),
  346. 'private' => __('Private'),
  347. 'publish' => __('Published')
  348. );
  349. return $status;
  350. }
  351. /**
  352. * get_post_type() - Returns post type
  353. *
  354. * {@internal Missing Long Description}}
  355. *
  356. * @package WordPress
  357. * @subpackage Post
  358. * @since 2.1
  359. *
  360. * @uses $wpdb
  361. * @uses $posts {@internal Missing Description}}
  362. *
  363. * @param mixed $post post object or post ID
  364. * @return mixed post type or false
  365. */
  366. function get_post_type($post = false) {
  367. global $posts;
  368. if ( false === $post )
  369. $post = $posts[0];
  370. elseif ( (int) $post )
  371. $post = get_post($post, OBJECT);
  372. if ( is_object($post) )
  373. return $post->post_type;
  374. return false;
  375. }
  376. /**
  377. * set_post_type() - Set post type
  378. *
  379. * {@internal Missing Long Description}}
  380. *
  381. * @package WordPress
  382. * @subpackage Post
  383. * @since 2.5
  384. *
  385. * @uses $wpdb
  386. * @uses $posts {@internal Missing Description}}
  387. *
  388. * @param mixed $post_id post ID
  389. * @param mixed post type
  390. * @return bool {@internal Missing Description}}
  391. */
  392. function set_post_type( $post_id = 0, $post_type = 'post' ) {
  393. global $wpdb;
  394. $post_type = sanitize_post_field('post_type', $post_type, $post_id, 'db');
  395. $return = $wpdb->query( $wpdb->prepare("UPDATE $wpdb->posts SET post_type = %s WHERE ID = %d", $post_type, $post_id) );
  396. if ( 'page' == $post_type )
  397. clean_page_cache($post_id);
  398. else
  399. clean_post_cache($post_id);
  400. return $return;
  401. }
  402. /**
  403. * get_posts() - Returns a number of posts
  404. *
  405. * {@internal Missing Long Description}}
  406. *
  407. * @package WordPress
  408. * @subpackage Post
  409. * @since 1.2
  410. * @uses $wpdb
  411. * @link http://codex.wordpress.org/Template_Tags/get_posts
  412. *
  413. * @param array $args {@internal Missing Description}}
  414. * @return array {@internal Missing Description}}
  415. */
  416. function get_posts($args = null) {
  417. $defaults = array(
  418. 'numberposts' => 5, 'offset' => 0,
  419. 'category' => 0, 'orderby' => 'post_date',
  420. 'order' => 'DESC', 'include' => '',
  421. 'exclude' => '', 'meta_key' => '',
  422. 'meta_value' =>'', 'post_type' => 'post',
  423. 'post_parent' => 0
  424. );
  425. $r = wp_parse_args( $args, $defaults );
  426. if ( empty( $r['post_status'] ) )
  427. $r['post_status'] = ( 'attachment' == $r['post_type'] ) ? 'inherit' : 'publish';
  428. if ( ! empty($r['numberposts']) )
  429. $r['posts_per_page'] = $r['numberposts'];
  430. if ( ! empty($r['category']) )
  431. $r['cat'] = $r['category'];
  432. if ( ! empty($r['include']) ) {
  433. $incposts = preg_split('/[\s,]+/',$r['include']);
  434. $r['posts_per_page'] = count($incposts); // only the number of posts included
  435. $r['post__in'] = $incposts;
  436. } elseif ( ! empty($r['exclude']) )
  437. $r['post__not_in'] = preg_split('/[\s,]+/',$r['exclude']);
  438. $get_posts = new WP_Query;
  439. return $get_posts->query($r);
  440. }
  441. //
  442. // Post meta functions
  443. //
  444. /**
  445. * add_post_meta() - adds metadata for post
  446. *
  447. * {@internal Missing Long Description}}
  448. *
  449. * @package WordPress
  450. * @subpackage Post
  451. * @since 1.5
  452. * @uses $wpdb
  453. * @link http://codex.wordpress.org/Function_Reference/add_post_meta
  454. *
  455. * @param int $post_id post ID
  456. * @param string $key {@internal Missing Description}}
  457. * @param mixed $value {@internal Missing Description}}
  458. * @param bool $unique whether to check for a value with the same key
  459. * @return bool {@internal Missing Description}}
  460. */
  461. function add_post_meta($post_id, $meta_key, $meta_value, $unique = false) {
  462. global $wpdb;
  463. // make sure meta is added to the post, not a revision
  464. if ( $the_post = wp_is_post_revision($post_id) )
  465. $post_id = $the_post;
  466. // expected_slashed ($meta_key)
  467. $meta_key = stripslashes($meta_key);
  468. 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 ) ) )
  469. return false;
  470. $meta_value = maybe_serialize($meta_value);
  471. $wpdb->insert( $wpdb->postmeta, compact( 'post_id', 'meta_key', 'meta_value' ) );
  472. wp_cache_delete($post_id, 'post_meta');
  473. return true;
  474. }
  475. /**
  476. * delete_post_meta() - delete post metadata
  477. *
  478. * {@internal Missing Long Description}}
  479. *
  480. * @package WordPress
  481. * @subpackage Post
  482. * @since 1.5
  483. * @uses $wpdb
  484. * @link http://codex.wordpress.org/Function_Reference/delete_post_meta
  485. *
  486. * @param int $post_id post ID
  487. * @param string $key {@internal Missing Description}}
  488. * @param mixed $value {@internal Missing Description}}
  489. * @return bool {@internal Missing Description}}
  490. */
  491. function delete_post_meta($post_id, $key, $value = '') {
  492. global $wpdb;
  493. $post_id = absint( $post_id );
  494. // expected_slashed ($key, $value)
  495. $key = stripslashes( $key );
  496. $value = stripslashes( $value );
  497. if ( empty( $value ) )
  498. $meta_id = $wpdb->get_var( $wpdb->prepare( "SELECT meta_id FROM $wpdb->postmeta WHERE post_id = %d AND meta_key = %s", $post_id, $key ) );
  499. else
  500. $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 ) );
  501. if ( !$meta_id )
  502. return false;
  503. if ( empty( $value ) )
  504. $wpdb->query( $wpdb->prepare( "DELETE FROM $wpdb->postmeta WHERE post_id = %d AND meta_key = %s", $post_id, $key ) );
  505. else
  506. $wpdb->query( $wpdb->prepare( "DELETE FROM $wpdb->postmeta WHERE post_id = %d AND meta_key = %s AND meta_value = %s", $post_id, $key, $value ) );
  507. wp_cache_delete($post_id, 'post_meta');
  508. return true;
  509. }
  510. /**
  511. * get_post_meta() - Get a post meta field
  512. *
  513. * {@internal Missing Long Description}}
  514. *
  515. * @package WordPress
  516. * @subpackage Post
  517. * @since 1.5
  518. * @uses $wpdb
  519. * @link http://codex.wordpress.org/Function_Reference/get_post_meta
  520. *
  521. * @param int $post_id post ID
  522. * @param string $key The meta key to retrieve
  523. * @param bool $single Whether to return a single value
  524. * @return mixed {@internal Missing Description}}
  525. */
  526. function get_post_meta($post_id, $key, $single = false) {
  527. $post_id = (int) $post_id;
  528. $meta_cache = wp_cache_get($post_id, 'post_meta');
  529. if ( isset($meta_cache[$key]) ) {
  530. if ( $single ) {
  531. return maybe_unserialize( $meta_cache[$key][0] );
  532. } else {
  533. return maybe_unserialize( $meta_cache[$key] );
  534. }
  535. }
  536. if ( !$meta_cache ) {
  537. update_postmeta_cache($post_id);
  538. $meta_cache = wp_cache_get($post_id, 'post_meta');
  539. }
  540. if ( $single ) {
  541. if ( isset($meta_cache[$key][0]) )
  542. return maybe_unserialize($meta_cache[$key][0]);
  543. else
  544. return '';
  545. } else {
  546. return maybe_unserialize($meta_cache[$key]);
  547. }
  548. }
  549. /**
  550. * update_post_meta() - Update a post meta field
  551. *
  552. * {@internal Missing Long Description}}
  553. *
  554. * @package WordPress
  555. * @subpackage Post
  556. * @since 1.5
  557. * @uses $wpdb
  558. * @link http://codex.wordpress.org/Function_Reference/update_post_meta
  559. *
  560. * @param int $post_id post ID
  561. * @param string $key {@internal Missing Description}}
  562. * @param mixed $value {@internal Missing Description}}
  563. * @param mixed $prev_value previous value (for differentiating between meta fields with the same key and post ID)
  564. * @return bool {@internal Missing Description}}
  565. */
  566. function update_post_meta($post_id, $meta_key, $meta_value, $prev_value = '') {
  567. global $wpdb;
  568. // expected_slashed ($meta_key)
  569. $meta_key = stripslashes($meta_key);
  570. if ( ! $wpdb->get_var( $wpdb->prepare( "SELECT meta_key FROM $wpdb->postmeta WHERE meta_key = %s AND post_id = %d", $meta_key, $post_id ) ) ) {
  571. return add_post_meta($post_id, $meta_key, $meta_value);
  572. }
  573. $meta_value = maybe_serialize($meta_value);
  574. $data = compact( 'meta_value' );
  575. $where = compact( 'meta_key', 'post_id' );
  576. if ( !empty( $prev_value ) ) {
  577. $prev_value = maybe_serialize($prev_value);
  578. $where['meta_value'] = $prev_value;
  579. }
  580. $wpdb->update( $wpdb->postmeta, $data, $where );
  581. wp_cache_delete($post_id, 'post_meta');
  582. return true;
  583. }
  584. /**
  585. * delete_post_meta_by_key() - Delete everything from post meta matching $post_meta_key
  586. *
  587. * @package WordPress
  588. * @subpackage Post
  589. * @since 2.3
  590. * @uses $wpdb
  591. *
  592. * @param string $post_meta_key What to search for when deleting
  593. * @return bool Whether the post meta key was deleted from the database
  594. */
  595. function delete_post_meta_by_key($post_meta_key) {
  596. global $wpdb;
  597. if ( $wpdb->query($wpdb->prepare("DELETE FROM $wpdb->postmeta WHERE meta_key = %s", $post_meta_key)) ) {
  598. /** @todo Get post_ids and delete cache */
  599. // wp_cache_delete($post_id, 'post_meta');
  600. return true;
  601. }
  602. return false;
  603. }
  604. /**
  605. * get_post_custom() - Retrieve post custom fields
  606. *
  607. * {@internal Missing Long Description}}
  608. *
  609. * @package WordPress
  610. * @subpackage Post
  611. * @since 1.2
  612. * @link http://codex.wordpress.org/Function_Reference/get_post_custom
  613. *
  614. * @uses $id
  615. * @uses $wpdb
  616. *
  617. * @param int $post_id post ID
  618. * @return array {@internal Missing Description}}
  619. */
  620. function get_post_custom($post_id = 0) {
  621. global $id;
  622. if ( !$post_id )
  623. $post_id = (int) $id;
  624. $post_id = (int) $post_id;
  625. if ( ! wp_cache_get($post_id, 'post_meta') )
  626. update_postmeta_cache($post_id);
  627. return wp_cache_get($post_id, 'post_meta');
  628. }
  629. /**
  630. * get_post_custom_keys() - Retrieve post custom field names
  631. *
  632. * @package WordPress
  633. * @subpackage Post
  634. * @since 1.2
  635. * @link http://codex.wordpress.org/Function_Reference/get_post_custom_keys
  636. *
  637. * @param int $post_id post ID
  638. * @return array|null Either array of the keys, or null if keys would not be retrieved
  639. */
  640. function get_post_custom_keys( $post_id = 0 ) {
  641. $custom = get_post_custom( $post_id );
  642. if ( !is_array($custom) )
  643. return;
  644. if ( $keys = array_keys($custom) )
  645. return $keys;
  646. }
  647. /**
  648. * get_post_custom_values() - Retrieve values for a custom post field
  649. *
  650. * @package WordPress
  651. * @subpackage Post
  652. * @since 1.2
  653. * @link http://codex.wordpress.org/Function_Reference/get_post_custom_values
  654. *
  655. * @param string $key field name
  656. * @param int $post_id post ID
  657. * @return mixed {@internal Missing Description}}
  658. */
  659. function get_post_custom_values( $key = '', $post_id = 0 ) {
  660. $custom = get_post_custom($post_id);
  661. return $custom[$key];
  662. }
  663. /**
  664. * sanitize_post() - Sanitize every post field
  665. *
  666. * {@internal Missing Long Description}}
  667. *
  668. * @package WordPress
  669. * @subpackage Post
  670. * @since 2.3
  671. *
  672. * @param object|array $post The Post Object or Array
  673. * @param string $context How to sanitize post fields
  674. * @return object|array The now sanitized Post Object or Array (will be the same type as $post)
  675. */
  676. function sanitize_post($post, $context = 'display') {
  677. if ( 'raw' == $context )
  678. return $post;
  679. if ( is_object($post) ) {
  680. foreach ( array_keys(get_object_vars($post)) as $field )
  681. $post->$field = sanitize_post_field($field, $post->$field, $post->ID, $context);
  682. } else {
  683. foreach ( array_keys($post) as $field )
  684. $post[$field] = sanitize_post_field($field, $post[$field], $post['ID'], $context);
  685. }
  686. return $post;
  687. }
  688. /**
  689. * sanitize_post_field() - Sanitize post field based on context
  690. *
  691. * {@internal Missing Long Description}}
  692. *
  693. * @package WordPress
  694. * @subpackage Post
  695. * @since 2.3
  696. *
  697. * @param string $field The Post Object field name
  698. * @param string $value The Post Object value
  699. * @param int $postid Post ID
  700. * @param string $context How to sanitize post fields
  701. * @return string Sanitized value
  702. */
  703. function sanitize_post_field($field, $value, $post_id, $context) {
  704. $int_fields = array('ID', 'post_parent', 'menu_order');
  705. if ( in_array($field, $int_fields) )
  706. $value = (int) $value;
  707. if ( 'raw' == $context )
  708. return $value;
  709. $prefixed = false;
  710. if ( false !== strpos($field, 'post_') ) {
  711. $prefixed = true;
  712. $field_no_prefix = str_replace('post_', '', $field);
  713. }
  714. if ( 'edit' == $context ) {
  715. $format_to_edit = array('post_content', 'post_excerpt', 'post_title', 'post_password');
  716. if ( $prefixed ) {
  717. $value = apply_filters("edit_$field", $value, $post_id);
  718. // Old school
  719. $value = apply_filters("${field_no_prefix}_edit_pre", $value, $post_id);
  720. } else {
  721. $value = apply_filters("edit_post_$field", $value, $post_id);
  722. }
  723. if ( in_array($field, $format_to_edit) ) {
  724. if ( 'post_content' == $field )
  725. $value = format_to_edit($value, user_can_richedit());
  726. else
  727. $value = format_to_edit($value);
  728. } else {
  729. $value = attribute_escape($value);
  730. }
  731. } else if ( 'db' == $context ) {
  732. if ( $prefixed ) {
  733. $value = apply_filters("pre_$field", $value);
  734. $value = apply_filters("${field_no_prefix}_save_pre", $value);
  735. } else {
  736. $value = apply_filters("pre_post_$field", $value);
  737. $value = apply_filters("${field}_pre", $value);
  738. }
  739. } else {
  740. // Use display filters by default.
  741. if ( $prefixed )
  742. $value = apply_filters($field, $value, $post_id, $context);
  743. else
  744. $value = apply_filters("post_$field", $value, $post_id, $context);
  745. }
  746. if ( 'attribute' == $context )
  747. $value = attribute_escape($value);
  748. else if ( 'js' == $context )
  749. $value = js_escape($value);
  750. return $value;
  751. }
  752. /**
  753. * Count number of posts of a post type and is user has permissions to view.
  754. *
  755. * This function provides an efficient method of finding the amount of post's
  756. * type a blog has. Another method is to count the amount of items in
  757. * get_posts(), but that method has a lot of overhead with doing so. Therefore,
  758. * when developing for 2.5+, use this function instead.
  759. *
  760. * The $perm parameter checks for 'readable' value and if the user can read
  761. * private posts, it will display that for the user that is signed in.
  762. *
  763. * @package WordPress
  764. * @subpackage Post
  765. * @since 2.5
  766. * @link http://codex.wordpress.org/Template_Tags/wp_count_posts
  767. *
  768. * @param string $type Optional. Post type to retrieve count
  769. * @param string $perm Optional. 'readable' or empty.
  770. * @return object Number of posts for each status
  771. */
  772. function wp_count_posts( $type = 'post', $perm = '' ) {
  773. global $wpdb;
  774. $user = wp_get_current_user();
  775. $cache_key = $type;
  776. $query = "SELECT post_status, COUNT( * ) AS num_posts FROM {$wpdb->posts} WHERE post_type = %s";
  777. if ( 'readable' == $perm && is_user_logged_in() ) {
  778. if ( !current_user_can("read_private_{$type}s") ) {
  779. $cache_key .= '_' . $perm . '_' . $user->ID;
  780. $query .= " AND (post_status != 'private' OR ( post_author = '$user->ID' AND post_status = 'private' ))";
  781. }
  782. }
  783. $query .= ' GROUP BY post_status';
  784. $count = wp_cache_get($cache_key, 'counts');
  785. if ( false !== $count )
  786. return $count;
  787. $count = $wpdb->get_results( $wpdb->prepare( $query, $type ), ARRAY_A );
  788. $stats = array( );
  789. foreach( (array) $count as $row_num => $row ) {
  790. $stats[$row['post_status']] = $row['num_posts'];
  791. }
  792. $stats = (object) $stats;
  793. wp_cache_set($cache_key, $stats, 'counts');
  794. return $stats;
  795. }
  796. /**
  797. * wp_count_attachments() - Count number of attachments
  798. *
  799. * {@internal Missing Long Description}}
  800. *
  801. * @package WordPress
  802. * @subpackage Post
  803. * @since 2.5
  804. *
  805. * @param string|array $post_mime_type Array or comma-separated list of MIME patterns
  806. * @return array Number of posts for each post_mime_type
  807. */
  808. function wp_count_attachments( $mime_type = '' ) {
  809. global $wpdb;
  810. $and = wp_post_mime_type_where( $mime_type );
  811. $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 );
  812. $stats = array( );
  813. foreach( (array) $count as $row ) {
  814. $stats[$row['post_mime_type']] = $row['num_posts'];
  815. }
  816. return (object) $stats;
  817. }
  818. /**
  819. * wp_match_mime_type() - Check a MIME-Type against a list
  820. *
  821. * {@internal Missing Long Description}}
  822. *
  823. * @package WordPress
  824. * @subpackage Post
  825. * @since 2.5
  826. *
  827. * @param string|array $wildcard_mime_types e.g. audio/mpeg or image (same as image/*) or flash (same as *flash*)
  828. * @param string|array $real_mime_types post_mime_type values
  829. * @return array array(wildcard=>array(real types))
  830. */
  831. function wp_match_mime_types($wildcard_mime_types, $real_mime_types) {
  832. $matches = array();
  833. if ( is_string($wildcard_mime_types) )
  834. $wildcard_mime_types = array_map('trim', explode(',', $wildcard_mime_types));
  835. if ( is_string($real_mime_types) )
  836. $real_mime_types = array_map('trim', explode(',', $real_mime_types));
  837. $wild = '[-._a-z0-9]*';
  838. foreach ( (array) $wildcard_mime_types as $type ) {
  839. $type = str_replace('*', $wild, $type);
  840. $patternses[1][$type] = "^$type$";
  841. if ( false === strpos($type, '/') ) {
  842. $patternses[2][$type] = "^$type/";
  843. $patternses[3][$type] = $type;
  844. }
  845. }
  846. asort($patternses);
  847. foreach ( $patternses as $patterns )
  848. foreach ( $patterns as $type => $pattern )
  849. foreach ( (array) $real_mime_types as $real )
  850. if ( preg_match("#$pattern#", $real) && ( empty($matches[$type]) || false === array_search($real, $matches[$type]) ) )
  851. $matches[$type][] = $real;
  852. return $matches;
  853. }
  854. /**
  855. * wp_get_post_mime_type_where() - Convert MIME types into SQL
  856. *
  857. * @package WordPress
  858. * @subpackage Post
  859. * @since 2.5
  860. *
  861. * @param string|array $mime_types MIME types
  862. * @return string SQL AND clause
  863. */
  864. function wp_post_mime_type_where($post_mime_types) {
  865. $where = '';
  866. $wildcards = array('', '%', '%/%');
  867. if ( is_string($post_mime_types) )
  868. $post_mime_types = array_map('trim', explode(',', $post_mime_types));
  869. foreach ( (array) $post_mime_types as $mime_type ) {
  870. $mime_type = preg_replace('/\s/', '', $mime_type);
  871. $slashpos = strpos($mime_type, '/');
  872. if ( false !== $slashpos ) {
  873. $mime_group = preg_replace('/[^-*.a-zA-Z0-9]/', '', substr($mime_type, 0, $slashpos));
  874. $mime_subgroup = preg_replace('/[^-*.a-zA-Z0-9]/', '', substr($mime_type, $slashpos + 1));
  875. if ( empty($mime_subgroup) )
  876. $mime_subgroup = '*';
  877. else
  878. $mime_subgroup = str_replace('/', '', $mime_subgroup);
  879. $mime_pattern = "$mime_group/$mime_subgroup";
  880. } else {
  881. $mime_pattern = preg_replace('/[^-*.a-zA-Z0-9]/', '', $mime_type);
  882. if ( false === strpos($mime_pattern, '*') )
  883. $mime_pattern .= '/*';
  884. }
  885. $mime_pattern = preg_replace('/\*+/', '%', $mime_pattern);
  886. if ( in_array( $mime_type, $wildcards ) )
  887. return '';
  888. if ( false !== strpos($mime_pattern, '%') )
  889. $wheres[] = "post_mime_type LIKE '$mime_pattern'";
  890. else
  891. $wheres[] = "post_mime_type = '$mime_pattern'";
  892. }
  893. if ( !empty($wheres) )
  894. $where = ' AND (' . join(' OR ', $wheres) . ') ';
  895. return $where;
  896. }
  897. /**
  898. * wp_delete_post() - Deletes a Post
  899. *
  900. * {@internal Missing Long Description}}
  901. *
  902. * @package WordPress
  903. * @subpackage Post
  904. * @since 1.0.0
  905. *
  906. * @param int $postid post ID
  907. * @return mixed {@internal Missing Description}}
  908. */
  909. function wp_delete_post($postid = 0) {
  910. global $wpdb, $wp_rewrite;
  911. if ( !$post = $wpdb->get_row($wpdb->prepare("SELECT * FROM $wpdb->posts WHERE ID = %d", $postid)) )
  912. return $post;
  913. if ( 'attachment' == $post->post_type )
  914. return wp_delete_attachment($postid);
  915. do_action('delete_post', $postid);
  916. /** @todo delete for pluggable post taxonomies too */
  917. wp_delete_object_term_relationships($postid, array('category', 'post_tag'));
  918. $parent_data = array( 'post_parent' => $post->post_parent );
  919. $parent_where = array( 'post_parent' => $postid );
  920. if ( 'page' == $post->post_type) {
  921. // if the page is defined in option page_on_front or post_for_posts,
  922. // adjust the corresponding options
  923. if ( get_option('page_on_front') == $postid ) {
  924. update_option('show_on_front', 'posts');
  925. delete_option('page_on_front');
  926. }
  927. if ( get_option('page_for_posts') == $postid ) {
  928. delete_option('page_for_posts');
  929. }
  930. // Point children of this page to its parent, also clean the cache of affected children
  931. $children_query = $wpdb->prepare("SELECT * FROM $wpdb->posts WHERE post_parent = %d AND post_type='page'", $postid);
  932. $children = $wpdb->get_results($children_query);
  933. $wpdb->update( $wpdb->posts, $parent_data, $parent_where + array( 'post_type' => 'page' ) );
  934. }
  935. // Do raw query. wp_get_post_revisions() is filtered
  936. $revision_ids = $wpdb->get_col( $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE post_parent = %d AND post_type = 'revision'", $postid ) );
  937. // Use wp_delete_post (via wp_delete_post_revision) again. Ensures any meta/misplaced data gets cleaned up.
  938. foreach ( $revision_ids as $revision_id )
  939. wp_delete_post_revision( $revision_id );
  940. // Point all attachments to this post up one level
  941. $wpdb->update( $wpdb->posts, $parent_data, $parent_where + array( 'post_type' => 'attachment' ) );
  942. $wpdb->query( $wpdb->prepare( "DELETE FROM $wpdb->posts WHERE ID = %d", $postid ));
  943. $wpdb->query( $wpdb->prepare( "DELETE FROM $wpdb->comments WHERE comment_post_ID = %d", $postid ));
  944. $wpdb->query( $wpdb->prepare( "DELETE FROM $wpdb->postmeta WHERE post_id = %d", $postid ));
  945. if ( 'page' == $post->post_type ) {
  946. clean_page_cache($postid);
  947. foreach ( (array) $children as $child )
  948. clean_page_cache($child->ID);
  949. $wp_rewrite->flush_rules();
  950. } else {
  951. clean_post_cache($postid);
  952. }
  953. do_action('deleted_post', $postid);
  954. return $post;
  955. }
  956. /**
  957. * wp_get_post_categories() - Retrieve the list of categories for a post
  958. *
  959. * Compatibility layer for themes and plugins. Also an easy layer of abstraction
  960. * away from the complexity of the taxonomy layer.
  961. *
  962. * @package WordPress
  963. * @subpackage Post
  964. * @since 2.1
  965. *
  966. * @uses wp_get_object_terms() Retrieves the categories. Args details can be found here
  967. *
  968. * @param int $post_id Optional. The Post ID
  969. * @param array $args Optional. Overwrite the defaults
  970. * @return array {@internal Missing Description}}
  971. */
  972. function wp_get_post_categories( $post_id = 0, $args = array() ) {
  973. $post_id = (int) $post_id;
  974. $defaults = array('fields' => 'ids');
  975. $args = wp_parse_args( $args, $defaults );
  976. $cats = wp_get_object_terms($post_id, 'category', $args);
  977. return $cats;
  978. }
  979. /**
  980. * wp_get_post_tags() - Retrieve the post tags
  981. *
  982. * @package WordPress
  983. * @subpackage Post
  984. * @since 2.3
  985. *
  986. * @uses wp_get_object_terms() Gets the tags for returning. Args can be found here
  987. *
  988. * @param int $post_id Optional. The Post ID
  989. * @param array $args Optional. Overwrite the defaults
  990. * @return mixed The tags the post has currently
  991. */
  992. function wp_get_post_tags( $post_id = 0, $args = array() ) {
  993. $post_id = (int) $post_id;
  994. $defaults = array('fields' => 'all');
  995. $args = wp_parse_args( $args, $defaults );
  996. $tags = wp_get_object_terms($post_id, 'post_tag', $args);
  997. return $tags;
  998. }
  999. /**
  1000. * wp_get_recent_posts() - Get the $num most recent posts
  1001. *
  1002. * {@internal Missing Long Description}}
  1003. *
  1004. * @package WordPress
  1005. * @subpackage Post
  1006. * @since 1.0.0
  1007. *
  1008. * @param int $num number of posts to get
  1009. * @return array {@internal Missing Description}}
  1010. */
  1011. function wp_get_recent_posts($num = 10) {
  1012. global $wpdb;
  1013. // Set the limit clause, if we got a limit
  1014. $num = (int) $num;
  1015. if ($num) {
  1016. $limit = "LIMIT $num";
  1017. }
  1018. $sql = "SELECT * FROM $wpdb->posts WHERE post_type = 'post' ORDER BY post_date DESC $limit";
  1019. $result = $wpdb->get_results($sql,ARRAY_A);
  1020. return $result?$result:array();
  1021. }
  1022. /**
  1023. * wp_get_single_post() - Get one post
  1024. *
  1025. * {@internal Missing Long Description}}
  1026. *
  1027. * @package WordPress
  1028. * @subpackage Post
  1029. * @since 1.0.0
  1030. * @uses $wpdb
  1031. *
  1032. * @param int $postid post ID
  1033. * @param string $mode How to return result, either OBJECT, ARRAY_N, or ARRAY_A
  1034. * @return object|array Post object or array holding post contents and information
  1035. */
  1036. function wp_get_single_post($postid = 0, $mode = OBJECT) {
  1037. $postid = (int) $postid;
  1038. $post = get_post($postid, $mode);
  1039. // Set categories and tags
  1040. if($mode == OBJECT) {
  1041. $post->post_category = wp_get_post_categories($postid);
  1042. $post->tags_input = wp_get_post_tags($postid, array('fields' => 'names'));
  1043. }
  1044. else {
  1045. $post['post_category'] = wp_get_post_categories($postid);
  1046. $post['tags_input'] = wp_get_post_tags($postid, array('fields' => 'names'));
  1047. }
  1048. return $post;
  1049. }
  1050. /**
  1051. * wp_insert_post() - Insert a post
  1052. *
  1053. * {@internal Missing Long Description}}
  1054. *
  1055. * @package WordPress
  1056. * @subpackage Post
  1057. * @since 1.0.0
  1058. *
  1059. * @uses $wpdb
  1060. * @uses $wp_rewrite
  1061. * @uses $user_ID
  1062. * @uses $allowedtags
  1063. *
  1064. * @param array $postarr post contents
  1065. * @return int post ID or 0 on error
  1066. */
  1067. function wp_insert_post($postarr = array(), $wp_error = false) {
  1068. global $wpdb, $wp_rewrite, $user_ID;
  1069. $defaults = array('post_status' => 'draft', 'post_type' => 'post', 'post_author' => $user_ID,
  1070. 'ping_status' => get_option('default_ping_status'), 'post_parent' => 0,
  1071. 'menu_order' => 0, 'to_ping' => '', 'pinged' => '', 'post_password' => '',
  1072. 'guid' => '', 'post_content_filtered' => '', 'post_excerpt' => '');
  1073. $postarr = wp_parse_args($postarr, $defaults);
  1074. $postarr = sanitize_post($postarr, 'db');
  1075. // export array as variables
  1076. extract($postarr, EXTR_SKIP);
  1077. // Are we updating or creating?
  1078. $update = false;
  1079. if ( !empty($ID) ) {
  1080. $update = true;
  1081. $previous_status = get_post_field('post_status', $ID);
  1082. } else {
  1083. $previous_status = 'new';
  1084. }
  1085. if ( ('' == $post_content) && ('' == $post_title) && ('' == $post_excerpt) ) {
  1086. if ( $wp_error )
  1087. return new WP_Error('empty_content', __('Content, title, and excerpt are empty.'));
  1088. else
  1089. return 0;
  1090. }
  1091. // Make sure we set a valid category
  1092. if (0 == count($post_category) || !is_array($post_category)) {
  1093. $post_category = array(get_option('default_category'));
  1094. }
  1095. if ( empty($post_author) )
  1096. $post_author = $user_ID;
  1097. if ( empty($post_status) )
  1098. $post_status = 'draft';
  1099. if ( empty($post_type) )
  1100. $post_type = 'post';
  1101. // Get the post ID and GUID
  1102. if ( $update ) {
  1103. $post_ID = (int) $ID;
  1104. $guid = get_post_field( 'guid', $post_ID );
  1105. }
  1106. // Create a valid post name. Drafts are allowed to have an empty
  1107. // post name.
  1108. if ( empty($post_name) ) {
  1109. if ( 'draft' != $post_status )
  1110. $post_name = sanitize_title($post_title);
  1111. } else {
  1112. $post_name = sanitize_title($post_name);
  1113. }
  1114. // If the post date is empty (due to having been new or a draft) and status is not 'draft', set date to now
  1115. if ( empty($post_date) || '0000-00-00 00:00:00' == $post_date ) {
  1116. if ( !in_array($post_status, array('draft', 'pending')) )
  1117. $post_date = current_time('mysql');
  1118. else
  1119. $post_date = '0000-00-00 00:00:00';
  1120. }
  1121. if ( empty($post_date_gmt) || '0000-00-00 00:00:00' == $post_date_gmt ) {
  1122. if ( !in_array($post_status, array('draft', 'pending')) )
  1123. $post_date_gmt = get_gmt_from_date($post_date);
  1124. else
  1125. $post_date_gmt = '0000-00-00 00:00:00';
  1126. }
  1127. if ( $update || '0000-00-00 00:00:00' == $post_date ) {
  1128. $post_modified = current_time( 'mysql' );
  1129. $post_modified_gmt = current_time( 'mysql', 1 );
  1130. } else {
  1131. $post_modified = $post_date;
  1132. $post_modified_gmt = $post_date_gmt;
  1133. }
  1134. if ( 'publish' == $post_status ) {
  1135. $now = gmdate('Y-m-d H:i:59');
  1136. if ( mysql2date('U', $post_date_gmt) > mysql2date('U', $now) )
  1137. $post_status = 'future';
  1138. }
  1139. if ( empty($comment_status) ) {
  1140. if ( $update )
  1141. $comment_status = 'closed';
  1142. else
  1143. $comment_status = get_option('default_comment_status');
  1144. }
  1145. if ( empty($ping_status) )
  1146. $ping_status = get_option('default_ping_status');
  1147. if ( isset($to_ping) )
  1148. $to_ping = preg_replace('|\s+|', "\n", $to_ping);
  1149. else
  1150. $to_ping = '';
  1151. if ( ! isset($pinged) )
  1152. $pinged = '';
  1153. if ( isset($post_parent) )
  1154. $post_parent = (int) $post_parent;
  1155. else
  1156. $post_parent = 0;
  1157. if ( isset($menu_order) )
  1158. $menu_order = (int) $menu_order;
  1159. else
  1160. $menu_order = 0;
  1161. if ( !isset($post_password) )
  1162. $post_password = '';
  1163. if ( 'draft' != $post_status ) {
  1164. $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));
  1165. if ($post_name_check || in_array($post_name, $wp_rewrite->feeds) ) {
  1166. $suffix = 2;
  1167. do {
  1168. $alt_post_name = substr($post_name, 0, 200-(strlen($suffix)+1)). "-$suffix";
  1169. $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", $alt_post_name, $post_type, $post_ID, $post_parent));
  1170. $suffix++;
  1171. } while ($post_name_check);
  1172. $post_name = $alt_post_name;
  1173. }
  1174. }
  1175. // expected_slashed (everything!)
  1176. $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' ) );
  1177. $data = stripslashes_deep( $data );
  1178. $where = array( 'ID' => $post_ID );
  1179. if ($update) {
  1180. do_action( 'pre_post_update', $post_ID );
  1181. if ( false === $wpdb->update( $wpdb->posts, $data, $where ) ) {
  1182. if ( $wp_error )
  1183. return new WP_Error('db_update_error', __('Could not update post in the database'), $wpdb->last_error);
  1184. else
  1185. return 0;
  1186. }
  1187. } else {
  1188. $data['post_mime_type'] = stripslashes( $post_mime_type ); // This isn't in the update
  1189. if ( false === $wpdb->insert( $wpdb->posts, $data ) ) {
  1190. if ( $wp_error )
  1191. return new WP_Error('db_insert_error', __('Could not insert post into the database'), $wpdb->last_error);
  1192. else
  1193. return 0;
  1194. }
  1195. $post_ID = (int) $wpdb->insert_id;
  1196. // use the newly generated $post_ID
  1197. $where = array( 'ID' => $post_ID );
  1198. }
  1199. if ( empty($post_name) && 'draft' != $post_status ) {
  1200. $post_name = sanitize_title($post_title, $post_ID);
  1201. $wpdb->update( $wpdb->posts, compact( 'post_name' ), $where );
  1202. }
  1203. wp_set_post_categories( $post_ID, $post_category );
  1204. wp_set_post_tags( $post_ID, $tags_input );
  1205. $current_guid = get_post_field( 'guid', $post_ID );
  1206. if ( 'page' == $post_type )
  1207. clean_page_cache($post_ID);
  1208. else
  1209. clean_post_cache($post_ID);
  1210. // Set GUID
  1211. if ( !$update && '' == $current_guid )
  1212. $wpdb->update( $wpdb->posts, array( 'guid' => get_permalink( $post_ID ) ), $where );
  1213. $post = get_post($post_ID);
  1214. if ( !empty($page_template) && 'page' == $post_type ) {
  1215. $post->page_template = $page_template;
  1216. $page_templates = get_page_templates();
  1217. if ( 'default' != $page_template && !in_array($page_template, $page_templates) ) {
  1218. if ( $wp_error )
  1219. return new WP_Error('invalid_page_template', __('The page template is invalid.'));
  1220. else
  1221. return 0;
  1222. }
  1223. update_post_meta($post_ID, '_wp_page_template', $page_template);
  1224. }
  1225. wp_transition_post_status($post_status, $previous_status, $post);
  1226. if ( $update)
  1227. do_action('edit_post', $post_ID, $post);
  1228. do_action('save_post', $post_ID, $post);
  1229. do_action('wp_insert_post', $post_ID, $post);
  1230. return $post_ID;
  1231. }
  1232. /**
  1233. * wp_update_post() - Update a post
  1234. *
  1235. * {@internal Missing Long Description}}
  1236. *
  1237. * @package WordPress
  1238. * @subpackage Post
  1239. * @since 1.0.0
  1240. * @uses $wpdb
  1241. *
  1242. * @param array $postarr post data
  1243. * @return int {@internal Missing Description}}
  1244. */
  1245. function wp_update_post($postarr = array()) {
  1246. if ( is_object($postarr) )
  1247. $postarr = get_object_vars($postarr);
  1248. // First, get all of the original fields
  1249. $post = wp_get_single_post($postarr['ID'], ARRAY_A);
  1250. // Escape data pulled from DB.
  1251. $post = add_magic_quotes($post);
  1252. // Passed post category list overwrites existing category list if not empty.
  1253. if ( isset($postarr['post_category']) && is_array($postarr['post_category'])
  1254. && 0 != count($postarr['post_category']) )
  1255. $post_cats = $postarr['post_category'];
  1256. else
  1257. $post_cats = $post['post_category'];
  1258. // Drafts shouldn't be assigned a date unless explicitly done so by the user
  1259. if ( in_array($post['post_status'], array('draft', 'pending')) && empty($postarr['edit_date']) && empty($postarr['post_date']) &&
  1260. ('0000-00-00 00:00:00' == $post['post_date']) )
  1261. $clear_date = true;
  1262. else
  1263. $clear_date = false;
  1264. // Merge old and new fields with new fields overwriting old ones.
  1265. $postarr = array_merge($post, $postarr);
  1266. $postarr['post_category'] = $post_cats;
  1267. if ( $clear_date ) {
  1268. $postarr['post_date'] = '';
  1269. $postarr['post_date_gmt'] = '';
  1270. }
  1271. if ($postarr['post_type'] == 'attachment')
  1272. return wp_insert_attachment($postarr);
  1273. return wp_insert_post($postarr);
  1274. }
  1275. /**
  1276. * wp_publish_post() - Mark a post as "published"
  1277. *
  1278. * {@internal Missing Long Description}}
  1279. *
  1280. * @package WordPress
  1281. * @subpackage Post
  1282. * @since 2.1
  1283. * @uses $wpdb
  1284. *
  1285. * @param int $post_id Post ID
  1286. * @return int|null {@internal Missing Description}}
  1287. */
  1288. function wp_publish_post($post_id) {
  1289. global $wpdb;
  1290. $post = get_post($post_id);
  1291. if ( empty($post) )
  1292. return;
  1293. if ( 'publish' == $post->post_status )
  1294. return;
  1295. $wpdb->update( $wpdb->posts, array( 'post_status' => 'publish' ), array( 'ID' => $post_id ) );
  1296. $old_status = $post->post_status;
  1297. $post->post_status = 'publish';
  1298. wp_transition_post_status('publish', $old_status, $post);
  1299. // Update counts for the post's terms.
  1300. foreach ( get_object_taxonomies('post') as $taxonomy ) {
  1301. $terms = wp_get_object_terms($post_id, $taxonomy, 'fields=tt_ids');
  1302. wp_update_term_count($terms, $taxonomy);
  1303. }
  1304. do_action('edit_post', $post_id, $post);
  1305. do_action('save_post', $post_id, $post);
  1306. do_action('wp_insert_post', $post_id, $post);
  1307. }
  1308. /**
  1309. * check_and_publish_future_post() - check to make sure post has correct status before
  1310. * passing it on to be published. Invoked by cron 'publish_future_post' event
  1311. * This safeguard prevents cron from publishing drafts, etc.
  1312. *
  1313. * {@internal Missing Long Description}}
  1314. *
  1315. * @package WordPress
  1316. * @subpackage Post
  1317. * @since 2.5
  1318. * @uses $wpdb
  1319. *
  1320. * @param int $post_id Post ID
  1321. * @return int|null {@internal Missing Description}}
  1322. */
  1323. function check_and_publish_future_post($post_id) {
  1324. $post = get_post($post_id);
  1325. if ( empty($post) )
  1326. return;
  1327. if ( 'future' != $post->post_status )
  1328. return;
  1329. return wp_publish_post($post_id);
  1330. }
  1331. /**
  1332. * wp_add_post_tags() - Adds the tags to a post
  1333. *
  1334. * @uses wp_set_post_tags() Same first two paraeters, but the last parameter is always set to true.
  1335. *
  1336. * @package WordPress
  1337. * @subpackage Post
  1338. * @since 2.3
  1339. *
  1340. * @param int $post_id Optional. Post ID
  1341. * @param string $tags The tags to set for the post
  1342. * @return bool|null Will return false if $post_id is not an integer or is 0. Will return null otherwise
  1343. */
  1344. function wp_add_post_tags($post_id = 0, $tags = '') {
  1345. return wp_set_post_tags($post_id, $tags, true);
  1346. }
  1347. /**
  1348. * wp_set_post_tags() - Set the tags for a post
  1349. *
  1350. * {@internal Missing Long Description}}
  1351. *
  1352. * @package WordPress
  1353. * @subpackage Post
  1354. * @since 2.3
  1355. * @uses $wpdb
  1356. *
  1357. * @param int $post_id post ID
  1358. * @param string $tags The tags to set for the post
  1359. * @param bool $append If true, don't delete existing tags, just add on. If false, replace the tags with the new tags.
  1360. * @return bool|null Will return false if $post_id is not an integer or is 0. Will return null otherwise
  1361. */
  1362. function wp_set_post_tags( $post_id = 0, $tags = '', $append = false ) {
  1363. $post_id = (int) $post_id;
  1364. if ( !$post_id )
  1365. return false;
  1366. if ( empty($tags) )
  1367. $tags = array();
  1368. $tags = (is_array($tags)) ? $tags : explode( ',', trim($tags, " \n\t\r\0\x0B,") );
  1369. wp_set_object_terms($post_id, $tags, 'post_tag', $append);
  1370. }
  1371. /**
  1372. * wp_set_post_categories() - Set categories for a post
  1373. *
  1374. * {@internal Missing Long Description}}
  1375. *
  1376. * @package WordPress
  1377. * @subpackage Post
  1378. * @since 2.1
  1379. * @uses $wpdb
  1380. *
  1381. * @param int $post_ID post ID
  1382. * @param array $post_categories
  1383. * @return bool|mixed {@internal Missing Description}}
  1384. */
  1385. function wp_set_post_categories($post_ID = 0, $post_categories = array()) {
  1386. $post_ID = (int) $post_ID;
  1387. // If $post_categories isn't already an array, make it one:
  1388. if (!is_array($post_categories) || 0 == count($post_categories) || empty($post_categories))
  1389. $post_categories = array(get_option('default_category'));
  1390. else if ( 1 == count($post_categories) && '' == $post_categories[0] )
  1391. return true;
  1392. $post_categories = array_map('intval', $post_categories);
  1393. $post_categories = array_unique($post_categories);
  1394. return wp_set_object_terms($post_ID, $post_categories, 'category');
  1395. } // wp_set_post_categories()
  1396. /**
  1397. * wp_transition_post_status() - Change the post transition status
  1398. *
  1399. * {@internal Missing Long Description}}
  1400. *
  1401. * @package WordPress
  1402. * @subpackage Post
  1403. * @since 2.3
  1404. *
  1405. * @param string $new_status {@internal Missing Description}}
  1406. * @param string $old_status {@internal Missing Description}}
  1407. * @param int $post {@internal Missing Description}}
  1408. */
  1409. function wp_transition_post_status($new_status, $old_status, $post) {
  1410. if ( $new_status != $old_status ) {
  1411. do_action('transition_post_status', $new_status, $old_status, $post);
  1412. do_action("${old_status}_to_$new_status", $post);
  1413. }
  1414. do_action("${new_status}_$post->post_type", $post->ID, $post);
  1415. }
  1416. //
  1417. // Trackback and ping functions
  1418. //
  1419. /**
  1420. * add_ping() - Add a URL to those already pung
  1421. *
  1422. * {@internal Missing Long Description}}
  1423. *
  1424. * @package WordPress
  1425. * @subpackage Post
  1426. * @since 1.5
  1427. * @uses $wpdb
  1428. *
  1429. * @param int $post_id post ID
  1430. * @param string $uri {@internal Missing Description}}
  1431. * @return mixed {@internal Missing Description}}
  1432. */
  1433. function add_ping($post_id, $uri) {
  1434. global $wpdb;
  1435. $pung = $wpdb->get_var( $wpdb->prepare( "SELECT pinged FROM $wpdb->posts WHERE ID = %d", $post_id ));
  1436. $pung = trim($pung);
  1437. $pung = preg_split('/\s/', $pung);
  1438. $pung[] = $uri;
  1439. $new = implode("\n", $pung);
  1440. $new = apply_filters('add_ping', $new);
  1441. // expected_slashed ($new)
  1442. $new = stripslashes($new);
  1443. return $wpdb->update( $wpdb->posts, array( 'pinged' => $new ), array( 'ID' => $post_id ) );
  1444. }
  1445. /**
  1446. * get_enclosed() - Get enclosures already enclosed for a post
  1447. *
  1448. * {@internal Missing Long Description}}
  1449. *
  1450. * @package WordPress
  1451. * @subpackage Post
  1452. * @since 1.5
  1453. * @uses $wpdb
  1454. *
  1455. * @param int $post_id post ID
  1456. * @return array {@internal Missing Description}}
  1457. */
  1458. function get_enclosed($post_id) {
  1459. $custom_fields = get_post_custom( $post_id );
  1460. $pung = array();
  1461. if ( !is_array( $custom_fields ) )
  1462. return $pung;
  1463. foreach ( $custom_fields as $key => $val ) {
  1464. if ( 'enclosure' != $key || !is_array( $val ) )
  1465. continue;
  1466. foreach( $val as $enc ) {
  1467. $enclosure = split( "\n", $enc );
  1468. $pung[] = trim( $enclosure[ 0 ] );
  1469. }
  1470. }
  1471. $pung = apply_filters('get_enclosed', $pung);
  1472. return $pung;
  1473. }
  1474. /**
  1475. * get_pung() - Get URLs already pinged for a post
  1476. *
  1477. * {@internal Missing Long Description}}
  1478. *
  1479. * @package WordPress
  1480. * @subpackage Post
  1481. * @since 1.5
  1482. * @uses $wpdb
  1483. *
  1484. * @param int $post_id post ID
  1485. * @return array {@internal Missing Description}}
  1486. */
  1487. function get_pung($post_id) {
  1488. global $wpdb;
  1489. $pung = $wpdb->get_var( $wpdb->prepare( "SELECT pinged FROM $wpdb->posts WHERE ID = %d", $post_id ));
  1490. $pung = trim($pung);
  1491. $pung = preg_split('/\s/', $pung);
  1492. $pung = apply_filters('get_pung', $pung);
  1493. return $pung;
  1494. }
  1495. /**
  1496. * get_to_ping() - Get any URLs in the todo list
  1497. *
  1498. * {@internal Missing Long Description}}
  1499. *
  1500. * @package WordPress
  1501. * @subpackage Post
  1502. * @since 1.5
  1503. * @uses $wpdb
  1504. *
  1505. * @param int $post_id post ID
  1506. * @return array {@internal Missing Description}}
  1507. */
  1508. function get_to_ping($post_id) {
  1509. global $wpdb;
  1510. $to_ping = $wpdb->get_var( $wpdb->prepare( "SELECT to_ping FROM $wpdb->posts WHERE ID = %d", $post_id ));
  1511. $to_ping = trim($to_ping);
  1512. $to_ping = preg_split('/\s/', $to_ping, -1, PREG_SPLIT_NO_EMPTY);
  1513. $to_ping = apply_filters('get_to_ping', $to_ping);
  1514. return $to_ping;
  1515. }
  1516. /**
  1517. * trackback_url_list() - Do trackbacks for a list of urls
  1518. *
  1519. * {@inteā€¦

Large files files are truncated, but you can click here to view the full file