PluginProbe
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot / 2.0.14
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot v2.0.14
4.9.1 4.9.0 4.8.2 4.8.1 4.8.0 4.7.0 4.6.2 4.6.1 4.6.0 4.5.6 4.5.5 4.5.4 4.5.3 4.5.2 4.5.1 4.5.0 4.4.1 4.4.0 3.3.4 3.4.0 3.4.1 3.4.2 3.5.0 3.5.1 3.5.2 All 199 releases
betterdocs / admin / partials / class-betterdocs-list-table.php

class-betterdocs-list-table.php in BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot 2.0.14, at admin/partials/class-betterdocs-list-table.php

420 lines 15.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 if(!class_exists('WP_List_Table')){
3 require_once( ABSPATH . 'wp-admin/includes/class-wp-list-table.php' );
4 }
5 if(!class_exists('WP_Posts_List_Table')){
6 require_once( ABSPATH . 'wp-admin/includes/class-wp-posts-list-table.php' );
7 }
8 class BetterDocs_WP_Posts_List_Table extends WP_Posts_List_Table {
9
10 public function __construct($args = array()) {
11 parent::__construct($args);
12 $screen = get_current_screen();
13 $this->screen = convert_to_screen($screen);
14 }
15
16 public function docs_wp_query($per_page) {
17 $paged = isset( $_REQUEST['paged'] ) ? $_REQUEST['paged'] : 1;
18 $args = array(
19 'post_type' => 'docs',
20 'posts_per_page' => $per_page,
21 'orderby' => 'date',
22 'paged' => $paged
23 );
24
25 if ( isset( $_GET['s'] ) && strlen( $_GET['s'] ) ) {
26 $args['s'] = $_GET['s'];
27 }
28
29 if ( isset( $_GET['order'] ) && $_GET['order'] === 'ASC') {
30 $args['order'] = 'ASC';
31 } else {
32 $args['order'] = 'DESC';
33 }
34
35 if ( isset( $_GET['author'] ) && $_GET['author'] != 'all' ) {
36 $args['author'] = $_GET['author'];
37 }
38
39 if ( isset( $_GET['post_status'] ) ) {
40 $args['post_status'] = $_GET['post_status'];
41 }
42
43 if ( isset( $_GET['view'] ) && !empty( $_GET['view'] ) ) {
44 $args['meta_key'] = '_betterdocs_meta_views';
45 $args['orderby'] = 'meta_value_num';
46 if ( $_GET['view'] === 'most_viewed') {
47 $args['order'] = 'DESC';
48 } else if ( $_GET['view'] === 'least_viewed') {
49 $args['order'] = 'ASC';
50 }
51
52 }
53
54 if ( isset( $_GET['date'] ) && !empty($_GET['date']) ) {
55 $args['orderby'] = $_GET['date'];
56 if ( $_GET['date'] === 'most_recent') {
57 $args['order'] = 'DESC';
58 } else if ( $_GET['date'] === 'least_recent') {
59 $args['order'] = 'ASC';
60 } else if ( $_GET['date'] === 'custom_date') {
61 $after = $before = '';
62 $date_range = explode('-',$_GET['date_range']);
63
64 if ( is_array( $date_range ) && array_key_exists( 0, $date_range ) ) {
65 $after = rtrim($date_range[0]);
66 }
67
68 if ( is_array( $date_range ) && array_key_exists( 1, $date_range ) ) {
69 $before = ltrim($date_range[1]);
70 }
71
72 $start_date = new DateTime($after);
73 $end_date = new DateTime($before);
74
75 if ($after === $before) {
76 $start_date = $start_date->format('Ymd');
77 $args['date_query'] = array(
78 array(
79 'year' => substr($start_date, 0, 4),
80 'month' => substr($start_date, 4, 2),
81 'day' => substr($start_date, 6, 2),
82 ),
83 );
84 } else {
85 $start_date = $start_date->modify('-1 day');
86 $end_date = $end_date->modify('+1 day');
87 $args['date_query'] = array(
88 array(
89 'after' => $start_date->format('M d, Y'),
90 'before' => $end_date->format('M d, Y'),
91 'inclusive' => true,
92 ),
93 );
94 }
95
96 }
97 }
98
99 $args['tax_query'] = array(
100 'relation' => 'AND'
101 );
102
103 if ( isset( $_GET['doc_category'] ) && ! empty( $_GET['doc_category']) && ( $_GET['doc_category'] != 'all') ) {
104 $args['tax_query'][] = array(
105 'taxonomy' => 'doc_category',
106 'field' => 'slug',
107 'operator' => 'IN',
108 'terms' => array($_GET['doc_category']),
109 'include_children' => true,
110 );
111 }
112
113 if ( isset( $_GET['knowledgebase'] ) && ! empty( $_GET['knowledgebase']) && ( $_GET['knowledgebase'] != 'all' ) ) {
114 $args['tax_query'][] = array(
115 'taxonomy' => 'knowledge_base',
116 'field' => 'slug',
117 'terms' => array($_GET['knowledgebase']),
118 'operator' => 'IN',
119 'include_children' => true,
120 );
121 }
122
123
124
125 return new WP_Query($args);
126 }
127 /**
128 * @global string $mode List table view mode.
129 * @global array $avail_post_stati
130 * @global WP_Query $wp_query WordPress Query object.
131 * @global int $per_page
132 */
133 public function prepare_items() {
134 global $mode, $avail_post_stati, $wp_query, $per_page;
135 $wp_query = $this->docs_wp_query($per_page);
136 if ( ! empty( $_REQUEST['mode'] ) ) {
137 $mode = 'excerpt' === $_REQUEST['mode'] ? 'excerpt' : 'list';
138 set_user_setting( 'posts_list_mode', $mode );
139 } else {
140 $mode = get_user_setting( 'posts_list_mode', 'list' );
141 }
142
143 // Is going to call wp().
144 $avail_post_stati = wp_edit_posts_query();
145
146 $this->set_hierarchical_display( is_post_type_hierarchical( $this->screen->post_type ) && 'menu_order title' === $wp_query->query['orderby'] );
147
148 $post_type = $this->screen->post_type;
149 $per_page = $this->get_items_per_page( 'edit_' . $post_type . '_per_page' );
150
151 /** This filter is documented in wp-admin/includes/post.php */
152 $per_page = apply_filters( 'edit_posts_per_page', $per_page, $post_type );
153
154 if ( $this->hierarchical_display ) {
155 $total_items = $wp_query->post_count;
156 } elseif ( $wp_query->found_posts || $this->get_pagenum() === 1 ) {
157 $total_items = $wp_query->found_posts;
158 } else {
159 $post_counts = (array) wp_count_posts( $post_type, 'readable' );
160
161 if ( isset( $_REQUEST['post_status'] ) && in_array( $_REQUEST['post_status'], $avail_post_stati, true ) ) {
162 $total_items = $post_counts[ $_REQUEST['post_status'] ];
163 } elseif ( isset( $_REQUEST['show_sticky'] ) && $_REQUEST['show_sticky'] ) {
164 $total_items = $this->sticky_posts_count;
165 } elseif ( isset( $_GET['author'] ) && get_current_user_id() == $_GET['author'] ) {
166 $total_items = $this->user_posts_count;
167 } else {
168 $total_items = array_sum( $post_counts );
169
170 // Subtract post types that are not included in the admin all list.
171 foreach ( get_post_stati( array( 'show_in_admin_all_list' => false ) ) as $state ) {
172 $total_items -= $post_counts[ $state ];
173 }
174 }
175 }
176
177 $this->is_trash = isset( $_REQUEST['post_status'] ) && 'trash' === $_REQUEST['post_status'];
178
179 $this->set_pagination_args(
180 array(
181 'total_items' => $total_items,
182 'per_page' => $per_page,
183 )
184 );
185 }
186
187 /**
188 * Displays the table.
189 *
190 */
191 public function display() {
192 $singular = $this->_args['singular'];
193 $this->screen->render_screen_reader_content( 'heading_list' );
194 ?>
195 <table class="wp-list-table <?php echo implode( ' ', $this->get_table_classes() ); ?>">
196 <thead>
197 <tr>
198 <?php $this->print_column_headers(); ?>
199 </tr>
200 </thead>
201
202 <tbody id="the-list"
203 <?php
204 if ( $singular ) {
205 echo " data-wp-lists='list:$singular'";
206 }
207 ?>
208 >
209 <?php $this->display_rows_or_placeholder(); ?>
210 </tbody>
211
212 </table>
213 <?php
214 $this->display_tablenav( 'bottom' );
215 }
216
217 /**
218 * Generates the table navigation above or below the table
219 *
220 * @param string $which
221 */
222 protected function display_tablenav( $which ) {
223 if ( 'top' === $which ) {
224 wp_nonce_field( 'bulk-' . $this->_args['plural'] );
225 }
226 ?>
227 <div class="tablenav <?php echo esc_attr( $which ); ?>">
228 <?php
229 $this->extra_tablenav( $which );
230 $this->pagination( $which );
231 ?>
232 <br class="clear" />
233 </div>
234 <?php
235 }
236
237 /**
238 * @global WP_Query $wp_query WordPress Query object.
239 * @global int $per_page
240 * @param array $posts
241 * @param int $level
242 */
243 public function display_rows( $posts = array(), $level = 0 ) {
244 global $wp_query, $per_page;
245 $wp_query = $this->docs_wp_query($per_page);
246
247 $posts = $wp_query->posts;
248
249 add_filter( 'the_title', 'esc_html' );
250
251 if ( $this->hierarchical_display ) {
252 $this->_display_rows_hierarchical( $posts, $this->get_pagenum(), $per_page );
253 } else {
254 $this->_display_rows( $posts, $level );
255 }
256 }
257
258 /**
259 * @param array $posts
260 * @param int $level
261 */
262 private function _display_rows( $posts, $level = 0 ) {
263 $post_type = 'docs';
264
265 // Create array of post IDs.
266 $post_ids = array();
267
268 foreach ( $posts as $a_post ) {
269 $post_ids[] = $a_post->ID;
270 }
271
272 if ( post_type_supports( $post_type, 'comments' ) ) {
273 $this->comment_pending_count = get_pending_comments_num( $post_ids );
274 }
275
276 foreach ( $posts as $post ) {
277 $this->single_row( $post, $level );
278 }
279 }
280
281 /**
282 * @since 4.3.0
283 *
284 * @param WP_Post $post
285 */
286 public function custom_column_title( $post ) {
287 echo $this->column_title( $post );
288 }
289
290 /**
291 * Generates and displays row action links.
292 *
293 * @since 4.3.0
294 *
295 * @param WP_Post $post Post being acted upon.
296 * @return string Row actions output for posts, or an empty string
297 * if the current column is not the primary column.
298 */
299 public function custom_row_actions( $post ) {
300 $post_type_object = get_post_type_object( 'docs' );
301 $can_edit_post = current_user_can( 'edit_post', $post->ID );
302 $actions = array();
303 $title = _draft_or_post_title();
304
305 if ( $can_edit_post && 'trash' !== $post->post_status ) {
306 $actions['edit'] = sprintf(
307 '<a href="%s" aria-label="%s">%s</a>',
308 get_edit_post_link( $post->ID ),
309 /* translators: %s: Post title. */
310 esc_attr( sprintf( __( 'Edit &#8220;%s&#8221;' ), $title ) ),
311 __( 'Edit' )
312 );
313
314 if ( 'wp_block' !== $post->post_type ) {
315 $actions['inline hide-if-no-js'] = sprintf(
316 '<button type="button" class="button-link editinline" aria-label="%s" aria-expanded="false">%s</button>',
317 /* translators: %s: Post title. */
318 esc_attr( sprintf( __( 'Quick edit &#8220;%s&#8221; inline' ), $title ) ),
319 __( 'Quick&nbsp;Edit' )
320 );
321 }
322 }
323
324 if ( current_user_can( 'delete_post', $post->ID ) ) {
325 if ( 'trash' === $post->post_status ) {
326 $actions['untrash'] = sprintf(
327 '<a href="%s" aria-label="%s">%s</a>',
328 wp_nonce_url( admin_url( sprintf( $post_type_object->_edit_link . '&amp;action=untrash', $post->ID ) ), 'untrash-post_' . $post->ID ),
329 /* translators: %s: Post title. */
330 esc_attr( sprintf( __( 'Restore &#8220;%s&#8221; from the Trash' ), $title ) ),
331 __( 'Restore' )
332 );
333 } elseif ( EMPTY_TRASH_DAYS ) {
334 $actions['trash'] = sprintf(
335 '<a href="%s" class="submitdelete" aria-label="%s">%s</a>',
336 get_delete_post_link( $post->ID ),
337 /* translators: %s: Post title. */
338 esc_attr( sprintf( __( 'Move &#8220;%s&#8221; to the Trash' ), $title ) ),
339 _x( 'Trash', 'verb' )
340 );
341 }
342 if ( 'trash' === $post->post_status || ! EMPTY_TRASH_DAYS ) {
343 $actions['delete'] = sprintf(
344 '<a href="%s" class="submitdelete" aria-label="%s">%s</a>',
345 get_delete_post_link( $post->ID, '', true ),
346 /* translators: %s: Post title. */
347 esc_attr( sprintf( __( 'Delete &#8220;%s&#8221; permanently' ), $title ) ),
348 __( 'Delete Permanently' )
349 );
350 }
351 }
352
353 if ( is_post_type_viewable( $post_type_object ) ) {
354 if ( in_array( $post->post_status, array( 'pending', 'draft', 'future' ), true ) ) {
355 if ( $can_edit_post ) {
356 $preview_link = get_preview_post_link( $post );
357 $actions['view'] = sprintf(
358 '<a href="%s" rel="bookmark" aria-label="%s">%s</a>',
359 esc_url( $preview_link ),
360 /* translators: %s: Post title. */
361 esc_attr( sprintf( __( 'Preview &#8220;%s&#8221;' ), $title ) ),
362 __( 'Preview' )
363 );
364 }
365 } elseif ( 'trash' !== $post->post_status ) {
366 $actions['view'] = sprintf(
367 '<a href="%s" rel="bookmark" aria-label="%s">%s</a>',
368 get_permalink( $post->ID ),
369 /* translators: %s: Post title. */
370 esc_attr( sprintf( __( 'View &#8220;%s&#8221;' ), $title ) ),
371 __( 'View' )
372 );
373 }
374 }
375
376 if ( 'wp_block' === $post->post_type ) {
377 $actions['export'] = sprintf(
378 '<button type="button" class="wp-list-reusable-blocks__export button-link" data-id="%s" aria-label="%s">%s</button>',
379 $post->ID,
380 /* translators: %s: Post title. */
381 esc_attr( sprintf( __( 'Export &#8220;%s&#8221; as JSON' ), $title ) ),
382 __( 'Export as JSON' )
383 );
384 }
385
386 if ( is_post_type_hierarchical( $post->post_type ) ) {
387
388 /**
389 * Filters the array of row action links on the Pages list table.
390 *
391 * The filter is evaluated only for hierarchical post types.
392 *
393 * @since 2.8.0
394 *
395 * @param string[] $actions An array of row action links. Defaults are
396 * 'Edit', 'Quick Edit', 'Restore', 'Trash',
397 * 'Delete Permanently', 'Preview', and 'View'.
398 * @param WP_Post $post The post object.
399 */
400 $actions = apply_filters( 'page_row_actions', $actions, $post );
401 } else {
402
403 /**
404 * Filters the array of row action links on the Posts list table.
405 *
406 * The filter is evaluated only for non-hierarchical post types.
407 *
408 * @since 2.8.0
409 *
410 * @param string[] $actions An array of row action links. Defaults are
411 * 'Edit', 'Quick Edit', 'Restore', 'Trash',
412 * 'Delete Permanently', 'Preview', and 'View'.
413 * @param WP_Post $post The post object.
414 */
415 $actions = apply_filters( 'post_row_actions', $actions, $post );
416 }
417
418 return $this->row_actions( $actions );
419 }
420 }