PageRenderTime 58ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/wp-admin/includes/class-wp-posts-list-table.php

https://github.com/shaiquddin/WordPress
PHP | 1061 lines | 788 code | 202 blank | 71 comment | 198 complexity | 5e63f6bc2ce643f67f762b987aaca76d MD5 | raw file
Possible License(s): GPL-2.0, AGPL-1.0, LGPL-2.1
  1. <?php
  2. /**
  3. * Posts List Table class.
  4. *
  5. * @package WordPress
  6. * @subpackage List_Table
  7. * @since 3.1.0
  8. * @access private
  9. */
  10. class WP_Posts_List_Table extends WP_List_Table {
  11. /**
  12. * Whether the items should be displayed hierarchically or linearly
  13. *
  14. * @since 3.1.0
  15. * @var bool
  16. * @access protected
  17. */
  18. var $hierarchical_display;
  19. /**
  20. * Holds the number of pending comments for each post
  21. *
  22. * @since 3.1.0
  23. * @var int
  24. * @access protected
  25. */
  26. var $comment_pending_count;
  27. /**
  28. * Holds the number of posts for this user
  29. *
  30. * @since 3.1.0
  31. * @var int
  32. * @access private
  33. */
  34. var $user_posts_count;
  35. /**
  36. * Holds the number of posts which are sticky.
  37. *
  38. * @since 3.1.0
  39. * @var int
  40. * @access private
  41. */
  42. var $sticky_posts_count = 0;
  43. function __construct( $args = array() ) {
  44. global $post_type_object, $wpdb;
  45. parent::__construct( array(
  46. 'plural' => 'posts',
  47. 'screen' => isset( $args['screen'] ) ? $args['screen'] : null,
  48. ) );
  49. $post_type = $this->screen->post_type;
  50. $post_type_object = get_post_type_object( $post_type );
  51. if ( !current_user_can( $post_type_object->cap->edit_others_posts ) ) {
  52. $this->user_posts_count = $wpdb->get_var( $wpdb->prepare( "
  53. SELECT COUNT( 1 ) FROM $wpdb->posts
  54. WHERE post_type = %s AND post_status NOT IN ( 'trash', 'auto-draft' )
  55. AND post_author = %d
  56. ", $post_type, get_current_user_id() ) );
  57. if ( $this->user_posts_count && empty( $_REQUEST['post_status'] ) && empty( $_REQUEST['all_posts'] ) && empty( $_REQUEST['author'] ) && empty( $_REQUEST['show_sticky'] ) )
  58. $_GET['author'] = get_current_user_id();
  59. }
  60. if ( 'post' == $post_type && $sticky_posts = get_option( 'sticky_posts' ) ) {
  61. $sticky_posts = implode( ', ', array_map( 'absint', (array) $sticky_posts ) );
  62. $this->sticky_posts_count = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT( 1 ) FROM $wpdb->posts WHERE post_type = %s AND post_status != 'trash' AND ID IN ($sticky_posts)", $post_type ) );
  63. }
  64. }
  65. function ajax_user_can() {
  66. return current_user_can( get_post_type_object( $this->screen->post_type )->cap->edit_posts );
  67. }
  68. function prepare_items() {
  69. global $avail_post_stati, $wp_query, $per_page, $mode;
  70. $avail_post_stati = wp_edit_posts_query();
  71. $this->hierarchical_display = ( is_post_type_hierarchical( $this->screen->post_type ) && 'menu_order title' == $wp_query->query['orderby'] );
  72. $total_items = $this->hierarchical_display ? $wp_query->post_count : $wp_query->found_posts;
  73. $post_type = $this->screen->post_type;
  74. $per_page = $this->get_items_per_page( 'edit_' . $post_type . '_per_page' );
  75. $per_page = apply_filters( 'edit_posts_per_page', $per_page, $post_type );
  76. if ( $this->hierarchical_display )
  77. $total_pages = ceil( $total_items / $per_page );
  78. else
  79. $total_pages = $wp_query->max_num_pages;
  80. $mode = empty( $_REQUEST['mode'] ) ? 'list' : $_REQUEST['mode'];
  81. $this->is_trash = isset( $_REQUEST['post_status'] ) && $_REQUEST['post_status'] == 'trash';
  82. $this->set_pagination_args( array(
  83. 'total_items' => $total_items,
  84. 'total_pages' => $total_pages,
  85. 'per_page' => $per_page
  86. ) );
  87. }
  88. function has_items() {
  89. return have_posts();
  90. }
  91. function no_items() {
  92. if ( isset( $_REQUEST['post_status'] ) && 'trash' == $_REQUEST['post_status'] )
  93. echo get_post_type_object( $this->screen->post_type )->labels->not_found_in_trash;
  94. else
  95. echo get_post_type_object( $this->screen->post_type )->labels->not_found;
  96. }
  97. function get_views() {
  98. global $locked_post_status, $avail_post_stati;
  99. $post_type = $this->screen->post_type;
  100. if ( !empty($locked_post_status) )
  101. return array();
  102. $status_links = array();
  103. $num_posts = wp_count_posts( $post_type, 'readable' );
  104. $class = '';
  105. $allposts = '';
  106. $current_user_id = get_current_user_id();
  107. if ( $this->user_posts_count ) {
  108. if ( isset( $_GET['author'] ) && ( $_GET['author'] == $current_user_id ) )
  109. $class = ' class="current"';
  110. $status_links['mine'] = "<a href='edit.php?post_type=$post_type&author=$current_user_id'$class>" . sprintf( _nx( 'Mine <span class="count">(%s)</span>', 'Mine <span class="count">(%s)</span>', $this->user_posts_count, 'posts' ), number_format_i18n( $this->user_posts_count ) ) . '</a>';
  111. $allposts = '&all_posts=1';
  112. }
  113. $total_posts = array_sum( (array) $num_posts );
  114. // Subtract post types that are not included in the admin all list.
  115. foreach ( get_post_stati( array('show_in_admin_all_list' => false) ) as $state )
  116. $total_posts -= $num_posts->$state;
  117. $class = empty( $class ) && empty( $_REQUEST['post_status'] ) && empty( $_REQUEST['show_sticky'] ) ? ' class="current"' : '';
  118. $status_links['all'] = "<a href='edit.php?post_type=$post_type{$allposts}'$class>" . sprintf( _nx( 'All <span class="count">(%s)</span>', 'All <span class="count">(%s)</span>', $total_posts, 'posts' ), number_format_i18n( $total_posts ) ) . '</a>';
  119. foreach ( get_post_stati(array('show_in_admin_status_list' => true), 'objects') as $status ) {
  120. $class = '';
  121. $status_name = $status->name;
  122. if ( !in_array( $status_name, $avail_post_stati ) )
  123. continue;
  124. if ( empty( $num_posts->$status_name ) )
  125. continue;
  126. if ( isset($_REQUEST['post_status']) && $status_name == $_REQUEST['post_status'] )
  127. $class = ' class="current"';
  128. $status_links[$status_name] = "<a href='edit.php?post_status=$status_name&amp;post_type=$post_type'$class>" . sprintf( translate_nooped_plural( $status->label_count, $num_posts->$status_name ), number_format_i18n( $num_posts->$status_name ) ) . '</a>';
  129. }
  130. if ( ! empty( $this->sticky_posts_count ) ) {
  131. $class = ! empty( $_REQUEST['show_sticky'] ) ? ' class="current"' : '';
  132. $sticky_link = array( 'sticky' => "<a href='edit.php?post_type=$post_type&amp;show_sticky=1'$class>" . sprintf( _nx( 'Sticky <span class="count">(%s)</span>', 'Sticky <span class="count">(%s)</span>', $this->sticky_posts_count, 'posts' ), number_format_i18n( $this->sticky_posts_count ) ) . '</a>' );
  133. // Sticky comes after Publish, or if not listed, after All.
  134. $split = 1 + array_search( ( isset( $status_links['publish'] ) ? 'publish' : 'all' ), array_keys( $status_links ) );
  135. $status_links = array_merge( array_slice( $status_links, 0, $split ), $sticky_link, array_slice( $status_links, $split ) );
  136. }
  137. return $status_links;
  138. }
  139. function get_bulk_actions() {
  140. $actions = array();
  141. if ( $this->is_trash )
  142. $actions['untrash'] = __( 'Restore' );
  143. else
  144. $actions['edit'] = __( 'Edit' );
  145. if ( $this->is_trash || !EMPTY_TRASH_DAYS )
  146. $actions['delete'] = __( 'Delete Permanently' );
  147. else
  148. $actions['trash'] = __( 'Move to Trash' );
  149. return $actions;
  150. }
  151. function extra_tablenav( $which ) {
  152. global $cat;
  153. ?>
  154. <div class="alignleft actions">
  155. <?php
  156. if ( 'top' == $which && !is_singular() ) {
  157. $this->months_dropdown( $this->screen->post_type );
  158. if ( is_object_in_taxonomy( $this->screen->post_type, 'category' ) ) {
  159. $dropdown_options = array(
  160. 'show_option_all' => __( 'View all categories' ),
  161. 'hide_empty' => 0,
  162. 'hierarchical' => 1,
  163. 'show_count' => 0,
  164. 'orderby' => 'name',
  165. 'selected' => $cat
  166. );
  167. wp_dropdown_categories( $dropdown_options );
  168. }
  169. do_action( 'restrict_manage_posts' );
  170. submit_button( __( 'Filter' ), 'button', false, false, array( 'id' => 'post-query-submit' ) );
  171. }
  172. if ( $this->is_trash && current_user_can( get_post_type_object( $this->screen->post_type )->cap->edit_others_posts ) ) {
  173. submit_button( __( 'Empty Trash' ), 'apply', 'delete_all', false );
  174. }
  175. ?>
  176. </div>
  177. <?php
  178. }
  179. function current_action() {
  180. if ( isset( $_REQUEST['delete_all'] ) || isset( $_REQUEST['delete_all2'] ) )
  181. return 'delete_all';
  182. return parent::current_action();
  183. }
  184. function pagination( $which ) {
  185. global $mode;
  186. parent::pagination( $which );
  187. if ( 'top' == $which && ! is_post_type_hierarchical( $this->screen->post_type ) )
  188. $this->view_switcher( $mode );
  189. }
  190. function get_table_classes() {
  191. return array( 'widefat', 'fixed', is_post_type_hierarchical( $this->screen->post_type ) ? 'pages' : 'posts' );
  192. }
  193. function get_columns() {
  194. $post_type = $this->screen->post_type;
  195. $posts_columns = array();
  196. $posts_columns['cb'] = '<input type="checkbox" />';
  197. /* translators: manage posts column name */
  198. $posts_columns['title'] = _x( 'Title', 'column name' );
  199. if ( post_type_supports( $post_type, 'author' ) )
  200. $posts_columns['author'] = __( 'Author' );
  201. $taxonomies = array();
  202. $taxonomies = get_object_taxonomies( $post_type, 'objects' );
  203. $taxonomies = wp_filter_object_list( $taxonomies, array( 'show_admin_column' => true ), 'and', 'name' );
  204. $taxonomies = apply_filters( "manage_taxonomies_for_{$post_type}_columns", $taxonomies, $post_type );
  205. $taxonomies = array_filter( $taxonomies, 'taxonomy_exists' );
  206. foreach ( $taxonomies as $taxonomy ) {
  207. if ( 'category' == $taxonomy )
  208. $column_key = 'categories';
  209. elseif ( 'post_tag' == $taxonomy )
  210. $column_key = 'tags';
  211. else
  212. $column_key = 'taxonomy-' . $taxonomy;
  213. $posts_columns[ $column_key ] = get_taxonomy( $taxonomy )->labels->name;
  214. }
  215. $post_status = !empty( $_REQUEST['post_status'] ) ? $_REQUEST['post_status'] : 'all';
  216. if ( post_type_supports( $post_type, 'comments' ) && !in_array( $post_status, array( 'pending', 'draft', 'future' ) ) )
  217. $posts_columns['comments'] = '<span class="vers"><img alt="' . esc_attr__( 'Comments' ) . '" src="' . esc_url( admin_url( 'images/comment-grey-bubble.png' ) ) . '" /></span>';
  218. $posts_columns['date'] = __( 'Date' );
  219. if ( 'page' == $post_type )
  220. $posts_columns = apply_filters( 'manage_pages_columns', $posts_columns );
  221. else
  222. $posts_columns = apply_filters( 'manage_posts_columns', $posts_columns, $post_type );
  223. $posts_columns = apply_filters( "manage_{$post_type}_posts_columns", $posts_columns );
  224. return $posts_columns;
  225. }
  226. function get_sortable_columns() {
  227. return array(
  228. 'title' => 'title',
  229. 'parent' => 'parent',
  230. 'comments' => 'comment_count',
  231. 'date' => array( 'date', true )
  232. );
  233. }
  234. function display_rows( $posts = array(), $level = 0 ) {
  235. global $wp_query, $per_page;
  236. if ( empty( $posts ) )
  237. $posts = $wp_query->posts;
  238. add_filter( 'the_title', 'esc_html' );
  239. if ( $this->hierarchical_display ) {
  240. $this->_display_rows_hierarchical( $posts, $this->get_pagenum(), $per_page );
  241. } else {
  242. $this->_display_rows( $posts, $level );
  243. }
  244. }
  245. function _display_rows( $posts, $level = 0 ) {
  246. global $mode;
  247. // Create array of post IDs.
  248. $post_ids = array();
  249. foreach ( $posts as $a_post )
  250. $post_ids[] = $a_post->ID;
  251. $this->comment_pending_count = get_pending_comments_num( $post_ids );
  252. foreach ( $posts as $post )
  253. $this->single_row( $post, $level );
  254. }
  255. function _display_rows_hierarchical( $pages, $pagenum = 1, $per_page = 20 ) {
  256. global $wpdb;
  257. $level = 0;
  258. if ( ! $pages ) {
  259. $pages = get_pages( array( 'sort_column' => 'menu_order' ) );
  260. if ( ! $pages )
  261. return false;
  262. }
  263. /*
  264. * arrange pages into two parts: top level pages and children_pages
  265. * children_pages is two dimensional array, eg.
  266. * children_pages[10][] contains all sub-pages whose parent is 10.
  267. * It only takes O( N ) to arrange this and it takes O( 1 ) for subsequent lookup operations
  268. * If searching, ignore hierarchy and treat everything as top level
  269. */
  270. if ( empty( $_REQUEST['s'] ) ) {
  271. $top_level_pages = array();
  272. $children_pages = array();
  273. foreach ( $pages as $page ) {
  274. // catch and repair bad pages
  275. if ( $page->post_parent == $page->ID ) {
  276. $page->post_parent = 0;
  277. $wpdb->update( $wpdb->posts, array( 'post_parent' => 0 ), array( 'ID' => $page->ID ) );
  278. clean_post_cache( $page );
  279. }
  280. if ( 0 == $page->post_parent )
  281. $top_level_pages[] = $page;
  282. else
  283. $children_pages[ $page->post_parent ][] = $page;
  284. }
  285. $pages = &$top_level_pages;
  286. }
  287. $count = 0;
  288. $start = ( $pagenum - 1 ) * $per_page;
  289. $end = $start + $per_page;
  290. foreach ( $pages as $page ) {
  291. if ( $count >= $end )
  292. break;
  293. if ( $count >= $start )
  294. echo "\t" . $this->single_row( $page, $level );
  295. $count++;
  296. if ( isset( $children_pages ) )
  297. $this->_page_rows( $children_pages, $count, $page->ID, $level + 1, $pagenum, $per_page );
  298. }
  299. // if it is the last pagenum and there are orphaned pages, display them with paging as well
  300. if ( isset( $children_pages ) && $count < $end ){
  301. foreach ( $children_pages as $orphans ){
  302. foreach ( $orphans as $op ) {
  303. if ( $count >= $end )
  304. break;
  305. if ( $count >= $start )
  306. echo "\t" . $this->single_row( $op, 0 );
  307. $count++;
  308. }
  309. }
  310. }
  311. }
  312. /**
  313. * Given a top level page ID, display the nested hierarchy of sub-pages
  314. * together with paging support
  315. *
  316. * @since 3.1.0 (Standalone function exists since 2.6.0)
  317. *
  318. * @param unknown_type $children_pages
  319. * @param unknown_type $count
  320. * @param unknown_type $parent
  321. * @param unknown_type $level
  322. * @param unknown_type $pagenum
  323. * @param unknown_type $per_page
  324. */
  325. function _page_rows( &$children_pages, &$count, $parent, $level, $pagenum, $per_page ) {
  326. if ( ! isset( $children_pages[$parent] ) )
  327. return;
  328. $start = ( $pagenum - 1 ) * $per_page;
  329. $end = $start + $per_page;
  330. foreach ( $children_pages[$parent] as $page ) {
  331. if ( $count >= $end )
  332. break;
  333. // If the page starts in a subtree, print the parents.
  334. if ( $count == $start && $page->post_parent > 0 ) {
  335. $my_parents = array();
  336. $my_parent = $page->post_parent;
  337. while ( $my_parent ) {
  338. $my_parent = get_post( $my_parent );
  339. $my_parents[] = $my_parent;
  340. if ( !$my_parent->post_parent )
  341. break;
  342. $my_parent = $my_parent->post_parent;
  343. }
  344. $num_parents = count( $my_parents );
  345. while ( $my_parent = array_pop( $my_parents ) ) {
  346. echo "\t" . $this->single_row( $my_parent, $level - $num_parents );
  347. $num_parents--;
  348. }
  349. }
  350. if ( $count >= $start )
  351. echo "\t" . $this->single_row( $page, $level );
  352. $count++;
  353. $this->_page_rows( $children_pages, $count, $page->ID, $level + 1, $pagenum, $per_page );
  354. }
  355. unset( $children_pages[$parent] ); //required in order to keep track of orphans
  356. }
  357. function single_row( $post, $level = 0 ) {
  358. global $mode;
  359. static $alternate;
  360. $global_post = get_post();
  361. $GLOBALS['post'] = $post;
  362. setup_postdata( $post );
  363. $edit_link = get_edit_post_link( $post->ID );
  364. $title = _draft_or_post_title();
  365. $post_type_object = get_post_type_object( $post->post_type );
  366. $can_edit_post = current_user_can( $post_type_object->cap->edit_post, $post->ID );
  367. $alternate = 'alternate' == $alternate ? '' : 'alternate';
  368. $classes = $alternate . ' iedit author-' . ( get_current_user_id() == $post->post_author ? 'self' : 'other' );
  369. ?>
  370. <tr id="post-<?php echo $post->ID; ?>" class="<?php echo implode( ' ', get_post_class( $classes, $post->ID ) ); ?>" valign="top">
  371. <?php
  372. list( $columns, $hidden ) = $this->get_column_info();
  373. foreach ( $columns as $column_name => $column_display_name ) {
  374. $class = "class=\"$column_name column-$column_name\"";
  375. $style = '';
  376. if ( in_array( $column_name, $hidden ) )
  377. $style = ' style="display:none;"';
  378. $attributes = "$class$style";
  379. switch ( $column_name ) {
  380. case 'cb':
  381. ?>
  382. <th scope="row" class="check-column">
  383. <?php if ( $can_edit_post ) { ?>
  384. <label class="screen-reader-text" for="cb-select-<?php the_ID(); ?>"><?php printf( __( 'Select %s' ), $title ); ?></label>
  385. <input id="cb-select-<?php the_ID(); ?>" type="checkbox" name="post[]" value="<?php the_ID(); ?>" />
  386. <?php } ?>
  387. </th>
  388. <?php
  389. break;
  390. case 'title':
  391. if ( $this->hierarchical_display ) {
  392. $attributes = 'class="post-title page-title column-title"' . $style;
  393. if ( 0 == $level && (int) $post->post_parent > 0 ) {
  394. //sent level 0 by accident, by default, or because we don't know the actual level
  395. $find_main_page = (int) $post->post_parent;
  396. while ( $find_main_page > 0 ) {
  397. $parent = get_post( $find_main_page );
  398. if ( is_null( $parent ) )
  399. break;
  400. $level++;
  401. $find_main_page = (int) $parent->post_parent;
  402. if ( !isset( $parent_name ) )
  403. $parent_name = apply_filters( 'the_title', $parent->post_title, $parent->ID );
  404. }
  405. }
  406. $pad = str_repeat( '&#8212; ', $level );
  407. ?>
  408. <td <?php echo $attributes ?>><strong><?php if ( $can_edit_post && $post->post_status != 'trash' ) { ?><a class="row-title" href="<?php echo $edit_link; ?>" title="<?php echo esc_attr( sprintf( __( 'Edit &#8220;%s&#8221;' ), $title ) ); ?>"><?php echo $pad; echo $title ?></a><?php } else { echo $pad; echo $title; }; _post_states( $post ); echo isset( $parent_name ) ? ' | ' . $post_type_object->labels->parent_item_colon . ' ' . esc_html( $parent_name ) : ''; ?></strong>
  409. <?php
  410. }
  411. else {
  412. $attributes = 'class="post-title page-title column-title"' . $style;
  413. $pad = str_repeat( '&#8212; ', $level );
  414. ?>
  415. <td <?php echo $attributes ?>><strong><?php if ( $can_edit_post && $post->post_status != 'trash' ) { ?><a class="row-title" href="<?php echo $edit_link; ?>" title="<?php echo esc_attr( sprintf( __( 'Edit &#8220;%s&#8221;' ), $title ) ); ?>"><?php echo $pad; echo $title ?></a><?php } else { echo $pad; echo $title; }; _post_states( $post ); ?></strong>
  416. <?php
  417. if ( 'excerpt' == $mode && current_user_can( 'read_post', $post->ID ) )
  418. the_excerpt();
  419. }
  420. $actions = array();
  421. if ( $can_edit_post && 'trash' != $post->post_status ) {
  422. $actions['edit'] = '<a href="' . get_edit_post_link( $post->ID, true ) . '" title="' . esc_attr( __( 'Edit this item' ) ) . '">' . __( 'Edit' ) . '</a>';
  423. $actions['inline hide-if-no-js'] = '<a href="#" class="editinline" title="' . esc_attr( __( 'Edit this item inline' ) ) . '">' . __( 'Quick&nbsp;Edit' ) . '</a>';
  424. }
  425. if ( current_user_can( $post_type_object->cap->delete_post, $post->ID ) ) {
  426. if ( 'trash' == $post->post_status )
  427. $actions['untrash'] = "<a title='" . esc_attr( __( 'Restore this item from the Trash' ) ) . "' href='" . wp_nonce_url( admin_url( sprintf( $post_type_object->_edit_link . '&amp;action=untrash', $post->ID ) ), 'untrash-post_' . $post->ID ) . "'>" . __( 'Restore' ) . "</a>";
  428. elseif ( EMPTY_TRASH_DAYS )
  429. $actions['trash'] = "<a class='submitdelete' title='" . esc_attr( __( 'Move this item to the Trash' ) ) . "' href='" . get_delete_post_link( $post->ID ) . "'>" . __( 'Trash' ) . "</a>";
  430. if ( 'trash' == $post->post_status || !EMPTY_TRASH_DAYS )
  431. $actions['delete'] = "<a class='submitdelete' title='" . esc_attr( __( 'Delete this item permanently' ) ) . "' href='" . get_delete_post_link( $post->ID, '', true ) . "'>" . __( 'Delete Permanently' ) . "</a>";
  432. }
  433. if ( $post_type_object->public ) {
  434. if ( in_array( $post->post_status, array( 'pending', 'draft', 'future' ) ) ) {
  435. if ( $can_edit_post )
  436. $actions['view'] = '<a href="' . esc_url( add_query_arg( 'preview', 'true', get_permalink( $post->ID ) ) ) . '" title="' . esc_attr( sprintf( __( 'Preview &#8220;%s&#8221;' ), $title ) ) . '" rel="permalink">' . __( 'Preview' ) . '</a>';
  437. } elseif ( 'trash' != $post->post_status ) {
  438. $actions['view'] = '<a href="' . get_permalink( $post->ID ) . '" title="' . esc_attr( sprintf( __( 'View &#8220;%s&#8221;' ), $title ) ) . '" rel="permalink">' . __( 'View' ) . '</a>';
  439. }
  440. }
  441. $actions = apply_filters( is_post_type_hierarchical( $post->post_type ) ? 'page_row_actions' : 'post_row_actions', $actions, $post );
  442. echo $this->row_actions( $actions );
  443. get_inline_data( $post );
  444. echo '</td>';
  445. break;
  446. case 'date':
  447. if ( '0000-00-00 00:00:00' == $post->post_date ) {
  448. $t_time = $h_time = __( 'Unpublished' );
  449. $time_diff = 0;
  450. } else {
  451. $t_time = get_the_time( __( 'Y/m/d g:i:s A' ) );
  452. $m_time = $post->post_date;
  453. $time = get_post_time( 'G', true, $post );
  454. $time_diff = time() - $time;
  455. if ( $time_diff > 0 && $time_diff < DAY_IN_SECONDS )
  456. $h_time = sprintf( __( '%s ago' ), human_time_diff( $time ) );
  457. else
  458. $h_time = mysql2date( __( 'Y/m/d' ), $m_time );
  459. }
  460. echo '<td ' . $attributes . '>';
  461. if ( 'excerpt' == $mode )
  462. echo apply_filters( 'post_date_column_time', $t_time, $post, $column_name, $mode );
  463. else
  464. echo '<abbr title="' . $t_time . '">' . apply_filters( 'post_date_column_time', $h_time, $post, $column_name, $mode ) . '</abbr>';
  465. echo '<br />';
  466. if ( 'publish' == $post->post_status ) {
  467. _e( 'Published' );
  468. } elseif ( 'future' == $post->post_status ) {
  469. if ( $time_diff > 0 )
  470. echo '<strong class="attention">' . __( 'Missed schedule' ) . '</strong>';
  471. else
  472. _e( 'Scheduled' );
  473. } else {
  474. _e( 'Last Modified' );
  475. }
  476. echo '</td>';
  477. break;
  478. case 'comments':
  479. ?>
  480. <td <?php echo $attributes ?>><div class="post-com-count-wrapper">
  481. <?php
  482. $pending_comments = isset( $this->comment_pending_count[$post->ID] ) ? $this->comment_pending_count[$post->ID] : 0;
  483. $this->comments_bubble( $post->ID, $pending_comments );
  484. ?>
  485. </div></td>
  486. <?php
  487. break;
  488. case 'author':
  489. ?>
  490. <td <?php echo $attributes ?>><?php
  491. printf( '<a href="%s">%s</a>',
  492. esc_url( add_query_arg( array( 'post_type' => $post->post_type, 'author' => get_the_author_meta( 'ID' ) ), 'edit.php' )),
  493. get_the_author()
  494. );
  495. ?></td>
  496. <?php
  497. break;
  498. default:
  499. if ( 'categories' == $column_name )
  500. $taxonomy = 'category';
  501. elseif ( 'tags' == $column_name )
  502. $taxonomy = 'post_tag';
  503. elseif ( 0 === strpos( $column_name, 'taxonomy-' ) )
  504. $taxonomy = substr( $column_name, 9 );
  505. else
  506. $taxonomy = false;
  507. if ( $taxonomy ) {
  508. $taxonomy_object = get_taxonomy( $taxonomy );
  509. echo '<td ' . $attributes . '>';
  510. if ( $terms = get_the_terms( $post->ID, $taxonomy ) ) {
  511. $out = array();
  512. foreach ( $terms as $t ) {
  513. $posts_in_term_qv = array();
  514. if ( 'post' != $post->post_type )
  515. $posts_in_term_qv['post_type'] = $post->post_type;
  516. if ( $taxonomy_object->query_var ) {
  517. $posts_in_term_qv[ $taxonomy_object->query_var ] = $t->slug;
  518. } else {
  519. $posts_in_term_qv['taxonomy'] = $taxonomy;
  520. $posts_in_term_qv['term'] = $t->slug;
  521. }
  522. $out[] = sprintf( '<a href="%s">%s</a>',
  523. esc_url( add_query_arg( $posts_in_term_qv, 'edit.php' ) ),
  524. esc_html( sanitize_term_field( 'name', $t->name, $t->term_id, $taxonomy, 'display' ) )
  525. );
  526. }
  527. /* translators: used between list items, there is a space after the comma */
  528. echo join( __( ', ' ), $out );
  529. } else {
  530. echo '&#8212;';
  531. }
  532. echo '</td>';
  533. break;
  534. }
  535. ?>
  536. <td <?php echo $attributes ?>><?php
  537. if ( is_post_type_hierarchical( $post->post_type ) )
  538. do_action( 'manage_pages_custom_column', $column_name, $post->ID );
  539. else
  540. do_action( 'manage_posts_custom_column', $column_name, $post->ID );
  541. do_action( "manage_{$post->post_type}_posts_custom_column", $column_name, $post->ID );
  542. ?></td>
  543. <?php
  544. break;
  545. }
  546. }
  547. ?>
  548. </tr>
  549. <?php
  550. $GLOBALS['post'] = $global_post;
  551. }
  552. /**
  553. * Outputs the hidden row displayed when inline editing
  554. *
  555. * @since 3.1.0
  556. */
  557. function inline_edit() {
  558. global $mode;
  559. $screen = $this->screen;
  560. $post = get_default_post_to_edit( $screen->post_type );
  561. $post_type_object = get_post_type_object( $screen->post_type );
  562. $taxonomy_names = get_object_taxonomies( $screen->post_type );
  563. $hierarchical_taxonomies = array();
  564. $flat_taxonomies = array();
  565. foreach ( $taxonomy_names as $taxonomy_name ) {
  566. $taxonomy = get_taxonomy( $taxonomy_name );
  567. if ( !$taxonomy->show_ui )
  568. continue;
  569. if ( $taxonomy->hierarchical )
  570. $hierarchical_taxonomies[] = $taxonomy;
  571. else
  572. $flat_taxonomies[] = $taxonomy;
  573. }
  574. $m = ( isset( $mode ) && 'excerpt' == $mode ) ? 'excerpt' : 'list';
  575. $can_publish = current_user_can( $post_type_object->cap->publish_posts );
  576. $core_columns = array( 'cb' => true, 'date' => true, 'title' => true, 'categories' => true, 'tags' => true, 'comments' => true, 'author' => true );
  577. ?>
  578. <form method="get" action=""><table style="display: none"><tbody id="inlineedit">
  579. <?php
  580. $hclass = count( $hierarchical_taxonomies ) ? 'post' : 'page';
  581. $bulk = 0;
  582. while ( $bulk < 2 ) { ?>
  583. <tr id="<?php echo $bulk ? 'bulk-edit' : 'inline-edit'; ?>" class="inline-edit-row inline-edit-row-<?php echo "$hclass inline-edit-" . $screen->post_type;
  584. echo $bulk ? " bulk-edit-row bulk-edit-row-$hclass bulk-edit-{$screen->post_type}" : " quick-edit-row quick-edit-row-$hclass inline-edit-{$screen->post_type}";
  585. ?>" style="display: none"><td colspan="<?php echo $this->get_column_count(); ?>" class="colspanchange">
  586. <fieldset class="inline-edit-col-left"><div class="inline-edit-col">
  587. <h4><?php echo $bulk ? __( 'Bulk Edit' ) : __( 'Quick Edit' ); ?></h4>
  588. <?php
  589. if ( post_type_supports( $screen->post_type, 'title' ) ) :
  590. if ( $bulk ) : ?>
  591. <div id="bulk-title-div">
  592. <div id="bulk-titles"></div>
  593. </div>
  594. <?php else : // $bulk ?>
  595. <label>
  596. <span class="title"><?php _e( 'Title' ); ?></span>
  597. <span class="input-text-wrap"><input type="text" name="post_title" class="ptitle" value="" /></span>
  598. </label>
  599. <label>
  600. <span class="title"><?php _e( 'Slug' ); ?></span>
  601. <span class="input-text-wrap"><input type="text" name="post_name" value="" /></span>
  602. </label>
  603. <?php endif; // $bulk
  604. endif; // post_type_supports title ?>
  605. <?php if ( !$bulk ) : ?>
  606. <label><span class="title"><?php _e( 'Date' ); ?></span></label>
  607. <div class="inline-edit-date">
  608. <?php touch_time( 1, 1, 0, 1 ); ?>
  609. </div>
  610. <br class="clear" />
  611. <?php endif; // $bulk
  612. if ( post_type_supports( $screen->post_type, 'author' ) ) :
  613. $authors_dropdown = '';
  614. if ( is_super_admin() || current_user_can( $post_type_object->cap->edit_others_posts ) ) :
  615. $users_opt = array(
  616. 'hide_if_only_one_author' => false,
  617. 'who' => 'authors',
  618. 'name' => 'post_author',
  619. 'class'=> 'authors',
  620. 'multi' => 1,
  621. 'echo' => 0
  622. );
  623. if ( $bulk )
  624. $users_opt['show_option_none'] = __( '&mdash; No Change &mdash;' );
  625. if ( $authors = wp_dropdown_users( $users_opt ) ) :
  626. $authors_dropdown = '<label class="inline-edit-author">';
  627. $authors_dropdown .= '<span class="title">' . __( 'Author' ) . '</span>';
  628. $authors_dropdown .= $authors;
  629. $authors_dropdown .= '</label>';
  630. endif;
  631. endif; // authors
  632. ?>
  633. <?php if ( !$bulk ) echo $authors_dropdown;
  634. endif; // post_type_supports author
  635. if ( !$bulk ) :
  636. ?>
  637. <div class="inline-edit-group">
  638. <label class="alignleft">
  639. <span class="title"><?php _e( 'Password' ); ?></span>
  640. <span class="input-text-wrap"><input type="text" name="post_password" class="inline-edit-password-input" value="" /></span>
  641. </label>
  642. <em style="margin:5px 10px 0 0" class="alignleft">
  643. <?php
  644. /* translators: Between password field and private checkbox on post quick edit interface */
  645. echo __( '&ndash;OR&ndash;' );
  646. ?>
  647. </em>
  648. <label class="alignleft inline-edit-private">
  649. <input type="checkbox" name="keep_private" value="private" />
  650. <span class="checkbox-title"><?php echo __( 'Private' ); ?></span>
  651. </label>
  652. </div>
  653. <?php endif; ?>
  654. </div></fieldset>
  655. <?php if ( count( $hierarchical_taxonomies ) && !$bulk ) : ?>
  656. <fieldset class="inline-edit-col-center inline-edit-categories"><div class="inline-edit-col">
  657. <?php foreach ( $hierarchical_taxonomies as $taxonomy ) : ?>
  658. <span class="title inline-edit-categories-label"><?php echo esc_html( $taxonomy->labels->name ) ?>
  659. <span class="catshow"><?php _e( '[more]' ); ?></span>
  660. <span class="cathide" style="display:none;"><?php _e( '[less]' ); ?></span>
  661. </span>
  662. <input type="hidden" name="<?php echo ( $taxonomy->name == 'category' ) ? 'post_category[]' : 'tax_input[' . esc_attr( $taxonomy->name ) . '][]'; ?>" value="0" />
  663. <ul class="cat-checklist <?php echo esc_attr( $taxonomy->name )?>-checklist">
  664. <?php wp_terms_checklist( null, array( 'taxonomy' => $taxonomy->name ) ) ?>
  665. </ul>
  666. <?php endforeach; //$hierarchical_taxonomies as $taxonomy ?>
  667. </div></fieldset>
  668. <?php endif; // count( $hierarchical_taxonomies ) && !$bulk ?>
  669. <fieldset class="inline-edit-col-right"><div class="inline-edit-col">
  670. <?php
  671. if ( post_type_supports( $screen->post_type, 'author' ) && $bulk )
  672. echo $authors_dropdown;
  673. if ( post_type_supports( $screen->post_type, 'page-attributes' ) ) :
  674. if ( $post_type_object->hierarchical ) :
  675. ?>
  676. <label>
  677. <span class="title"><?php _e( 'Parent' ); ?></span>
  678. <?php
  679. $dropdown_args = array(
  680. 'post_type' => $post_type_object->name,
  681. 'selected' => $post->post_parent,
  682. 'name' => 'post_parent',
  683. 'show_option_none' => __( 'Main Page (no parent)' ),
  684. 'option_none_value' => 0,
  685. 'sort_column' => 'menu_order, post_title',
  686. );
  687. if ( $bulk )
  688. $dropdown_args['show_option_no_change'] = __( '&mdash; No Change &mdash;' );
  689. $dropdown_args = apply_filters( 'quick_edit_dropdown_pages_args', $dropdown_args );
  690. wp_dropdown_pages( $dropdown_args );
  691. ?>
  692. </label>
  693. <?php
  694. endif; // hierarchical
  695. if ( !$bulk ) : ?>
  696. <label>
  697. <span class="title"><?php _e( 'Order' ); ?></span>
  698. <span class="input-text-wrap"><input type="text" name="menu_order" class="inline-edit-menu-order-input" value="<?php echo $post->menu_order ?>" /></span>
  699. </label>
  700. <?php endif; // !$bulk
  701. if ( 'page' == $screen->post_type ) :
  702. ?>
  703. <label>
  704. <span class="title"><?php _e( 'Template' ); ?></span>
  705. <select name="page_template">
  706. <?php if ( $bulk ) : ?>
  707. <option value="-1"><?php _e( '&mdash; No Change &mdash;' ); ?></option>
  708. <?php endif; // $bulk ?>
  709. <option value="default"><?php _e( 'Default Template' ); ?></option>
  710. <?php page_template_dropdown() ?>
  711. </select>
  712. </label>
  713. <?php
  714. endif; // page post_type
  715. endif; // page-attributes
  716. ?>
  717. <?php if ( count( $flat_taxonomies ) && !$bulk ) : ?>
  718. <?php foreach ( $flat_taxonomies as $taxonomy ) : ?>
  719. <?php if ( current_user_can( $taxonomy->cap->assign_terms ) ) : ?>
  720. <label class="inline-edit-tags">
  721. <span class="title"><?php echo esc_html( $taxonomy->labels->name ) ?></span>
  722. <textarea cols="22" rows="1" name="tax_input[<?php echo esc_attr( $taxonomy->name )?>]" class="tax_input_<?php echo esc_attr( $taxonomy->name )?>"></textarea>
  723. </label>
  724. <?php endif; ?>
  725. <?php endforeach; //$flat_taxonomies as $taxonomy ?>
  726. <?php endif; // count( $flat_taxonomies ) && !$bulk ?>
  727. <?php if ( post_type_supports( $screen->post_type, 'comments' ) || post_type_supports( $screen->post_type, 'trackbacks' ) ) :
  728. if ( $bulk ) : ?>
  729. <div class="inline-edit-group">
  730. <?php if ( post_type_supports( $screen->post_type, 'comments' ) ) : ?>
  731. <label class="alignleft">
  732. <span class="title"><?php _e( 'Comments' ); ?></span>
  733. <select name="comment_status">
  734. <option value=""><?php _e( '&mdash; No Change &mdash;' ); ?></option>
  735. <option value="open"><?php _e( 'Allow' ); ?></option>
  736. <option value="closed"><?php _e( 'Do not allow' ); ?></option>
  737. </select>
  738. </label>
  739. <?php endif; if ( post_type_supports( $screen->post_type, 'trackbacks' ) ) : ?>
  740. <label class="alignright">
  741. <span class="title"><?php _e( 'Pings' ); ?></span>
  742. <select name="ping_status">
  743. <option value=""><?php _e( '&mdash; No Change &mdash;' ); ?></option>
  744. <option value="open"><?php _e( 'Allow' ); ?></option>
  745. <option value="closed"><?php _e( 'Do not allow' ); ?></option>
  746. </select>
  747. </label>
  748. <?php endif; ?>
  749. </div>
  750. <?php else : // $bulk ?>
  751. <div class="inline-edit-group">
  752. <?php if ( post_type_supports( $screen->post_type, 'comments' ) ) : ?>
  753. <label class="alignleft">
  754. <input type="checkbox" name="comment_status" value="open" />
  755. <span class="checkbox-title"><?php _e( 'Allow Comments' ); ?></span>
  756. </label>
  757. <?php endif; if ( post_type_supports( $screen->post_type, 'trackbacks' ) ) : ?>
  758. <label class="alignleft">
  759. <input type="checkbox" name="ping_status" value="open" />
  760. <span class="checkbox-title"><?php _e( 'Allow Pings' ); ?></span>
  761. </label>
  762. <?php endif; ?>
  763. </div>
  764. <?php endif; // $bulk
  765. endif; // post_type_supports comments or pings ?>
  766. <div class="inline-edit-group">
  767. <label class="inline-edit-status alignleft">
  768. <span class="title"><?php _e( 'Status' ); ?></span>
  769. <select name="_status">
  770. <?php if ( $bulk ) : ?>
  771. <option value="-1"><?php _e( '&mdash; No Change &mdash;' ); ?></option>
  772. <?php endif; // $bulk ?>
  773. <?php if ( $can_publish ) : // Contributors only get "Unpublished" and "Pending Review" ?>
  774. <option value="publish"><?php _e( 'Published' ); ?></option>
  775. <option value="future"><?php _e( 'Scheduled' ); ?></option>
  776. <?php if ( $bulk ) : ?>
  777. <option value="private"><?php _e( 'Private' ) ?></option>
  778. <?php endif; // $bulk ?>
  779. <?php endif; ?>
  780. <option value="pending"><?php _e( 'Pending Review' ); ?></option>
  781. <option value="draft"><?php _e( 'Draft' ); ?></option>
  782. </select>
  783. </label>
  784. <?php if ( 'post' == $screen->post_type && $can_publish && current_user_can( $post_type_object->cap->edit_others_posts ) ) : ?>
  785. <?php if ( $bulk ) : ?>
  786. <label class="alignright">
  787. <span class="title"><?php _e( 'Sticky' ); ?></span>
  788. <select name="sticky">
  789. <option value="-1"><?php _e( '&mdash; No Change &mdash;' ); ?></option>
  790. <option value="sticky"><?php _e( 'Sticky' ); ?></option>
  791. <option value="unsticky"><?php _e( 'Not Sticky' ); ?></option>
  792. </select>
  793. </label>
  794. <?php else : // $bulk ?>
  795. <label class="alignleft">
  796. <input type="checkbox" name="sticky" value="sticky" />
  797. <span class="checkbox-title"><?php _e( 'Make this post sticky' ); ?></span>
  798. </label>
  799. <?php endif; // $bulk ?>
  800. <?php endif; // 'post' && $can_publish && current_user_can( 'edit_others_cap' ) ?>
  801. </div>
  802. <?php if ( post_type_supports( $screen->post_type, 'post-formats' ) && current_theme_supports( 'post-formats' ) ) :
  803. $post_formats = get_theme_support( 'post-formats' );
  804. if ( isset( $post_formats[0] ) && is_array( $post_formats[0] ) ) :
  805. $all_post_formats = get_post_format_strings();
  806. unset( $all_post_formats['standard'] ); ?>
  807. <div class="inline-edit-group">
  808. <label class="alignleft" for="post_format">
  809. <span class="title"><?php _ex( 'Format', 'post format' ); ?></span>
  810. <select name="post_format">
  811. <?php if ( $bulk ) : ?>
  812. <option value="-1"><?php _e( '&mdash; No Change &mdash;' ); ?></option>
  813. <?php endif; ?>
  814. <option value="0"><?php _ex( 'Standard', 'Post format' ); ?></option>
  815. <?php foreach ( $all_post_formats as $slug => $format ) :
  816. $unsupported = ! in_array( $slug, $post_formats[0] );
  817. if ( $bulk && $unsupported )
  818. continue;
  819. ?>
  820. <option value="<?php echo esc_attr( $slug ); ?>"<?php if ( $unsupported ) echo ' class="unsupported"'; ?>><?php echo esc_html( $format ); ?></option>
  821. <?php endforeach; ?>
  822. </select></label>
  823. </div>
  824. <?php endif; ?>
  825. <?php endif; // post-formats ?>
  826. </div></fieldset>
  827. <?php
  828. list( $columns ) = $this->get_column_info();
  829. foreach ( $columns as $column_name => $column_display_name ) {
  830. if ( isset( $core_columns[$column_name] ) )
  831. continue;
  832. do_action( $bulk ? 'bulk_edit_custom_box' : 'quick_edit_custom_box', $column_name, $screen->post_type );
  833. }
  834. ?>
  835. <p class="submit inline-edit-save">
  836. <a accesskey="c" href="#inline-edit" title="<?php esc_attr_e( 'Cancel' ); ?>" class="button-secondary cancel alignleft"><?php _e( 'Cancel' ); ?></a>
  837. <?php if ( ! $bulk ) {
  838. wp_nonce_field( 'inlineeditnonce', '_inline_edit', false );
  839. $update_text = __( 'Update' );
  840. ?>
  841. <a accesskey="s" href="#inline-edit" title="<?php esc_attr_e( 'Update' ); ?>" class="button-primary save alignright"><?php echo esc_attr( $update_text ); ?></a>
  842. <span class="spinner"></span>
  843. <?php } else {
  844. submit_button( __( 'Update' ), 'button-primary alignright', 'bulk_edit', false, array( 'accesskey' => 's' ) );
  845. } ?>
  846. <input type="hidden" name="post_view" value="<?php echo esc_attr( $m ); ?>" />
  847. <input type="hidden" name="screen" value="<?php echo esc_attr( $screen->id ); ?>" />
  848. <span class="error" style="display:none"></span>
  849. <br class="clear" />
  850. </p>
  851. </td></tr>
  852. <?php
  853. $bulk++;
  854. }
  855. ?>
  856. </tbody></table></form>
  857. <?php
  858. }
  859. }