PageRenderTime 48ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/wp-admin/includes/post.php

https://bitbucket.org/julianelve/vendor-wordpress
PHP | 1309 lines | 794 code | 213 blank | 302 comment | 282 complexity | 019f433e738b88e54fcec8a5ff1d7575 MD5 | raw file
Possible License(s): AGPL-1.0, LGPL-2.1, GPL-2.0
  1. <?php
  2. /**
  3. * WordPress Post Administration API.
  4. *
  5. * @package WordPress
  6. * @subpackage Administration
  7. */
  8. /**
  9. * Rename $_POST data from form names to DB post columns.
  10. *
  11. * Manipulates $_POST directly.
  12. *
  13. * @package WordPress
  14. * @since 2.6.0
  15. *
  16. * @param bool $update Are we updating a pre-existing post?
  17. * @param array $post_data Array of post data. Defaults to the contents of $_POST.
  18. * @return object|bool WP_Error on failure, true on success.
  19. */
  20. function _wp_translate_postdata( $update = false, $post_data = null ) {
  21. if ( empty($post_data) )
  22. $post_data = &$_POST;
  23. if ( $update )
  24. $post_data['ID'] = (int) $post_data['post_ID'];
  25. $ptype = get_post_type_object( $post_data['post_type'] );
  26. if ( $update && ! current_user_can( $ptype->cap->edit_post, $post_data['ID'] ) ) {
  27. if ( 'page' == $post_data['post_type'] )
  28. return new WP_Error( 'edit_others_pages', __( 'You are not allowed to edit pages as this user.' ) );
  29. else
  30. return new WP_Error( 'edit_others_posts', __( 'You are not allowed to edit posts as this user.' ) );
  31. } elseif ( ! $update && ! current_user_can( $ptype->cap->create_posts ) ) {
  32. if ( 'page' == $post_data['post_type'] )
  33. return new WP_Error( 'edit_others_pages', __( 'You are not allowed to create pages as this user.' ) );
  34. else
  35. return new WP_Error( 'edit_others_posts', __( 'You are not allowed to create posts as this user.' ) );
  36. }
  37. if ( isset( $post_data['content'] ) )
  38. $post_data['post_content'] = $post_data['content'];
  39. if ( isset( $post_data['excerpt'] ) )
  40. $post_data['post_excerpt'] = $post_data['excerpt'];
  41. if ( isset( $post_data['parent_id'] ) )
  42. $post_data['post_parent'] = (int) $post_data['parent_id'];
  43. if ( isset($post_data['trackback_url']) )
  44. $post_data['to_ping'] = $post_data['trackback_url'];
  45. if ( !isset($post_data['user_ID']) )
  46. $post_data['user_ID'] = $GLOBALS['user_ID'];
  47. if (!empty ( $post_data['post_author_override'] ) ) {
  48. $post_data['post_author'] = (int) $post_data['post_author_override'];
  49. } else {
  50. if (!empty ( $post_data['post_author'] ) ) {
  51. $post_data['post_author'] = (int) $post_data['post_author'];
  52. } else {
  53. $post_data['post_author'] = (int) $post_data['user_ID'];
  54. }
  55. }
  56. if ( ! $update && isset( $post_data['user_ID'] ) && ( $post_data['post_author'] != $post_data['user_ID'] )
  57. && ! current_user_can( $ptype->cap->edit_others_posts ) ) {
  58. if ( 'page' == $post_data['post_type'] )
  59. return new WP_Error( 'edit_others_pages', __( 'You are not allowed to create pages as this user.' ) );
  60. else
  61. return new WP_Error( 'edit_others_posts', __( 'You are not allowed to create posts as this user.' ) );
  62. }
  63. // What to do based on which button they pressed
  64. if ( isset($post_data['saveasdraft']) && '' != $post_data['saveasdraft'] )
  65. $post_data['post_status'] = 'draft';
  66. if ( isset($post_data['saveasprivate']) && '' != $post_data['saveasprivate'] )
  67. $post_data['post_status'] = 'private';
  68. if ( isset($post_data['publish']) && ( '' != $post_data['publish'] ) && ( !isset($post_data['post_status']) || $post_data['post_status'] != 'private' ) )
  69. $post_data['post_status'] = 'publish';
  70. if ( isset($post_data['advanced']) && '' != $post_data['advanced'] )
  71. $post_data['post_status'] = 'draft';
  72. if ( isset($post_data['pending']) && '' != $post_data['pending'] )
  73. $post_data['post_status'] = 'pending';
  74. if ( isset( $post_data['ID'] ) )
  75. $post_id = $post_data['ID'];
  76. else
  77. $post_id = false;
  78. $previous_status = $post_id ? get_post_field( 'post_status', $post_id ) : false;
  79. // Posts 'submitted for approval' present are submitted to $_POST the same as if they were being published.
  80. // Change status from 'publish' to 'pending' if user lacks permissions to publish or to resave published posts.
  81. if ( isset($post_data['post_status']) && ('publish' == $post_data['post_status'] && !current_user_can( $ptype->cap->publish_posts )) )
  82. if ( $previous_status != 'publish' || !current_user_can( 'edit_post', $post_id ) )
  83. $post_data['post_status'] = 'pending';
  84. if ( ! isset($post_data['post_status']) )
  85. $post_data['post_status'] = $previous_status;
  86. if (!isset( $post_data['comment_status'] ))
  87. $post_data['comment_status'] = 'closed';
  88. if (!isset( $post_data['ping_status'] ))
  89. $post_data['ping_status'] = 'closed';
  90. foreach ( array('aa', 'mm', 'jj', 'hh', 'mn') as $timeunit ) {
  91. if ( !empty( $post_data['hidden_' . $timeunit] ) && $post_data['hidden_' . $timeunit] != $post_data[$timeunit] ) {
  92. $post_data['edit_date'] = '1';
  93. break;
  94. }
  95. }
  96. if ( !empty( $post_data['edit_date'] ) ) {
  97. $aa = $post_data['aa'];
  98. $mm = $post_data['mm'];
  99. $jj = $post_data['jj'];
  100. $hh = $post_data['hh'];
  101. $mn = $post_data['mn'];
  102. $ss = $post_data['ss'];
  103. $aa = ($aa <= 0 ) ? date('Y') : $aa;
  104. $mm = ($mm <= 0 ) ? date('n') : $mm;
  105. $jj = ($jj > 31 ) ? 31 : $jj;
  106. $jj = ($jj <= 0 ) ? date('j') : $jj;
  107. $hh = ($hh > 23 ) ? $hh -24 : $hh;
  108. $mn = ($mn > 59 ) ? $mn -60 : $mn;
  109. $ss = ($ss > 59 ) ? $ss -60 : $ss;
  110. $post_data['post_date'] = sprintf( "%04d-%02d-%02d %02d:%02d:%02d", $aa, $mm, $jj, $hh, $mn, $ss );
  111. $valid_date = wp_checkdate( $mm, $jj, $aa, $post_data['post_date'] );
  112. if ( !$valid_date ) {
  113. return new WP_Error( 'invalid_date', __( 'Whoops, the provided date is invalid.' ) );
  114. }
  115. $post_data['post_date_gmt'] = get_gmt_from_date( $post_data['post_date'] );
  116. }
  117. return $post_data;
  118. }
  119. /**
  120. * Update an existing post with values provided in $_POST.
  121. *
  122. * @since 1.5.0
  123. *
  124. * @param array $post_data Optional.
  125. * @return int Post ID.
  126. */
  127. function edit_post( $post_data = null ) {
  128. if ( empty($post_data) )
  129. $post_data = &$_POST;
  130. // Clear out any data in internal vars.
  131. unset( $post_data['filter'] );
  132. $post_ID = (int) $post_data['post_ID'];
  133. $post = get_post( $post_ID );
  134. $post_data['post_type'] = $post->post_type;
  135. $post_data['post_mime_type'] = $post->post_mime_type;
  136. $ptype = get_post_type_object($post_data['post_type']);
  137. if ( !current_user_can( $ptype->cap->edit_post, $post_ID ) ) {
  138. if ( 'page' == $post_data['post_type'] )
  139. wp_die( __('You are not allowed to edit this page.' ));
  140. else
  141. wp_die( __('You are not allowed to edit this post.' ));
  142. }
  143. $post_data = _wp_translate_postdata( true, $post_data );
  144. if ( is_wp_error($post_data) )
  145. wp_die( $post_data->get_error_message() );
  146. if ( ( empty( $post_data['action'] ) || 'autosave' != $post_data['action'] ) && 'auto-draft' == $post_data['post_status'] ) {
  147. $post_data['post_status'] = 'draft';
  148. }
  149. if ( isset($post_data['visibility']) ) {
  150. switch ( $post_data['visibility'] ) {
  151. case 'public' :
  152. $post_data['post_password'] = '';
  153. break;
  154. case 'password' :
  155. unset( $post_data['sticky'] );
  156. break;
  157. case 'private' :
  158. $post_data['post_status'] = 'private';
  159. $post_data['post_password'] = '';
  160. unset( $post_data['sticky'] );
  161. break;
  162. }
  163. }
  164. // Post Formats
  165. if ( isset( $post_data['post_format'] ) ) {
  166. if ( current_theme_supports( 'post-formats', $post_data['post_format'] ) )
  167. set_post_format( $post_ID, $post_data['post_format'] );
  168. elseif ( '0' == $post_data['post_format'] )
  169. set_post_format( $post_ID, false );
  170. }
  171. // Meta Stuff
  172. if ( isset($post_data['meta']) && $post_data['meta'] ) {
  173. foreach ( $post_data['meta'] as $key => $value ) {
  174. if ( !$meta = get_post_meta_by_id( $key ) )
  175. continue;
  176. if ( $meta->post_id != $post_ID )
  177. continue;
  178. if ( is_protected_meta( $value['key'], 'post' ) || ! current_user_can( 'edit_post_meta', $post_ID, $value['key'] ) )
  179. continue;
  180. update_meta( $key, $value['key'], $value['value'] );
  181. }
  182. }
  183. if ( isset($post_data['deletemeta']) && $post_data['deletemeta'] ) {
  184. foreach ( $post_data['deletemeta'] as $key => $value ) {
  185. if ( !$meta = get_post_meta_by_id( $key ) )
  186. continue;
  187. if ( $meta->post_id != $post_ID )
  188. continue;
  189. if ( is_protected_meta( $meta->meta_key, 'post' ) || ! current_user_can( 'delete_post_meta', $post_ID, $meta->meta_key ) )
  190. continue;
  191. delete_meta( $key );
  192. }
  193. }
  194. // Attachment stuff
  195. if ( 'attachment' == $post_data['post_type'] ) {
  196. if ( isset( $post_data[ '_wp_attachment_image_alt' ] ) ) {
  197. $image_alt = get_post_meta( $post_ID, '_wp_attachment_image_alt', true );
  198. if ( $image_alt != stripslashes( $post_data['_wp_attachment_image_alt'] ) ) {
  199. $image_alt = wp_strip_all_tags( stripslashes( $post_data['_wp_attachment_image_alt'] ), true );
  200. // update_meta expects slashed
  201. update_post_meta( $post_ID, '_wp_attachment_image_alt', addslashes( $image_alt ) );
  202. }
  203. }
  204. $attachment_data = isset( $post_data['attachments'][ $post_ID ] ) ? $post_data['attachments'][ $post_ID ] : array();
  205. $post_data = apply_filters( 'attachment_fields_to_save', $post_data, $attachment_data );
  206. }
  207. add_meta( $post_ID );
  208. update_post_meta( $post_ID, '_edit_last', $GLOBALS['current_user']->ID );
  209. wp_update_post( $post_data );
  210. // Now that we have an ID we can fix any attachment anchor hrefs
  211. _fix_attachment_links( $post_ID );
  212. wp_set_post_lock( $post_ID );
  213. if ( current_user_can( $ptype->cap->edit_others_posts ) ) {
  214. if ( ! empty( $post_data['sticky'] ) )
  215. stick_post( $post_ID );
  216. else
  217. unstick_post( $post_ID );
  218. }
  219. return $post_ID;
  220. }
  221. /**
  222. * Process the post data for the bulk editing of posts.
  223. *
  224. * Updates all bulk edited posts/pages, adding (but not removing) tags and
  225. * categories. Skips pages when they would be their own parent or child.
  226. *
  227. * @since 2.7.0
  228. *
  229. * @param array $post_data Optional, the array of post data to process if not provided will use $_POST superglobal.
  230. * @return array
  231. */
  232. function bulk_edit_posts( $post_data = null ) {
  233. global $wpdb;
  234. if ( empty($post_data) )
  235. $post_data = &$_POST;
  236. if ( isset($post_data['post_type']) )
  237. $ptype = get_post_type_object($post_data['post_type']);
  238. else
  239. $ptype = get_post_type_object('post');
  240. if ( !current_user_can( $ptype->cap->edit_posts ) ) {
  241. if ( 'page' == $ptype->name )
  242. wp_die( __('You are not allowed to edit pages.'));
  243. else
  244. wp_die( __('You are not allowed to edit posts.'));
  245. }
  246. if ( -1 == $post_data['_status'] ) {
  247. $post_data['post_status'] = null;
  248. unset($post_data['post_status']);
  249. } else {
  250. $post_data['post_status'] = $post_data['_status'];
  251. }
  252. unset($post_data['_status']);
  253. $post_IDs = array_map( 'intval', (array) $post_data['post'] );
  254. $reset = array( 'post_author', 'post_status', 'post_password', 'post_parent', 'page_template', 'comment_status', 'ping_status', 'keep_private', 'tax_input', 'post_category', 'sticky' );
  255. foreach ( $reset as $field ) {
  256. if ( isset($post_data[$field]) && ( '' == $post_data[$field] || -1 == $post_data[$field] ) )
  257. unset($post_data[$field]);
  258. }
  259. if ( isset($post_data['post_category']) ) {
  260. if ( is_array($post_data['post_category']) && ! empty($post_data['post_category']) )
  261. $new_cats = array_map( 'absint', $post_data['post_category'] );
  262. else
  263. unset($post_data['post_category']);
  264. }
  265. $tax_input = array();
  266. if ( isset($post_data['tax_input'])) {
  267. foreach ( $post_data['tax_input'] as $tax_name => $terms ) {
  268. if ( empty($terms) )
  269. continue;
  270. if ( is_taxonomy_hierarchical( $tax_name ) ) {
  271. $tax_input[ $tax_name ] = array_map( 'absint', $terms );
  272. } else {
  273. $comma = _x( ',', 'tag delimiter' );
  274. if ( ',' !== $comma )
  275. $terms = str_replace( $comma, ',', $terms );
  276. $tax_input[ $tax_name ] = explode( ',', trim( $terms, " \n\t\r\0\x0B," ) );
  277. }
  278. }
  279. }
  280. if ( isset($post_data['post_parent']) && ($parent = (int) $post_data['post_parent']) ) {
  281. $pages = $wpdb->get_results("SELECT ID, post_parent FROM $wpdb->posts WHERE post_type = 'page'");
  282. $children = array();
  283. for ( $i = 0; $i < 50 && $parent > 0; $i++ ) {
  284. $children[] = $parent;
  285. foreach ( $pages as $page ) {
  286. if ( $page->ID == $parent ) {
  287. $parent = $page->post_parent;
  288. break;
  289. }
  290. }
  291. }
  292. }
  293. if ( isset( $post_data['post_format'] ) ) {
  294. if ( '0' == $post_data['post_format'] )
  295. $post_data['post_format'] = false;
  296. // don't change the post format if it's not supported or not '0' (standard)
  297. elseif ( ! current_theme_supports( 'post-formats', $post_data['post_format'] ) )
  298. unset( $post_data['post_format'] );
  299. }
  300. $updated = $skipped = $locked = array();
  301. foreach ( $post_IDs as $post_ID ) {
  302. $post_type_object = get_post_type_object( get_post_type( $post_ID ) );
  303. if ( !isset( $post_type_object ) || ( isset($children) && in_array($post_ID, $children) ) || !current_user_can( $post_type_object->cap->edit_post, $post_ID ) ) {
  304. $skipped[] = $post_ID;
  305. continue;
  306. }
  307. if ( wp_check_post_lock( $post_ID ) ) {
  308. $locked[] = $post_ID;
  309. continue;
  310. }
  311. $post = get_post( $post_ID );
  312. $tax_names = get_object_taxonomies( $post );
  313. foreach ( $tax_names as $tax_name ) {
  314. $taxonomy_obj = get_taxonomy($tax_name);
  315. if ( isset( $tax_input[$tax_name]) && current_user_can( $taxonomy_obj->cap->assign_terms ) )
  316. $new_terms = $tax_input[$tax_name];
  317. else
  318. $new_terms = array();
  319. if ( $taxonomy_obj->hierarchical )
  320. $current_terms = (array) wp_get_object_terms( $post_ID, $tax_name, array('fields' => 'ids') );
  321. else
  322. $current_terms = (array) wp_get_object_terms( $post_ID, $tax_name, array('fields' => 'names') );
  323. $post_data['tax_input'][$tax_name] = array_merge( $current_terms, $new_terms );
  324. }
  325. if ( isset($new_cats) && in_array( 'category', $tax_names ) ) {
  326. $cats = (array) wp_get_post_categories($post_ID);
  327. $post_data['post_category'] = array_unique( array_merge($cats, $new_cats) );
  328. unset( $post_data['tax_input']['category'] );
  329. }
  330. $post_data['post_mime_type'] = $post->post_mime_type;
  331. $post_data['guid'] = $post->guid;
  332. $post_data['ID'] = $post_ID;
  333. $updated[] = wp_update_post( $post_data );
  334. if ( isset( $post_data['sticky'] ) && current_user_can( $ptype->cap->edit_others_posts ) ) {
  335. if ( 'sticky' == $post_data['sticky'] )
  336. stick_post( $post_ID );
  337. else
  338. unstick_post( $post_ID );
  339. }
  340. if ( isset( $post_data['post_format'] ) )
  341. set_post_format( $post_ID, $post_data['post_format'] );
  342. }
  343. return array( 'updated' => $updated, 'skipped' => $skipped, 'locked' => $locked );
  344. }
  345. /**
  346. * Default post information to use when populating the "Write Post" form.
  347. *
  348. * @since 2.0.0
  349. *
  350. * @param string $post_type A post type string, defaults to 'post'.
  351. * @return WP_Post Post object containing all the default post data as attributes
  352. */
  353. function get_default_post_to_edit( $post_type = 'post', $create_in_db = false ) {
  354. global $wpdb;
  355. $post_title = '';
  356. if ( !empty( $_REQUEST['post_title'] ) )
  357. $post_title = esc_html( stripslashes( $_REQUEST['post_title'] ));
  358. $post_content = '';
  359. if ( !empty( $_REQUEST['content'] ) )
  360. $post_content = esc_html( stripslashes( $_REQUEST['content'] ));
  361. $post_excerpt = '';
  362. if ( !empty( $_REQUEST['excerpt'] ) )
  363. $post_excerpt = esc_html( stripslashes( $_REQUEST['excerpt'] ));
  364. if ( $create_in_db ) {
  365. $post_id = wp_insert_post( array( 'post_title' => __( 'Auto Draft' ), 'post_type' => $post_type, 'post_status' => 'auto-draft' ) );
  366. $post = get_post( $post_id );
  367. if ( current_theme_supports( 'post-formats' ) && post_type_supports( $post->post_type, 'post-formats' ) && get_option( 'default_post_format' ) )
  368. set_post_format( $post, get_option( 'default_post_format' ) );
  369. } else {
  370. $post = new stdClass;
  371. $post->ID = 0;
  372. $post->post_author = '';
  373. $post->post_date = '';
  374. $post->post_date_gmt = '';
  375. $post->post_password = '';
  376. $post->post_type = $post_type;
  377. $post->post_status = 'draft';
  378. $post->to_ping = '';
  379. $post->pinged = '';
  380. $post->comment_status = get_option( 'default_comment_status' );
  381. $post->ping_status = get_option( 'default_ping_status' );
  382. $post->post_pingback = get_option( 'default_pingback_flag' );
  383. $post->post_category = get_option( 'default_category' );
  384. $post->page_template = 'default';
  385. $post->post_parent = 0;
  386. $post->menu_order = 0;
  387. $post = new WP_Post( $post );
  388. }
  389. $post->post_content = apply_filters( 'default_content', $post_content, $post );
  390. $post->post_title = apply_filters( 'default_title', $post_title, $post );
  391. $post->post_excerpt = apply_filters( 'default_excerpt', $post_excerpt, $post );
  392. $post->post_name = '';
  393. return $post;
  394. }
  395. /**
  396. * Determine if a post exists based on title, content, and date
  397. *
  398. * @since 2.0.0
  399. *
  400. * @param string $title Post title
  401. * @param string $content Optional post content
  402. * @param string $date Optional post date
  403. * @return int Post ID if post exists, 0 otherwise.
  404. */
  405. function post_exists($title, $content = '', $date = '') {
  406. global $wpdb;
  407. $post_title = stripslashes( sanitize_post_field( 'post_title', $title, 0, 'db' ) );
  408. $post_content = stripslashes( sanitize_post_field( 'post_content', $content, 0, 'db' ) );
  409. $post_date = stripslashes( sanitize_post_field( 'post_date', $date, 0, 'db' ) );
  410. $query = "SELECT ID FROM $wpdb->posts WHERE 1=1";
  411. $args = array();
  412. if ( !empty ( $date ) ) {
  413. $query .= ' AND post_date = %s';
  414. $args[] = $post_date;
  415. }
  416. if ( !empty ( $title ) ) {
  417. $query .= ' AND post_title = %s';
  418. $args[] = $post_title;
  419. }
  420. if ( !empty ( $content ) ) {
  421. $query .= 'AND post_content = %s';
  422. $args[] = $post_content;
  423. }
  424. if ( !empty ( $args ) )
  425. return (int) $wpdb->get_var( $wpdb->prepare($query, $args) );
  426. return 0;
  427. }
  428. /**
  429. * Creates a new post from the "Write Post" form using $_POST information.
  430. *
  431. * @since 2.1.0
  432. *
  433. * @return unknown
  434. */
  435. function wp_write_post() {
  436. global $user_ID;
  437. if ( isset($_POST['post_type']) )
  438. $ptype = get_post_type_object($_POST['post_type']);
  439. else
  440. $ptype = get_post_type_object('post');
  441. if ( !current_user_can( $ptype->cap->edit_posts ) ) {
  442. if ( 'page' == $ptype->name )
  443. return new WP_Error( 'edit_pages', __( 'You are not allowed to create pages on this site.' ) );
  444. else
  445. return new WP_Error( 'edit_posts', __( 'You are not allowed to create posts or drafts on this site.' ) );
  446. }
  447. $_POST['post_mime_type'] = '';
  448. // Clear out any data in internal vars.
  449. unset( $_POST['filter'] );
  450. // Edit don't write if we have a post id.
  451. if ( isset( $_POST['post_ID'] ) )
  452. return edit_post();
  453. $translated = _wp_translate_postdata( false );
  454. if ( is_wp_error($translated) )
  455. return $translated;
  456. if ( isset($_POST['visibility']) ) {
  457. switch ( $_POST['visibility'] ) {
  458. case 'public' :
  459. $_POST['post_password'] = '';
  460. break;
  461. case 'password' :
  462. unset( $_POST['sticky'] );
  463. break;
  464. case 'private' :
  465. $_POST['post_status'] = 'private';
  466. $_POST['post_password'] = '';
  467. unset( $_POST['sticky'] );
  468. break;
  469. }
  470. }
  471. // Create the post.
  472. $post_ID = wp_insert_post( $_POST );
  473. if ( is_wp_error( $post_ID ) )
  474. return $post_ID;
  475. if ( empty($post_ID) )
  476. return 0;
  477. add_meta( $post_ID );
  478. add_post_meta( $post_ID, '_edit_last', $GLOBALS['current_user']->ID );
  479. // Now that we have an ID we can fix any attachment anchor hrefs
  480. _fix_attachment_links( $post_ID );
  481. wp_set_post_lock( $post_ID );
  482. return $post_ID;
  483. }
  484. /**
  485. * Calls wp_write_post() and handles the errors.
  486. *
  487. * @since 2.0.0
  488. * @uses wp_write_post()
  489. * @uses is_wp_error()
  490. * @uses wp_die()
  491. * @return unknown
  492. */
  493. function write_post() {
  494. $result = wp_write_post();
  495. if ( is_wp_error( $result ) )
  496. wp_die( $result->get_error_message() );
  497. else
  498. return $result;
  499. }
  500. //
  501. // Post Meta
  502. //
  503. /**
  504. * {@internal Missing Short Description}}
  505. *
  506. * @since 1.2.0
  507. *
  508. * @param unknown_type $post_ID
  509. * @return unknown
  510. */
  511. function add_meta( $post_ID ) {
  512. global $wpdb;
  513. $post_ID = (int) $post_ID;
  514. $metakeyselect = isset($_POST['metakeyselect']) ? stripslashes( trim( $_POST['metakeyselect'] ) ) : '';
  515. $metakeyinput = isset($_POST['metakeyinput']) ? stripslashes( trim( $_POST['metakeyinput'] ) ) : '';
  516. $metavalue = isset($_POST['metavalue']) ? $_POST['metavalue'] : '';
  517. if ( is_string( $metavalue ) )
  518. $metavalue = trim( $metavalue );
  519. if ( ('0' === $metavalue || ! empty ( $metavalue ) ) && ( ( ( '#NONE#' != $metakeyselect ) && !empty ( $metakeyselect) ) || !empty ( $metakeyinput ) ) ) {
  520. // We have a key/value pair. If both the select and the
  521. // input for the key have data, the input takes precedence:
  522. if ( '#NONE#' != $metakeyselect )
  523. $metakey = $metakeyselect;
  524. if ( $metakeyinput )
  525. $metakey = $metakeyinput; // default
  526. if ( is_protected_meta( $metakey, 'post' ) || ! current_user_can( 'add_post_meta', $post_ID, $metakey ) )
  527. return false;
  528. $metakey = esc_sql( $metakey );
  529. return add_post_meta( $post_ID, $metakey, $metavalue );
  530. }
  531. return false;
  532. } // add_meta
  533. /**
  534. * {@internal Missing Short Description}}
  535. *
  536. * @since 1.2.0
  537. *
  538. * @param unknown_type $mid
  539. * @return unknown
  540. */
  541. function delete_meta( $mid ) {
  542. return delete_metadata_by_mid( 'post' , $mid );
  543. }
  544. /**
  545. * Get a list of previously defined keys.
  546. *
  547. * @since 1.2.0
  548. *
  549. * @return unknown
  550. */
  551. function get_meta_keys() {
  552. global $wpdb;
  553. $keys = $wpdb->get_col( "
  554. SELECT meta_key
  555. FROM $wpdb->postmeta
  556. GROUP BY meta_key
  557. ORDER BY meta_key" );
  558. return $keys;
  559. }
  560. /**
  561. * {@internal Missing Short Description}}
  562. *
  563. * @since 2.1.0
  564. *
  565. * @param unknown_type $mid
  566. * @return unknown
  567. */
  568. function get_post_meta_by_id( $mid ) {
  569. return get_metadata_by_mid( 'post', $mid );
  570. }
  571. /**
  572. * {@internal Missing Short Description}}
  573. *
  574. * Some postmeta stuff.
  575. *
  576. * @since 1.2.0
  577. *
  578. * @param unknown_type $postid
  579. * @return unknown
  580. */
  581. function has_meta( $postid ) {
  582. global $wpdb;
  583. return $wpdb->get_results( $wpdb->prepare("SELECT meta_key, meta_value, meta_id, post_id
  584. FROM $wpdb->postmeta WHERE post_id = %d
  585. ORDER BY meta_key,meta_id", $postid), ARRAY_A );
  586. }
  587. /**
  588. * {@internal Missing Short Description}}
  589. *
  590. * @since 1.2.0
  591. *
  592. * @param unknown_type $meta_id
  593. * @param unknown_type $meta_key Expect Slashed
  594. * @param unknown_type $meta_value Expect Slashed
  595. * @return unknown
  596. */
  597. function update_meta( $meta_id, $meta_key, $meta_value ) {
  598. $meta_key = stripslashes( $meta_key );
  599. $meta_value = stripslashes_deep( $meta_value );
  600. return update_metadata_by_mid( 'post', $meta_id, $meta_value, $meta_key );
  601. }
  602. //
  603. // Private
  604. //
  605. /**
  606. * Replace hrefs of attachment anchors with up-to-date permalinks.
  607. *
  608. * @since 2.3.0
  609. * @access private
  610. *
  611. * @param unknown_type $post_ID
  612. * @return unknown
  613. */
  614. function _fix_attachment_links( $post_ID ) {
  615. $post = get_post( $post_ID, ARRAY_A );
  616. $content = $post['post_content'];
  617. // quick sanity check, don't run if no pretty permalinks or post is not published
  618. if ( !get_option('permalink_structure') || $post['post_status'] != 'publish' )
  619. return;
  620. // Short if there aren't any links or no '?attachment_id=' strings (strpos cannot be zero)
  621. if ( !strpos($content, '?attachment_id=') || !preg_match_all( '/<a ([^>]+)>[\s\S]+?<\/a>/', $content, $link_matches ) )
  622. return;
  623. $site_url = get_bloginfo('url');
  624. $site_url = substr( $site_url, (int) strpos($site_url, '://') ); // remove the http(s)
  625. $replace = '';
  626. foreach ( $link_matches[1] as $key => $value ) {
  627. if ( !strpos($value, '?attachment_id=') || !strpos($value, 'wp-att-')
  628. || !preg_match( '/href=(["\'])[^"\']*\?attachment_id=(\d+)[^"\']*\\1/', $value, $url_match )
  629. || !preg_match( '/rel=["\'][^"\']*wp-att-(\d+)/', $value, $rel_match ) )
  630. continue;
  631. $quote = $url_match[1]; // the quote (single or double)
  632. $url_id = (int) $url_match[2];
  633. $rel_id = (int) $rel_match[1];
  634. if ( !$url_id || !$rel_id || $url_id != $rel_id || strpos($url_match[0], $site_url) === false )
  635. continue;
  636. $link = $link_matches[0][$key];
  637. $replace = str_replace( $url_match[0], 'href=' . $quote . get_attachment_link( $url_id ) . $quote, $link );
  638. $content = str_replace( $link, $replace, $content );
  639. }
  640. if ( $replace ) {
  641. $post['post_content'] = $content;
  642. // Escape data pulled from DB.
  643. $post = add_magic_quotes($post);
  644. return wp_update_post($post);
  645. }
  646. }
  647. /**
  648. * Move child posts to a new parent.
  649. *
  650. * @since 2.3.0
  651. * @access private
  652. *
  653. * @param unknown_type $old_ID
  654. * @param unknown_type $new_ID
  655. * @return unknown
  656. */
  657. function _relocate_children( $old_ID, $new_ID ) {
  658. global $wpdb;
  659. $old_ID = (int) $old_ID;
  660. $new_ID = (int) $new_ID;
  661. $children = $wpdb->get_col( $wpdb->prepare("
  662. SELECT post_id
  663. FROM $wpdb->postmeta
  664. WHERE meta_key = '_wp_attachment_temp_parent'
  665. AND meta_value = %d", $old_ID) );
  666. foreach ( $children as $child_id ) {
  667. $wpdb->update($wpdb->posts, array('post_parent' => $new_ID), array('ID' => $child_id) );
  668. delete_post_meta($child_id, '_wp_attachment_temp_parent');
  669. }
  670. }
  671. /**
  672. * Get all the possible statuses for a post_type
  673. *
  674. * @since 2.5.0
  675. *
  676. * @param string $type The post_type you want the statuses for
  677. * @return array As array of all the statuses for the supplied post type
  678. */
  679. function get_available_post_statuses($type = 'post') {
  680. $stati = wp_count_posts($type);
  681. return array_keys(get_object_vars($stati));
  682. }
  683. /**
  684. * Run the wp query to fetch the posts for listing on the edit posts page
  685. *
  686. * @since 2.5.0
  687. *
  688. * @param array|bool $q Array of query variables to use to build the query or false to use $_GET superglobal.
  689. * @return array
  690. */
  691. function wp_edit_posts_query( $q = false ) {
  692. if ( false === $q )
  693. $q = $_GET;
  694. $q['m'] = isset($q['m']) ? (int) $q['m'] : 0;
  695. $q['cat'] = isset($q['cat']) ? (int) $q['cat'] : 0;
  696. $post_stati = get_post_stati();
  697. if ( isset($q['post_type']) && in_array( $q['post_type'], get_post_types() ) )
  698. $post_type = $q['post_type'];
  699. else
  700. $post_type = 'post';
  701. $avail_post_stati = get_available_post_statuses($post_type);
  702. if ( isset($q['post_status']) && in_array( $q['post_status'], $post_stati ) ) {
  703. $post_status = $q['post_status'];
  704. $perm = 'readable';
  705. }
  706. if ( isset($q['orderby']) )
  707. $orderby = $q['orderby'];
  708. elseif ( isset($q['post_status']) && in_array($q['post_status'], array('pending', 'draft')) )
  709. $orderby = 'modified';
  710. if ( isset($q['order']) )
  711. $order = $q['order'];
  712. elseif ( isset($q['post_status']) && 'pending' == $q['post_status'] )
  713. $order = 'ASC';
  714. $per_page = 'edit_' . $post_type . '_per_page';
  715. $posts_per_page = (int) get_user_option( $per_page );
  716. if ( empty( $posts_per_page ) || $posts_per_page < 1 )
  717. $posts_per_page = 20;
  718. $posts_per_page = apply_filters( $per_page, $posts_per_page );
  719. $posts_per_page = apply_filters( 'edit_posts_per_page', $posts_per_page, $post_type );
  720. $query = compact('post_type', 'post_status', 'perm', 'order', 'orderby', 'posts_per_page');
  721. // Hierarchical types require special args.
  722. if ( is_post_type_hierarchical( $post_type ) && !isset($orderby) ) {
  723. $query['orderby'] = 'menu_order title';
  724. $query['order'] = 'asc';
  725. $query['posts_per_page'] = -1;
  726. $query['posts_per_archive_page'] = -1;
  727. }
  728. if ( ! empty( $q['show_sticky'] ) )
  729. $query['post__in'] = (array) get_option( 'sticky_posts' );
  730. wp( $query );
  731. return $avail_post_stati;
  732. }
  733. /**
  734. * {@internal Missing Short Description}}
  735. *
  736. * @since 2.5.0
  737. *
  738. * @param unknown_type $type
  739. * @return unknown
  740. */
  741. function get_available_post_mime_types($type = 'attachment') {
  742. global $wpdb;
  743. $types = $wpdb->get_col($wpdb->prepare("SELECT DISTINCT post_mime_type FROM $wpdb->posts WHERE post_type = %s", $type));
  744. return $types;
  745. }
  746. /**
  747. * Executes a query for attachments. An array of WP_Query arguments
  748. * can be passed in, which will override the arguments set by this function.
  749. *
  750. * @since 2.5.0
  751. * @uses apply_filters() Calls 'upload_per_page' on posts_per_page argument
  752. *
  753. * @param array|bool $q Array of query variables to use to build the query or false to use $_GET superglobal.
  754. * @return array
  755. */
  756. function wp_edit_attachments_query( $q = false ) {
  757. if ( false === $q )
  758. $q = $_GET;
  759. $q['m'] = isset( $q['m'] ) ? (int) $q['m'] : 0;
  760. $q['cat'] = isset( $q['cat'] ) ? (int) $q['cat'] : 0;
  761. $q['post_type'] = 'attachment';
  762. $post_type = get_post_type_object( 'attachment' );
  763. $states = 'inherit';
  764. if ( current_user_can( $post_type->cap->read_private_posts ) )
  765. $states .= ',private';
  766. $q['post_status'] = isset( $q['status'] ) && 'trash' == $q['status'] ? 'trash' : $states;
  767. $media_per_page = (int) get_user_option( 'upload_per_page' );
  768. if ( empty( $media_per_page ) || $media_per_page < 1 )
  769. $media_per_page = 20;
  770. $q['posts_per_page'] = apply_filters( 'upload_per_page', $media_per_page );
  771. $post_mime_types = get_post_mime_types();
  772. $avail_post_mime_types = get_available_post_mime_types('attachment');
  773. if ( isset($q['post_mime_type']) && !array_intersect( (array) $q['post_mime_type'], array_keys($post_mime_types) ) )
  774. unset($q['post_mime_type']);
  775. if ( isset($q['detached']) )
  776. add_filter('posts_where', '_edit_attachments_query_helper');
  777. wp( $q );
  778. if ( isset($q['detached']) )
  779. remove_filter('posts_where', '_edit_attachments_query_helper');
  780. return array($post_mime_types, $avail_post_mime_types);
  781. }
  782. function _edit_attachments_query_helper($where) {
  783. global $wpdb;
  784. return $where .= " AND {$wpdb->posts}.post_parent < 1";
  785. }
  786. /**
  787. * Returns the list of classes to be used by a metabox
  788. *
  789. * @uses get_user_option()
  790. * @since 2.5.0
  791. *
  792. * @param unknown_type $id
  793. * @param unknown_type $page
  794. * @return unknown
  795. */
  796. function postbox_classes( $id, $page ) {
  797. if ( isset( $_GET['edit'] ) && $_GET['edit'] == $id ) {
  798. $classes = array( '' );
  799. } elseif ( $closed = get_user_option('closedpostboxes_'.$page ) ) {
  800. if ( !is_array( $closed ) ) {
  801. $classes = array( '' );
  802. } else {
  803. $classes = in_array( $id, $closed ) ? array( 'closed' ) : array( '' );
  804. }
  805. } else {
  806. $classes = array( '' );
  807. }
  808. $classes = apply_filters( "postbox_classes_{$page}_{$id}", $classes );
  809. return implode( ' ', $classes );
  810. }
  811. /**
  812. * {@internal Missing Short Description}}
  813. *
  814. * @since 2.5.0
  815. *
  816. * @param int|object $id Post ID or post object.
  817. * @param string $title (optional) Title
  818. * @param string $name (optional) Name
  819. * @return array With two entries of type string
  820. */
  821. function get_sample_permalink($id, $title = null, $name = null) {
  822. $post = get_post($id);
  823. if ( !$post->ID )
  824. return array('', '');
  825. $ptype = get_post_type_object($post->post_type);
  826. $original_status = $post->post_status;
  827. $original_date = $post->post_date;
  828. $original_name = $post->post_name;
  829. // Hack: get_permalink would return ugly permalink for
  830. // drafts, so we will fake, that our post is published
  831. if ( in_array($post->post_status, array('draft', 'pending')) ) {
  832. $post->post_status = 'publish';
  833. $post->post_name = sanitize_title($post->post_name ? $post->post_name : $post->post_title, $post->ID);
  834. }
  835. // If the user wants to set a new name -- override the current one
  836. // Note: if empty name is supplied -- use the title instead, see #6072
  837. if ( !is_null($name) )
  838. $post->post_name = sanitize_title($name ? $name : $title, $post->ID);
  839. $post->post_name = wp_unique_post_slug($post->post_name, $post->ID, $post->post_status, $post->post_type, $post->post_parent);
  840. $post->filter = 'sample';
  841. $permalink = get_permalink($post, true);
  842. // Replace custom post_type Token with generic pagename token for ease of use.
  843. $permalink = str_replace("%$post->post_type%", '%pagename%', $permalink);
  844. // Handle page hierarchy
  845. if ( $ptype->hierarchical ) {
  846. $uri = get_page_uri($post);
  847. $uri = untrailingslashit($uri);
  848. $uri = strrev( stristr( strrev( $uri ), '/' ) );
  849. $uri = untrailingslashit($uri);
  850. $uri = apply_filters( 'editable_slug', $uri );
  851. if ( !empty($uri) )
  852. $uri .= '/';
  853. $permalink = str_replace('%pagename%', "{$uri}%pagename%", $permalink);
  854. }
  855. $permalink = array($permalink, apply_filters('editable_slug', $post->post_name));
  856. $post->post_status = $original_status;
  857. $post->post_date = $original_date;
  858. $post->post_name = $original_name;
  859. unset($post->filter);
  860. return $permalink;
  861. }
  862. /**
  863. * Returns the HTML of the sample permalink slug editor.
  864. *
  865. * @since 2.5.0
  866. *
  867. * @param int|object $id Post ID or post object.
  868. * @param string $new_title Optional. New title.
  869. * @param string $new_slug Optional. New slug.
  870. * @return string The HTML of the sample permalink slug editor.
  871. */
  872. function get_sample_permalink_html( $id, $new_title = null, $new_slug = null ) {
  873. global $wpdb;
  874. $post = get_post($id);
  875. list($permalink, $post_name) = get_sample_permalink($post->ID, $new_title, $new_slug);
  876. if ( 'publish' == get_post_status( $post ) ) {
  877. $ptype = get_post_type_object($post->post_type);
  878. $view_post = $ptype->labels->view_item;
  879. $title = __('Click to edit this part of the permalink');
  880. } else {
  881. $title = __('Temporary permalink. Click to edit this part.');
  882. }
  883. if ( false === strpos($permalink, '%postname%') && false === strpos($permalink, '%pagename%') ) {
  884. $return = '<strong>' . __('Permalink:') . "</strong>\n" . '<span id="sample-permalink" tabindex="-1">' . $permalink . "</span>\n";
  885. if ( '' == get_option( 'permalink_structure' ) && current_user_can( 'manage_options' ) && !( 'page' == get_option('show_on_front') && $id == get_option('page_on_front') ) )
  886. $return .= '<span id="change-permalinks"><a href="options-permalink.php" class="button button-small" target="_blank">' . __('Change Permalinks') . "</a></span>\n";
  887. if ( isset( $view_post ) )
  888. $return .= "<span id='view-post-btn'><a href='$permalink' class='button button-small'>$view_post</a></span>\n";
  889. $return = apply_filters('get_sample_permalink_html', $return, $id, $new_title, $new_slug);
  890. return $return;
  891. }
  892. if ( function_exists('mb_strlen') ) {
  893. if ( mb_strlen($post_name) > 30 ) {
  894. $post_name_abridged = mb_substr($post_name, 0, 14). '&hellip;' . mb_substr($post_name, -14);
  895. } else {
  896. $post_name_abridged = $post_name;
  897. }
  898. } else {
  899. if ( strlen($post_name) > 30 ) {
  900. $post_name_abridged = substr($post_name, 0, 14). '&hellip;' . substr($post_name, -14);
  901. } else {
  902. $post_name_abridged = $post_name;
  903. }
  904. }
  905. $post_name_html = '<span id="editable-post-name" title="' . $title . '">' . $post_name_abridged . '</span>';
  906. $display_link = str_replace(array('%pagename%','%postname%'), $post_name_html, $permalink);
  907. $view_link = str_replace(array('%pagename%','%postname%'), $post_name, $permalink);
  908. $return = '<strong>' . __('Permalink:') . "</strong>\n";
  909. $return .= '<span id="sample-permalink" tabindex="-1">' . $display_link . "</span>\n";
  910. $return .= '&lrm;'; // Fix bi-directional text display defect in RTL languages.
  911. $return .= '<span id="edit-slug-buttons"><a href="#post_name" class="edit-slug button button-small hide-if-no-js" onclick="editPermalink(' . $id . '); return false;">' . __('Edit') . "</a></span>\n";
  912. $return .= '<span id="editable-post-name-full">' . $post_name . "</span>\n";
  913. if ( isset($view_post) )
  914. $return .= "<span id='view-post-btn'><a href='$view_link' class='button button-small'>$view_post</a></span>\n";
  915. $return = apply_filters('get_sample_permalink_html', $return, $id, $new_title, $new_slug);
  916. return $return;
  917. }
  918. /**
  919. * Output HTML for the post thumbnail meta-box.
  920. *
  921. * @since 2.9.0
  922. *
  923. * @param int $thumbnail_id ID of the attachment used for thumbnail
  924. * @param mixed $post The post ID or object associated with the thumbnail, defaults to global $post.
  925. * @return string html
  926. */
  927. function _wp_post_thumbnail_html( $thumbnail_id = null, $post = null ) {
  928. global $content_width, $_wp_additional_image_sizes;
  929. $post = get_post( $post );
  930. $upload_iframe_src = esc_url( get_upload_iframe_src('image', $post->ID ) );
  931. $set_thumbnail_link = '<p class="hide-if-no-js"><a title="' . esc_attr__( 'Set featured image' ) . '" href="%s" id="set-post-thumbnail" class="thickbox">%s</a></p>';
  932. $content = sprintf( $set_thumbnail_link, $upload_iframe_src, esc_html__( 'Set featured image' ) );
  933. if ( $thumbnail_id && get_post( $thumbnail_id ) ) {
  934. $old_content_width = $content_width;
  935. $content_width = 266;
  936. if ( !isset( $_wp_additional_image_sizes['post-thumbnail'] ) )
  937. $thumbnail_html = wp_get_attachment_image( $thumbnail_id, array( $content_width, $content_width ) );
  938. else
  939. $thumbnail_html = wp_get_attachment_image( $thumbnail_id, 'post-thumbnail' );
  940. if ( !empty( $thumbnail_html ) ) {
  941. $ajax_nonce = wp_create_nonce( 'set_post_thumbnail-' . $post->ID );
  942. $content = sprintf( $set_thumbnail_link, $upload_iframe_src, $thumbnail_html );
  943. $content .= '<p class="hide-if-no-js"><a href="#" id="remove-post-thumbnail" onclick="WPRemoveThumbnail(\'' . $ajax_nonce . '\');return false;">' . esc_html__( 'Remove featured image' ) . '</a></p>';
  944. }
  945. $content_width = $old_content_width;
  946. }
  947. return apply_filters( 'admin_post_thumbnail_html', $content, $post->ID );
  948. }
  949. /**
  950. * Check to see if the post is currently being edited by another user.
  951. *
  952. * @since 2.5.0
  953. *
  954. * @param int $post_id ID of the post to check for editing
  955. * @return bool|int False: not locked or locked by current user. Int: user ID of user with lock.
  956. */
  957. function wp_check_post_lock( $post_id ) {
  958. if ( !$post = get_post( $post_id ) )
  959. return false;
  960. if ( !$lock = get_post_meta( $post->ID, '_edit_lock', true ) )
  961. return false;
  962. $lock = explode( ':', $lock );
  963. $time = $lock[0];
  964. $user = isset( $lock[1] ) ? $lock[1] : get_post_meta( $post->ID, '_edit_last', true );
  965. $time_window = apply_filters( 'wp_check_post_lock_window', AUTOSAVE_INTERVAL * 2 );
  966. if ( $time && $time > time() - $time_window && $user != get_current_user_id() )
  967. return $user;
  968. return false;
  969. }
  970. /**
  971. * Mark the post as currently being edited by the current user
  972. *
  973. * @since 2.5.0
  974. *
  975. * @param int $post_id ID of the post to being edited
  976. * @return bool|array Returns false if the post doesn't exist of there is no current user, or
  977. * an array of the lock time and the user ID.
  978. */
  979. function wp_set_post_lock( $post_id ) {
  980. if ( !$post = get_post( $post_id ) )
  981. return false;
  982. if ( 0 == ($user_id = get_current_user_id()) )
  983. return false;
  984. $now = time();
  985. $lock = "$now:$user_id";
  986. update_post_meta( $post->ID, '_edit_lock', $lock );
  987. return array( $now, $user_id );
  988. }
  989. /**
  990. * Outputs the notice message to say that someone else is editing this post at the moment.
  991. *
  992. * @since 2.8.5
  993. * @return none
  994. */
  995. function _admin_notice_post_locked() {
  996. $post = get_post();
  997. $lock = explode( ':', get_post_meta( $post->ID, '_edit_lock', true ) );
  998. $user = isset( $lock[1] ) ? $lock[1] : get_post_meta( $post->ID, '_edit_last', true );
  999. $last_user = get_userdata( $user );
  1000. $last_user_name = $last_user ? $last_user->display_name : __('Somebody');
  1001. switch ($post->post_type) {
  1002. case 'post':
  1003. $message = __( 'Warning: %s is currently editing this post' );
  1004. break;
  1005. case 'page':
  1006. $message = __( 'Warning: %s is currently editing this page' );
  1007. break;
  1008. default:
  1009. $message = __( 'Warning: %s is currently editing this.' );
  1010. }
  1011. $message = sprintf( $message, esc_html( $last_user_name ) );
  1012. echo "<div class='error'><p>$message</p></div>";
  1013. }
  1014. /**
  1015. * Creates autosave data for the specified post from $_POST data.
  1016. *
  1017. * @package WordPress
  1018. * @subpackage Post_Revisions
  1019. * @since 2.6.0
  1020. *
  1021. * @uses _wp_translate_postdata()
  1022. * @uses _wp_post_revision_fields()
  1023. *
  1024. * @return unknown
  1025. */
  1026. function wp_create_post_autosave( $post_id ) {
  1027. $translated = _wp_translate_postdata( true );
  1028. if ( is_wp_error( $translated ) )
  1029. return $translated;
  1030. // Only store one autosave. If there is already an autosave, overwrite it.
  1031. if ( $old_autosave = wp_get_post_autosave( $post_id ) ) {
  1032. $new_autosave = _wp_post_revision_fields( $_POST, true );
  1033. $new_autosave['ID'] = $old_autosave->ID;
  1034. $new_autosave['post_author'] = get_current_user_id();
  1035. return wp_update_post( $new_autosave );
  1036. }
  1037. // _wp_put_post_revision() expects unescaped.
  1038. $_POST = stripslashes_deep($_POST);
  1039. // Otherwise create the new autosave as a special post revision
  1040. return _wp_put_post_revision( $_POST, true );
  1041. }
  1042. /**
  1043. * Save draft or manually autosave for showing preview.
  1044. *
  1045. * @package WordPress
  1046. * @since 2.7.0
  1047. *
  1048. * @uses get_post_status()
  1049. * @uses edit_post()
  1050. * @uses get_post()
  1051. * @uses current_user_can()
  1052. * @uses wp_die()
  1053. * @uses wp_create_post_autosave()
  1054. * @uses add_query_arg()
  1055. * @uses wp_create_nonce()
  1056. *
  1057. * @return str URL to redirect to show the preview
  1058. */
  1059. function post_preview() {
  1060. $post_ID = (int) $_POST['post_ID'];
  1061. $status = get_post_status( $post_ID );
  1062. if ( 'auto-draft' == $status )
  1063. wp_die( __('Preview not available. Please save as a draft first.') );
  1064. if ( isset($_POST['catslist']) )
  1065. $_POST['post_category'] = explode(",", $_POST['catslist']);
  1066. if ( isset($_POST['tags_input']) )
  1067. $_POST['tags_input'] = explode(",", $_POST['tags_input']);
  1068. if ( $_POST['post_type'] == 'page' || empty($_POST['post_category']) )
  1069. unset($_POST['post_category']);
  1070. $_POST['ID'] = $post_ID;
  1071. $post = get_post($post_ID);
  1072. if ( 'page' == $post->post_type ) {
  1073. if ( !current_user_can('edit_page', $post_ID) )
  1074. wp_die(__('You are not allowed to edit this page.'));
  1075. } else {
  1076. if ( !current_user_can('edit_post', $post_ID) )
  1077. wp_die(__('You are not allowed to edit this post.'));
  1078. }
  1079. if ( 'draft' == $post->post_status ) {
  1080. $id = edit_post();
  1081. } else { // Non drafts are not overwritten. The autosave is stored in a special post revision.
  1082. $id = wp_create_post_autosave( $post->ID );
  1083. if ( ! is_wp_error($id) )
  1084. $id = $post->ID;
  1085. }
  1086. if ( is_wp_error($id) )
  1087. wp_die( $id->get_error_message() );
  1088. if ( $_POST['post_status'] == 'draft' ) {
  1089. $url = add_query_arg( 'preview', 'true', get_permalink($id) );
  1090. } else {
  1091. $nonce = wp_create_nonce('post_preview_' . $id);
  1092. $url = add_query_arg( array( 'preview' => 'true', 'preview_id' => $id, 'preview_nonce' => $nonce ), get_permalink($id) );
  1093. }
  1094. return $url;
  1095. }