PluginProbe
Adminify – White Label, Admin Menu Editor, Login Customizer / 4.1.17
Adminify – White Label, Admin Menu Editor, Login Customizer v4.1.17
4.3.1 4.3.0 4.2.26 4.2.25 4.2.24 4.2.23 4.2.22 4.2.21 4.2.20 4.2.19 4.2.18 4.2.17 4.2.16 4.2.15 4.2.14 4.2.13 4.2.12 4.2.11 4.2.10 4.2.9 4.2.8 4.2.7 4.2.6 4.2.5 4.1.17 All 164 releases
adminify / Inc / Modules / PostTypesOrder / PostTypesOrder.php

PostTypesOrder.php in Adminify – White Label, Admin Menu Editor, Login Customizer 4.1.17, at Inc/Modules/PostTypesOrder/PostTypesOrder.php

600 lines 18.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace WPAdminify\Inc\Modules\PostTypesOrder;
4
5 use WPAdminify\Inc\Admin\AdminSettings;
6 use WPAdminify\Inc\Admin\AdminSettingsModel;
7 use WPAdminify\Inc\Modules\PostTypesOrder\PostTypesOrderWalker;
8
9 // no direct access allowed
10 if ( ! defined( 'ABSPATH' ) ) {
11 exit;
12 }
13
14 /**
15 * WP Adminify
16 *
17 * @package WP Adminify: Post Types Order
18 *
19 * @author WP Adminify <support@wpadminify.com>
20 */
21
22 class PostTypesOrder extends AdminSettingsModel {
23 public function __construct() {
24 $this->options = (array) AdminSettings::get_instance()->get('post_types_order');
25
26 // Admin Init
27 if ( empty( $_GET ) ) {
28 add_action( 'admin_init', [ $this, 'jltwp_adminify_refresh' ] );
29 }
30
31 add_action( 'admin_init', [ $this, 'adminify_pto_load_scripts' ] );
32 add_action( 'admin_enqueue_scripts', [ $this, 'adminify_pto_css' ], 99 );
33
34 // sortable ajax action
35 add_action( 'wp_ajax_update_post_types_order', [ $this, 'adminify_pto_update_order' ] );
36 add_action( 'wp_ajax_update_post_types_taxonomy_order', [ $this, 'adminify_pto_update_taxonomy' ] );
37
38 // reorder post types
39 add_action( 'pre_get_posts', [ $this, 'adminify_pto_pre_get_posts' ] );
40
41 add_filter( 'get_previous_post_where', array( $this, 'adminify_pto_previous_post_where' ) );
42 add_filter( 'get_previous_post_sort', [ $this, 'adminify_pto_previous_post_sort' ] );
43 add_filter( 'get_next_post_where', [ $this, 'adminify_pto_next_post_where' ] );
44 add_filter( 'get_next_post_sort', [ $this, 'adminify_pto_next_post_sort' ] );
45
46 // Taxonomy ordering (pto_taxonomies) is a Pro-only feature.
47 // The get_terms_orderby / wp_get_object_terms / get_terms
48 // filters are registered by Pro/Classes/Filters.php when the
49 // Pro plugin is active.
50
51 // reorder sites
52 if ( function_exists( 'is_multisite' ) && is_multisite() ) {
53 add_action( 'wp_ajax_update_post_types_order_sites', [ $this, 'adminify_pto_update_sites' ] );
54
55 // networkadmin
56 if (
57 empty( $_SERVER['QUERY_STRING'] ) ||
58 ( ! empty( $_SERVER['QUERY_STRING'] ) &&
59 'action=deleteblog' !== $_SERVER['QUERY_STRING'] && // delete
60 'action=allblogs' !== $_SERVER['QUERY_STRING'] // delete all
61 )
62 ) {
63
64 // call from 'get_sites'
65 add_filter( 'sites_clauses', [ $this, 'adminify_pto_sites_clauses' ], 10, 1 );
66
67 add_action( 'admin_init', [ $this, 'adminify_pto_refresh_network' ] );
68
69 // adminbar sites reorder
70 add_filter( 'get_blogs_of_user', [ $this, 'adminify_pto_get_blogs_of_user' ], 10, 3 );
71 }
72 }
73 }
74
75 public function adminiy_pto_media_list( $args = '' ) {
76 $defaults = [
77 'depth' => -1,
78 'date_format' => get_option( 'date_format' ),
79 'child_of' => 0,
80 'sort_column' => 'menu_order',
81 'post_status' => 'any',
82 ];
83
84 $r = wp_parse_args( $args, $defaults );
85 extract( $r, EXTR_SKIP );
86
87 $output = '';
88
89 $r['exclude'] = implode( ',', apply_filters( 'wp_list_pages_excludes', [] ) );
90
91 // Query pages.
92 $r['hierarchical'] = 0;
93 $args = [
94 'sort_column' => 'menu_order',
95 'post_type' => $post_type,
96 'posts_per_page' => -1,
97 'post_status' => 'any',
98 'orderby' => [
99 'menu_order' => 'ASC',
100 'post_date' => 'DESC',
101 ],
102 ];
103
104 $the_query = new \WP_Query( $args );
105 $pages = $the_query->posts;
106
107 if ( ! empty( $pages ) ) {
108 $output .= $this->walkTree( $pages, $r['depth'], $r );
109 }
110
111 echo wp_kses_post( $output );
112 }
113
114 public function walkTree( $pages, $depth, $r ) {
115 $walker = new PostTypesOrderWalker();
116
117 $args = [ $pages, $depth, $r ];
118 return call_user_func_array( [ &$walker, 'walk' ], $args );
119 }
120
121
122 public function jltwp_adminify_refresh() {
123 global $wpdb;
124 $objects = $this->adminify_pto_get_options();
125
126 if ( ! empty( $objects ) ) {
127 foreach ( $objects as $object ) {
128 $result = $wpdb->get_results(
129 "
130 SELECT count(*) as cnt, max(menu_order) as max, min(menu_order) as min
131 FROM $wpdb->posts
132 WHERE post_type = '" . $object . "' AND post_status IN ('publish', 'pending', 'draft', 'private', 'future')
133 "
134 );
135 if ( $result[0]->cnt == 0 || $result[0]->cnt == $result[0]->max ) {
136 continue;
137 }
138
139 $results = $wpdb->get_results(
140 "
141 SELECT ID
142 FROM $wpdb->posts
143 WHERE post_type = '" . $object . "' AND post_status IN ('publish', 'pending', 'draft', 'private', 'future')
144 ORDER BY menu_order ASC
145 "
146 );
147 foreach ( $results as $key => $result ) {
148 $wpdb->update( $wpdb->posts, [ 'menu_order' => $key + 1 ], [ 'ID' => $result->ID ] );
149 }
150 }
151 }
152 }
153
154
155
156 function adminify_pto_pre_get_posts( $wp_query ) {
157 $objects = $this->adminify_pto_get_options();
158 if ( empty( $objects ) ) {
159 return false;
160 }
161
162 /**
163 * for Admin
164 * @default
165 * post pto: [order] => null(desc) [orderby] => null(date)
166 * page: [order] => asc [orderby] => menu_order title
167 */
168
169 if ( is_admin() ) {
170 if ( isset( $wp_query->query['post_type'] ) && ! isset( $_GET['orderby'] ) ) {
171 if ( in_array( $wp_query->query['post_type'], $objects ) ) {
172 $wp_query->set( 'orderby', 'menu_order' );
173 $wp_query->set( 'order', 'ASC' );
174 }
175 }
176 } else {
177 $active = false;
178
179 // page or custom post types
180 if ( isset( $wp_query->query['post_type'] ) ) {
181 // exclude array()
182 if ( ! is_array( $wp_query->query['post_type'] ) ) {
183 if ( in_array( $wp_query->query['post_type'], $objects ) ) {
184 $active = true;
185 }
186 }
187 // post
188 } else {
189 if ( in_array( 'post', $objects ) ) {
190 $active = true;
191 }
192 }
193
194 if ( ! $active ) {
195 return false;
196 }
197
198 // get_posts()
199 if ( isset( $wp_query->query['suppress_filters'] ) ) {
200 if ( $wp_query->get( 'orderby' ) == 'date' || $wp_query->get( 'orderby' ) == 'menu_order' ) {
201 $wp_query->set( 'orderby', 'menu_order' );
202 $wp_query->set( 'order', 'ASC' );
203 } elseif ( $wp_query->get( 'orderby' ) == 'default_date' ) {
204 $wp_query->set( 'orderby', 'date' );
205 }
206 // WP_Query( contain main_query )
207 } else {
208 if (
209 ! $wp_query->get( 'orderby' )
210 ) {
211 $wp_query->set( 'orderby', 'menu_order' );
212 }
213 if (
214 ! $wp_query->get( 'order' )
215 ) {
216 $wp_query->set( 'order', 'ASC' );
217 }
218 }
219 }
220 }
221
222
223 public function adminify_pto_update_order() {
224 // Security check - verify nonce and capability
225 check_ajax_referer( 'adminify-pto-security-nonce', 'security' );
226
227 if ( ! current_user_can( 'edit_others_posts' ) ) {
228 wp_send_json_error( array( 'message' => __( 'You do not have permission to perform this action.', 'adminify' ) ) );
229 }
230
231 global $wpdb;
232 $data = [];
233 parse_str( sanitize_text_field( wp_unslash( $_POST['order'] ) ), $data );
234
235 if ( ! is_array( $data ) ) {
236 return false;
237 }
238
239 // get objects per now page
240 $id_arr = [];
241 foreach ( $data as $key => $values ) {
242 foreach ( $values as $position => $id ) {
243 $id_arr[] = $id;
244 }
245 }
246
247 // get menu_order of objects per now page
248 $menu_order_arr = [];
249 foreach ( $id_arr as $key => $id ) {
250 $results = $wpdb->get_results( "SELECT menu_order FROM $wpdb->posts WHERE ID = " . intval( $id ) );
251 foreach ( $results as $result ) {
252 $menu_order_arr[] = $result->menu_order;
253 }
254 }
255
256 // maintains key association = no
257 sort( $menu_order_arr );
258
259 foreach ( $data as $key => $values ) {
260 foreach ( $values as $position => $id ) {
261 $wpdb->update( $wpdb->posts, [ 'menu_order' => $menu_order_arr[ $position ] ], [ 'ID' => intval( $id ) ] );
262 }
263 }
264
265 // same number check
266 $post_type = get_post_type( $id );
267 $sql = "SELECT COUNT(menu_order) AS mo_count, post_type, menu_order FROM $wpdb->posts
268 WHERE post_type = '{$post_type}' AND post_status IN ('publish', 'pending', 'draft', 'private', 'future')
269 AND menu_order > 0 GROUP BY post_type, menu_order HAVING (mo_count) > 1";
270 $results = $wpdb->get_results( $sql );
271 if ( count( $results ) > 0 ) {
272
273 // menu_order refresh
274 $sql = "SELECT ID, menu_order FROM $wpdb->posts
275 WHERE post_type = '{$post_type}' AND post_status IN ('publish', 'pending', 'draft', 'private', 'future')
276 AND menu_order > 0 ORDER BY menu_order";
277 $results = $wpdb->get_results( $sql );
278 foreach ( $results as $key => $result ) {
279 $view_posi = array_search( $result->ID, $id_arr, true );
280 if ( $view_posi === false ) {
281 $view_posi = 999;
282 }
283 $sort_key = ( $result->menu_order * 1000 ) + $view_posi;
284 $sort_ids[ $sort_key ] = $result->ID;
285 }
286 ksort( $sort_ids );
287 $oreder_no = 0;
288 foreach ( $sort_ids as $key => $id ) {
289 $oreder_no = $oreder_no + 1;
290 $wpdb->update( $wpdb->posts, [ 'menu_order' => $oreder_no ], [ 'ID' => intval( $id ) ] );
291 }
292 }
293 }
294
295 public function adminify_pto_update_taxonomy() {
296 // Security check - verify nonce and capability
297 check_ajax_referer( 'adminify-pto-security-nonce', 'security' );
298
299 if ( ! current_user_can( 'manage_categories' ) ) {
300 wp_send_json_error( array( 'message' => __( 'You do not have permission to perform this action.', 'adminify' ) ) );
301 }
302
303 global $wpdb;
304
305 parse_str( sanitize_text_field( wp_unslash( $_POST['order'] ) ), $data );
306
307 if ( ! is_array( $data ) ) {
308 return false;
309 }
310
311 $id_arr = [];
312 foreach ( $data as $key => $values ) {
313 foreach ( $values as $position => $id ) {
314 $id_arr[] = $id;
315 }
316 }
317
318 $menu_order_arr = [];
319 foreach ( $id_arr as $key => $id ) {
320 $results = $wpdb->get_results( "SELECT term_order FROM $wpdb->terms WHERE term_id = " . intval( $id ) );
321 foreach ( $results as $result ) {
322 $menu_order_arr[] = $result->term_order;
323 }
324 }
325 sort( $menu_order_arr );
326
327 foreach ( $data as $key => $values ) {
328 foreach ( $values as $position => $id ) {
329 $wpdb->update( $wpdb->terms, [ 'term_order' => $menu_order_arr[ $position ] ], [ 'term_id' => intval( $id ) ] );
330 }
331 }
332
333 // same number check
334 $term = get_term( $id );
335 $taxonomy = $term->taxonomy;
336 $sql = "SELECT COUNT(term_order) AS to_count, term_order
337 FROM $wpdb->terms AS terms
338 INNER JOIN $wpdb->term_taxonomy AS term_taxonomy ON ( terms.term_id = term_taxonomy.term_id )
339 WHERE term_taxonomy.taxonomy = '" . $taxonomy . "'GROUP BY taxonomy, term_order HAVING (to_count) > 1";
340 $results = $wpdb->get_results( $sql );
341 if ( count( $results ) > 0 ) {
342 // term_order refresh
343 $sql = "SELECT terms.term_id, term_order
344 FROM $wpdb->terms AS terms
345 INNER JOIN $wpdb->term_taxonomy AS term_taxonomy ON ( terms.term_id = term_taxonomy.term_id )
346 WHERE term_taxonomy.taxonomy = '" . $taxonomy . "'
347 ORDER BY term_order ASC";
348 $results = $wpdb->get_results( $sql );
349 foreach ( $results as $key => $result ) {
350 $view_posi = array_search( $result->term_id, $id_arr, true );
351 if ( $view_posi === false ) {
352 $view_posi = 999;
353 }
354 $sort_key = ( $result->term_order * 1000 ) + $view_posi;
355 $sort_ids[ $sort_key ] = $result->term_id;
356 }
357 ksort( $sort_ids );
358 $oreder_no = 0;
359 foreach ( $sort_ids as $key => $id ) {
360 $oreder_no = $oreder_no + 1;
361 $wpdb->update( $wpdb->terms, [ 'term_order' => $oreder_no ], [ 'term_id' => $id ] );
362 }
363 }
364
365 do_action( 'wpadminify_update_post_types_order_taxonomy' );
366 }
367
368 public function adminify_pto_load_scripts() {
369 global $pagenow;
370
371 if ( $this->conditional_script_load() || ( $pagenow === 'upload.php' && ( isset( $this->options['pto_media'] ) && $this->options['pto_media'] ) ) ) {
372 wp_enqueue_script( 'jquery' );
373 wp_enqueue_script( 'jquery-ui-sortable' );
374 wp_enqueue_script( 'wp-adminify-post-type-order', WP_ADMINIFY_URL . 'Inc/Modules/PostTypesOrder/js/post-type-order.js', [ 'jquery' ], WP_ADMINIFY_VER, true );
375 wp_localize_script( 'wp-adminify-post-type-order', 'adminify_pto', array(
376 'nonce' => wp_create_nonce( 'adminify-pto-security-nonce' ),
377 ) );
378 }
379 }
380
381 public function adminify_pto_css() {
382 global $pagenow;
383 if ( $this->conditional_script_load() || ( $pagenow === 'upload.php' && ( ! empty( $this->options['pto_media'] ) ) ) ) {
384 echo '<!-- Start of Post Type and Taxonomy Order --->';
385 echo '<style type="text/css">';
386 echo '.adminify-table-responsive-wrapper .ui-sortable tr:hover{cursor:move}.adminify-table-responsive-wrapper .ui-sortable tr.alternate{background-color:#f9f9f9 !important}.adminify-table-responsive-wrapper .ui-sortable tr.ui-sortable-helper{background-color:#f9f9f9 !important;border-top:1px solid #dfdfdf;border-bottom:1px solid #dfdfdf;box-shadow:0 -5px 5px -4px rgba(0,0,0,.1),0 5px 5px -3px rgba(0,0,0,.1)}.adminify-table-responsive-wrapper .ui-sortable-placeholder{height:50px;background-color:#e9e9e9;border:2px dashed #dfdfdf;visibility:visible!important}.adminify-table-responsive-wrapper .wp-list-table{table-layout:fixed;width:100%;border-collapse:collapse}.adminify-table-responsive-wrapper.wp-list-table td,.adminify-table-responsive-wrapper .wp-list-table th{padding:8px 16px;text-align:left;white-space:nowrap;word-wrap:break-word;overflow:hidden}.adminify-table-responsive-wrapper.wp-list-table .column-title,.wp-list-table td.column-title,.adminify-table-responsive-wrapper{overflow-x:auto;-webkit-overflow-scrolling:touch}@media screen and (max-width:768px){.adminify-table-responsive-wrapper .wp-list-table td,.adminify-table-responsive-wrapper.wp-list-table th{padding:8px}}';
387 echo '</style>';
388 echo '<!-- End of Post Type and Taxonomy Order --->';
389 }
390 }
391
392 public function conditional_script_load() {
393 global $pagenow;
394
395 $active = false;
396
397 // Multisite > Sites
398 if (
399 function_exists( 'is_multisite' )
400 && is_multisite()
401 && $pagenow == 'sites.php'
402 ) {
403 return true;
404 }
405
406 $objects = $this->adminify_pto_get_options();
407
408 if ( empty( $objects ) ) {
409 return false;
410 }
411
412 // exclude (sorting, addnew page, edit page)
413 if ( isset( $_GET['orderby'] ) || ( ! empty( $_SERVER['REQUEST_URI'] ) && strstr( sanitize_text_field( wp_unslash( $_SERVER['REQUEST_URI'] ) ), 'action=edit' ) || strstr( sanitize_text_field( wp_unslash( $_SERVER['REQUEST_URI'] ) ), 'wp-admin/post-new.php' ) ) ) {
414 return false;
415 }
416
417 if ( ! empty( $objects ) ) {
418 if ( isset( $_GET['post_type'] ) && ! isset( $_GET['taxonomy'] ) && in_array( $_GET['post_type'], $objects ) ) { // if page or custom post types
419 $active = true;
420 }
421 if ( ! isset( $_GET['post_type'] ) && ( ! empty( $_SERVER['REQUEST_URI'] && strstr( sanitize_text_field( wp_unslash( $_SERVER['REQUEST_URI'] ) ), 'wp-admin/edit.php' ) ) && in_array( 'post', $objects ) ) ) {
422 // if post
423 $active = true;
424 }
425 }
426
427 return $active;
428 }
429
430 function adminify_pto_get_options() {
431 $objects = isset( $this->options['pto_posts'] ) && is_array( $this->options['pto_posts'] ) ? $this->options['pto_posts'] : [];
432 return $objects;
433 }
434
435 function adminify_pto_previous_post_where( $where ) {
436 global $post;
437
438 $objects = $this->adminify_pto_get_options();
439 if ( empty( $objects ) ) {
440 return $where;
441 }
442
443 if ( isset( $post->post_type ) && in_array( $post->post_type, $objects ) ) {
444 $current_menu_order = $post->menu_order;
445 $where = str_replace( "p.post_date < '" . $post->post_date . "'", "p.menu_order > '" . $current_menu_order . "'", $where );
446 }
447 return $where;
448 }
449
450 function adminify_pto_previous_post_sort( $orderby ) {
451 global $post;
452
453 $objects = $this->adminify_pto_get_options();
454 if ( empty( $objects ) ) {
455 return $orderby;
456 }
457
458 if ( isset( $post->post_type ) && in_array( $post->post_type, $objects ) ) {
459 $orderby = 'ORDER BY p.menu_order ASC LIMIT 1';
460 }
461 return $orderby;
462 }
463
464
465 function adminify_pto_next_post_where( $where ) {
466 global $post;
467
468 $objects = $this->adminify_pto_get_options();
469 if ( empty( $objects ) ) {
470 return $where;
471 }
472
473 if ( isset( $post->post_type ) && in_array( $post->post_type, $objects ) ) {
474 $current_menu_order = $post->menu_order;
475 $where = str_replace( "p.post_date > '" . $post->post_date . "'", "p.menu_order < '" . $current_menu_order . "'", $where );
476 }
477 return $where;
478 }
479
480 function adminify_pto_next_post_sort( $orderby ) {
481 global $post;
482
483 $objects = $this->adminify_pto_get_options();
484 if ( empty( $objects ) ) {
485 return $orderby;
486 }
487
488 if ( isset( $post->post_type ) && in_array( $post->post_type, $objects ) ) {
489 $orderby = 'ORDER BY p.menu_order DESC LIMIT 1';
490 }
491 return $orderby;
492 }
493
494
495 public function adminify_pto_sites_clauses( $pieces = [] ) {
496 if ( is_admin() ) {
497 return $pieces;
498 }
499
500 global $wp_version;
501 if ( version_compare( $wp_version, '4.6.0' ) >= 0 ) {
502 if ( 'blog_id ASC' === $pieces['orderby'] ) {
503 $pieces['orderby'] = 'menu_order ASC';
504 }
505 }
506 return $pieces;
507 }
508
509 public function adminify_pto_update_sites() {
510 // Security check - verify nonce and capability
511 check_ajax_referer( 'adminify-pto-security-nonce', 'security' );
512
513 if ( ! current_user_can( 'manage_sites' ) ) {
514 wp_send_json_error( array( 'message' => __( 'You do not have permission to perform this action.', 'adminify' ) ) );
515 }
516
517 global $wpdb;
518
519 parse_str( sanitize_text_field( wp_unslash( $_POST['order'] ) ), $data );
520
521 if ( ! is_array( $data ) ) {
522 return false;
523 }
524
525 $id_arr = [];
526 foreach ( $data as $key => $values ) {
527 foreach ( $values as $position => $id ) {
528 $id_arr[] = $id;
529 }
530 }
531
532 foreach ( $data as $key => $values ) {
533 foreach ( $values as $position => $id ) {
534 $wpdb->update( $wpdb->prefix . 'blogs', [ 'menu_order' => $position + 1 ], [ 'blog_id' => intval( $id ) ] );
535 }
536 }
537
538 die();
539 }
540
541 public function adminify_pto_refresh_network() {
542 global $pagenow;
543 if ( 'sites.php' === $pagenow && ! isset( $_GET['orderby'] ) ) {
544 add_filter( 'query', [ $this, 'adminify_pto_refresh_network_second' ] );
545 }
546 }
547
548
549 public function adminify_pto_refresh_network_second( $query ) {
550 global $wpdb, $wp_version, $blog_id;
551
552 // $wpdb->get_varやswitch_to_blog(1)
553 if ( version_compare( $wp_version, '4.7.0' ) >= 0 ) {
554 if ( 1 !== $blog_id ) {
555 return $query;
556 }
557 }
558
559 if (
560 false !== strpos( $query, "SELECT * FROM $wpdb->blogs WHERE site_id = '1'" ) ||
561 false !== strpos( $query, "SQL_CALC_FOUND_ROWS blog_id FROM $wpdb->blogs WHERE site_id = 1" )
562 ) {
563 if ( false !== strpos( $query, ' LIMIT ' ) ) {
564 $query = preg_replace( '/^(.*) LIMIT(.*)$/', '$1 ORDER BY menu_order ASC LIMIT $2', $query );
565 } else {
566 $query .= ' ORDER BY menu_order ASC';
567 }
568 }
569 return $query;
570 }
571
572
573 public function adminify_pto_get_blogs_of_user( $blogs ) {
574 $sites = get_sites( [] );
575 $sort_keys = [];
576 foreach ( $sites as $k => $v ) {
577 $sort_keys[] = $v->menu_order;
578 }
579 array_multisort( $sort_keys, SORT_ASC, $sites );
580
581 $blog_list = [];
582 foreach ( $blogs as $k => $v ) {
583 $blog_list[ $v->userblog_id ] = $v;
584 }
585
586 $new = [];
587 foreach ( $sites as $k => $v ) {
588 if (
589 isset( $v->blog_id ) &&
590 isset( $blog_list[ $v->blog_id ] ) &&
591 is_object( $blog_list[ $v->blog_id ] )
592 ) {
593 $new[] = $blog_list[ $v->blog_id ];
594 }
595 }
596
597 return $new;
598 }
599 }
600