class-activation.php
7 months ago
class-admin-menu-organizer.php
7 months ago
class-admin-menu-svg-icon-mask.php
7 months ago
class-auto-publish-posts-with-missed-schedule.php
7 months ago
class-avif-upload.php
7 months ago
class-captcha-protection.php
7 months ago
class-change-login-url.php
7 months ago
class-cleanup-admin-bar.php
7 months ago
class-common-methods.php
7 months ago
class-content-duplication.php
7 months ago
class-content-order.php
7 months ago
class-custom-admin-footer-text.php
7 months ago
class-custom-body-class.php
7 months ago
class-custom-css.php
7 months ago
class-custom-nav-menu-items-in-new-tab.php
7 months ago
class-deactivation.php
7 months ago
class-disable-author-archives.php
7 months ago
class-disable-comments.php
7 months ago
class-disable-dashboard-widgets.php
7 months ago
class-disable-embeds.php
7 months ago
class-disable-feeds.php
7 months ago
class-disable-gutenberg.php
7 months ago
class-disable-rest-api.php
7 months ago
class-disable-smaller-components.php
7 months ago
class-disable-updates.php
7 months ago
class-disable-xml-rpc.php
7 months ago
class-display-system-summary.php
7 months ago
class-email-address-obfuscator.php
7 months ago
class-email-delivery.php
7 months ago
class-enhance-list-tables.php
7 months ago
class-external-permalinks.php
7 months ago
class-heartbeat-control.php
7 months ago
class-hide-admin-bar.php
7 months ago
class-hide-admin-notices.php
7 months ago
class-image-sizes-panel.php
7 months ago
class-image-upload-control.php
7 months ago
class-insert-head-body-footer-code.php
7 months ago
class-last-login-column.php
7 months ago
class-limit-login-attempts.php
7 months ago
class-login-id-type.php
7 months ago
class-login-logout-menu.php
7 months ago
class-maintenance-mode.php
7 months ago
class-manage-ads-appads-txt.php
7 months ago
class-manage-robots-txt.php
7 months ago
class-media-replacement.php
7 months ago
class-multiple-user-roles.php
7 months ago
class-obfuscate-author-slugs.php
7 months ago
class-open-external-links-in-new-tab.php
7 months ago
class-password-protection.php
7 months ago
class-redirect-after-login.php
7 months ago
class-redirect-after-logout.php
7 months ago
class-redirect-fourofour.php
7 months ago
class-registration-date-column.php
7 months ago
class-revisions-control.php
7 months ago
class-search-engines-visibility.php
7 months ago
class-settings-fields-render.php
7 months ago
class-settings-sanitization.php
7 months ago
class-settings-sections-fields.php
7 months ago
class-show-custom-taxonomy-filters.php
7 months ago
class-site-identity-on-login-page.php
7 months ago
class-svg-upload.php
7 months ago
class-various-admin-ui-enhancements.php
7 months ago
class-view-admin-as-role.php
7 months ago
class-wider-admin-menu.php
7 months ago
class-wp-config-transformer.php
7 months ago
class-content-order.php
607 lines
| 1 | <?php |
| 2 | |
| 3 | namespace ASENHA\Classes; |
| 4 | |
| 5 | use WP_Query; |
| 6 | /** |
| 7 | * Class for Content Order module |
| 8 | * |
| 9 | * @since 6.9.5 |
| 10 | */ |
| 11 | class Content_Order { |
| 12 | /** |
| 13 | * Whether to render featured image thumbnails on the "Order" admin page. |
| 14 | * |
| 15 | * Pro-only feature. Default is false to avoid rendering thumbnails for large lists. |
| 16 | * |
| 17 | * @var bool |
| 18 | */ |
| 19 | private $show_featured_thumbnails = false; |
| 20 | |
| 21 | /** |
| 22 | * Add "Custom Order" sub-menu for post types |
| 23 | * |
| 24 | * @since 5.0.0 |
| 25 | */ |
| 26 | public function add_content_order_submenu( $context ) { |
| 27 | $options = get_option( ASENHA_SLUG_U, array() ); |
| 28 | $content_order_for = ( isset( $options['content_order_for'] ) ? $options['content_order_for'] : array() ); |
| 29 | $content_order_enabled_post_types = array(); |
| 30 | if ( is_array( $content_order_for ) && count( $content_order_for ) > 0 ) { |
| 31 | foreach ( $content_order_for as $post_type_slug => $is_custom_order_enabled ) { |
| 32 | if ( $is_custom_order_enabled ) { |
| 33 | $post_type_object = get_post_type_object( $post_type_slug ); |
| 34 | if ( is_object( $post_type_object ) && property_exists( $post_type_object, 'labels' ) ) { |
| 35 | $post_type_name_plural = $post_type_object->labels->name; |
| 36 | if ( 'post' == $post_type_slug ) { |
| 37 | $hook_suffix = add_posts_page( |
| 38 | $post_type_name_plural . ' Order', |
| 39 | // Page title |
| 40 | __( 'Order', 'admin-site-enhancements' ), |
| 41 | // Menu title |
| 42 | 'edit_others_posts', |
| 43 | // Capability required |
| 44 | 'custom-order-posts', |
| 45 | // Menu and page slug |
| 46 | [$this, 'custom_order_page_output'] |
| 47 | ); |
| 48 | } else { |
| 49 | if ( 'sfwd-courses' == $post_type_slug ) { |
| 50 | // LearnDash LMS Courses |
| 51 | // Add 'Order' submenu item under LearnDash menu |
| 52 | // Linked URL will be /wp-admin/admin.php?page=custom-order-sfwd-courses |
| 53 | // We will add a redirect to the correct URL via $this->maybe_perform_menu_link_redirects() hooked in admin_init |
| 54 | $hook_suffix = add_submenu_page( |
| 55 | 'learndash-lms', |
| 56 | // Parent (menu) slug. Ref: https://developer.wordpress.org/reference/functions/add_submenu_page/#comment-1404 |
| 57 | $post_type_name_plural . ' ' . __( 'Order', 'admin-site-enhancements' ), |
| 58 | // Page title |
| 59 | $post_type_name_plural . ' ' . __( 'Order', 'admin-site-enhancements' ), |
| 60 | // Menu title |
| 61 | 'edit_others_posts', |
| 62 | // Capability required |
| 63 | 'custom-order-' . $post_type_slug, |
| 64 | // Menu and page slug |
| 65 | [$this, 'custom_order_page_output'], |
| 66 | // Callback function that outputs page content |
| 67 | 9999 |
| 68 | ); |
| 69 | // Add the actual, functional 'Order' submenu page at /edit.php?post_type=sfwd-courses&page=custom-order-sfwd-courses |
| 70 | // We will redirect to this URL from /wp-admin/admin.php?page=custom-order-sfwd-courses created above using $this->maybe_perform_menu_link_redirects() hooked in admin_init |
| 71 | $hook_suffix = add_submenu_page( |
| 72 | 'edit.php?post_type=' . $post_type_slug, |
| 73 | // Parent (menu) slug. Ref: https://developer.wordpress.org/reference/functions/add_submenu_page/#comment-1404 |
| 74 | // 'learndash-lms', // Parent (menu) slug. Ref: https://developer.wordpress.org/reference/functions/add_submenu_page/#comment-1404 |
| 75 | $post_type_name_plural . ' ' . __( 'Order', 'admin-site-enhancements' ), |
| 76 | // Page title |
| 77 | $post_type_name_plural . ' ' . __( 'Order', 'admin-site-enhancements' ), |
| 78 | // Menu title |
| 79 | 'edit_others_posts', |
| 80 | // Capability required |
| 81 | 'custom-order-' . $post_type_slug, |
| 82 | // Menu and page slug |
| 83 | [$this, 'custom_order_page_output'], |
| 84 | // Callback function that outputs page content |
| 85 | 9999 |
| 86 | ); |
| 87 | } else { |
| 88 | $hook_suffix = add_submenu_page( |
| 89 | 'edit.php?post_type=' . $post_type_slug, |
| 90 | // Parent (menu) slug. Ref: https://developer.wordpress.org/reference/functions/add_submenu_page/#comment-1404 |
| 91 | $post_type_name_plural . ' Order', |
| 92 | // Page title |
| 93 | __( 'Order', 'admin-site-enhancements' ), |
| 94 | // Menu title |
| 95 | 'edit_others_posts', |
| 96 | // Capability required |
| 97 | 'custom-order-' . $post_type_slug, |
| 98 | // Menu and page slug |
| 99 | [$this, 'custom_order_page_output'], |
| 100 | // Callback function that outputs page content |
| 101 | 9999 |
| 102 | ); |
| 103 | } |
| 104 | } |
| 105 | add_action( 'admin_print_styles-' . $hook_suffix, [$this, 'enqueue_content_order_styles'] ); |
| 106 | add_action( 'admin_print_scripts-' . $hook_suffix, [$this, 'enqueue_content_order_scripts'] ); |
| 107 | } |
| 108 | } |
| 109 | } |
| 110 | } |
| 111 | } |
| 112 | |
| 113 | /** |
| 114 | * Add additinal HTML elements on list tables |
| 115 | * |
| 116 | * @since 7.6.10 |
| 117 | */ |
| 118 | public function add_additional_elements() { |
| 119 | global $pagenow, $typenow; |
| 120 | $common_methods = new Common_Methods(); |
| 121 | $options = get_option( ASENHA_SLUG_U, array() ); |
| 122 | $content_order_for = ( isset( $options['content_order_for'] ) ? $options['content_order_for'] : array() ); |
| 123 | $content_order_enabled_post_types = $common_methods->get_array_of_keys_with_true_value( $content_order_for ); |
| 124 | $content_order_other_enabled_post_types = array(); |
| 125 | // List tables of pages, posts and CPTs. Administrators and Editors only. |
| 126 | if ( 'edit.php' == $pagenow && current_user_can( 'edit_others_posts' ) && (in_array( $typenow, $content_order_enabled_post_types ) || in_array( $typenow, $content_order_other_enabled_post_types )) ) { |
| 127 | // Add "Order" button |
| 128 | if ( 'post' == $typenow ) { |
| 129 | $typenow = 'posts'; |
| 130 | } |
| 131 | ?> |
| 132 | <div id="content-order-button"> |
| 133 | <a class="button" href="<?php |
| 134 | echo esc_url( get_admin_url() ); |
| 135 | ?>edit.php?post_type=<?php |
| 136 | echo esc_attr( $typenow ); |
| 137 | ?>&page=custom-order-<?php |
| 138 | echo esc_attr( $typenow ); |
| 139 | ?>"><?php |
| 140 | _e( 'Order', 'admin-site-enhancements' ); |
| 141 | ?></a> |
| 142 | </div> |
| 143 | <?php |
| 144 | } |
| 145 | } |
| 146 | |
| 147 | /** |
| 148 | * Add scripts for content list tables |
| 149 | * |
| 150 | * @since 7.6.10 |
| 151 | */ |
| 152 | public function add_list_tables_scripts( $hook_suffix ) { |
| 153 | global $pagenow, $typenow; |
| 154 | $common_methods = new Common_Methods(); |
| 155 | $options = get_option( ASENHA_SLUG_U, array() ); |
| 156 | $content_order_for = ( isset( $options['content_order_for'] ) ? $options['content_order_for'] : array() ); |
| 157 | $content_order_enabled_post_types = $common_methods->get_array_of_keys_with_true_value( $content_order_for ); |
| 158 | $content_order_other_enabled_post_types = array(); |
| 159 | // List tables of pages, posts and CPTs |
| 160 | if ( 'edit.php' == $hook_suffix && current_user_can( 'edit_others_posts' ) && (in_array( $typenow, $content_order_enabled_post_types ) || in_array( $typenow, $content_order_other_enabled_post_types )) ) { |
| 161 | wp_enqueue_style( |
| 162 | 'asenha-list-tables-content-order', |
| 163 | ASENHA_URL . 'assets/css/list-tables-content-order.css', |
| 164 | array(), |
| 165 | ASENHA_VERSION |
| 166 | ); |
| 167 | wp_enqueue_script( |
| 168 | 'asenha-list-tables-content-order', |
| 169 | ASENHA_URL . 'assets/js/list-tables-content-order.js', |
| 170 | array('jquery'), |
| 171 | ASENHA_VERSION, |
| 172 | false |
| 173 | ); |
| 174 | } |
| 175 | } |
| 176 | |
| 177 | /** |
| 178 | * Maybe perform redirects from the 'Order' submenu link |
| 179 | * |
| 180 | * @since 7.6.9 |
| 181 | */ |
| 182 | public function maybe_perform_menu_link_redirects() { |
| 183 | $request_uri = sanitize_text_field( $_SERVER['REQUEST_URI'] ); |
| 184 | // e.g. /wp-admin/index.php?page=page-slug |
| 185 | // Redirect for LearnDash LMS Courses post type ('sfwd-courses') |
| 186 | if ( in_array( 'sfwd-lms/sfwd_lms.php', get_option( 'active_plugins', array() ) ) ) { |
| 187 | if ( false !== strpos( $request_uri, 'admin.php?page=custom-order-sfwd-courses' ) ) { |
| 188 | wp_safe_redirect( get_admin_url() . 'edit.php?post_type=sfwd-courses&page=custom-order-sfwd-courses' ); |
| 189 | exit; |
| 190 | } |
| 191 | } |
| 192 | } |
| 193 | |
| 194 | /** |
| 195 | * Output content for the custom order page for each enabled post types |
| 196 | * Not using settings API because all done via AJAX |
| 197 | * |
| 198 | * @since 5.0.0 |
| 199 | */ |
| 200 | public function custom_order_page_output() { |
| 201 | $post_status = array( |
| 202 | 'publish', |
| 203 | 'future', |
| 204 | 'draft', |
| 205 | 'pending', |
| 206 | 'private' |
| 207 | ); |
| 208 | $parent_slug = get_admin_page_parent(); |
| 209 | if ( 'edit.php' == $parent_slug ) { |
| 210 | $post_type_slug = 'post'; |
| 211 | } elseif ( 'upload.php' == $parent_slug ) { |
| 212 | $post_type_slug = 'attachment'; |
| 213 | $post_status = array('inherit', 'private'); |
| 214 | } else { |
| 215 | $post_type_slug = str_replace( 'edit.php?post_type=', '', $parent_slug ); |
| 216 | } |
| 217 | // Pro-only: featured image thumbnails are rendered only when explicitly enabled via query arg. |
| 218 | $this->show_featured_thumbnails = false; |
| 219 | // Object with properties for each post status and the count of posts for each status |
| 220 | // $post_count_object = wp_count_posts( $post_type_slug ); |
| 221 | // Number of items with the status 'publish(ed)', 'future' (scheduled), 'draft', 'pending' and 'private' |
| 222 | // $post_count = absint( $post_count_object->publish ) |
| 223 | // + absint( $post_count_object->future ) |
| 224 | // + absint( $post_count_object->draft ) |
| 225 | // + absint( $post_count_object->pending ) |
| 226 | // + absint( $post_count_object->private ); |
| 227 | ?> |
| 228 | <div class="wrap"> |
| 229 | <div class="page-header"> |
| 230 | <h2> |
| 231 | <?php |
| 232 | echo esc_html( get_admin_page_title() ); |
| 233 | ?> |
| 234 | </h2> |
| 235 | <?php |
| 236 | ?> |
| 237 | </div> |
| 238 | <?php |
| 239 | // Get posts |
| 240 | $args = array( |
| 241 | 'post_type' => $post_type_slug, |
| 242 | 'numberposts' => -1, |
| 243 | 'orderby' => 'menu_order title', |
| 244 | 'order' => 'ASC', |
| 245 | 'post_status' => $post_status, |
| 246 | ); |
| 247 | // Add the following to non-attachment post types |
| 248 | if ( 'attachment' != $post_type_slug && is_post_type_hierarchical( $post_type_slug ) ) { |
| 249 | // In hierarchical post types, only return non-child posts as we currently only sort parent posts |
| 250 | $args['post_parent'] = 0; |
| 251 | } |
| 252 | $posts = get_posts( $args ); |
| 253 | if ( !empty( $posts ) ) { |
| 254 | ?> |
| 255 | <ul id="item-list"> |
| 256 | <?php |
| 257 | foreach ( $posts as $post ) { |
| 258 | $this->custom_order_single_item_output( $post ); |
| 259 | } |
| 260 | ?> |
| 261 | </ul> |
| 262 | <div id="updating-order-notice" class="updating-order-notice" style="display: none;"><img src="<?php |
| 263 | echo esc_attr( ASENHA_URL ) . 'assets/img/oval.svg'; |
| 264 | ?>" id="spinner-img" class="spinner-img" /><span class="dashicons dashicons-saved" style="display:none;"></span>Updating order...</div> |
| 265 | <?php |
| 266 | } else { |
| 267 | ?> |
| 268 | <h3>There is nothing to sort for this post type.</h3> |
| 269 | <?php |
| 270 | } |
| 271 | ?> |
| 272 | </div> <!-- End of div.wrap --> |
| 273 | <?php |
| 274 | } |
| 275 | |
| 276 | /** |
| 277 | * Output single item sortable for custom content order |
| 278 | * |
| 279 | * @since 5.0.0 |
| 280 | */ |
| 281 | private function custom_order_single_item_output( $post ) { |
| 282 | if ( is_post_type_hierarchical( $post->post_type ) ) { |
| 283 | $post_type_object = get_post_type_object( $post->post_type ); |
| 284 | $children = get_pages( array( |
| 285 | 'child_of' => $post->ID, |
| 286 | 'post_type' => $post->post_type, |
| 287 | ) ); |
| 288 | if ( count( $children ) > 0 ) { |
| 289 | $has_child_label = '<span class="has-child-label"> <span class="dashicons dashicons-arrow-right"></span> Has child ' . strtolower( $post_type_object->label ) . '</span>'; |
| 290 | $has_child = 'true'; |
| 291 | } else { |
| 292 | $has_child_label = ''; |
| 293 | $has_child = 'false'; |
| 294 | } |
| 295 | } else { |
| 296 | $has_child_label = ''; |
| 297 | $has_child = 'false'; |
| 298 | } |
| 299 | $post_status_label_class = ( $post->post_status == 'publish' ? ' item-status-hidden' : '' ); |
| 300 | $post_status_object = get_post_status_object( $post->post_status ); |
| 301 | if ( 'attachment' == $post->post_type ) { |
| 302 | $post_status_label_separator = ''; |
| 303 | $post_status_label = ''; |
| 304 | // Attachments / media only has the post status 'inherit'. Let's not show it. |
| 305 | } else { |
| 306 | $post_status_label_separator = ' — '; |
| 307 | $post_status_label = $post_status_object->label; |
| 308 | } |
| 309 | if ( empty( wp_trim_excerpt( $post->post_excerpt, $post ) ) ) { |
| 310 | $short_excerpt = ''; |
| 311 | } else { |
| 312 | $excerpt_trimmed = implode( " ", array_slice( explode( " ", wp_trim_excerpt( $post->post_excerpt, $post ) ), 0, 30 ) ); |
| 313 | $short_excerpt = '<span class="item-excerpt"> | ' . $excerpt_trimmed . '</span>'; |
| 314 | } |
| 315 | $taxonomies = get_object_taxonomies( $post->post_type, 'objects' ); |
| 316 | // vi( $taxonomies ); |
| 317 | $taxonomies_and_terms = ''; |
| 318 | foreach ( $taxonomies as $taxonomy ) { |
| 319 | $terms = array(); |
| 320 | if ( $taxonomy->hierarchical ) { |
| 321 | $taxonomy_terms = get_the_terms( $post->ID, $taxonomy->name ); |
| 322 | if ( is_array( $taxonomy_terms ) && !empty( $taxonomy_terms ) ) { |
| 323 | foreach ( $taxonomy_terms as $term ) { |
| 324 | $terms[] = $term->name; |
| 325 | } |
| 326 | } |
| 327 | } |
| 328 | $terms = implode( ', ', $terms ); |
| 329 | $taxonomies_and_terms .= ' | ' . $taxonomy->label . ': ' . $terms; |
| 330 | } |
| 331 | if ( !empty( $taxonomies_and_terms ) ) { |
| 332 | $taxonomies_and_terms = '<span class="item-taxonomy-terms">' . $taxonomies_and_terms . '</span>'; |
| 333 | } |
| 334 | // If WPML plugin is active, let's get the current language |
| 335 | if ( in_array( 'sitepress-multilingual-cms/sitepress.php', get_option( 'active_plugins', array() ) ) ) { |
| 336 | $current_language = apply_filters( 'wpml_current_language', null ); |
| 337 | $current_post_language_info = apply_filters( 'wpml_post_language_details', null, $post->ID ); |
| 338 | if ( !is_wp_error( $current_post_language_info ) ) { |
| 339 | $current_post_language = $current_post_language_info['language_code']; |
| 340 | } else { |
| 341 | // wpml has not set language information for the post |
| 342 | // e.g. post is not translated yet, so, let's use the current site/admin language |
| 343 | $current_post_language = $current_language; |
| 344 | } |
| 345 | $same_language = $current_language === $current_post_language; |
| 346 | // true if language is the same, false otherwise |
| 347 | } else { |
| 348 | // WPML is not active, $same_language is always true, e.g. all posts are in English |
| 349 | $same_language = true; |
| 350 | } |
| 351 | // Only render sortable for posts that have the same language as the current chosen language |
| 352 | if ( $same_language ) { |
| 353 | ?> |
| 354 | <li id="list_<?php |
| 355 | echo esc_attr( $post->ID ); |
| 356 | ?>" class="list-item" data-id="<?php |
| 357 | echo esc_attr( $post->ID ); |
| 358 | ?>" data-menu-order="<?php |
| 359 | echo esc_attr( $post->menu_order ); |
| 360 | ?>" data-parent="<?php |
| 361 | echo esc_attr( $post->post_parent ); |
| 362 | ?>" data-has-child="<?php |
| 363 | echo esc_attr( $has_child ); |
| 364 | ?>" data-post-type="<?php |
| 365 | echo esc_attr( $post->post_type ); |
| 366 | ?>"> |
| 367 | <div class="row"> |
| 368 | <div class="row-content"> |
| 369 | <?php |
| 370 | echo '<div class="content-main"> |
| 371 | <span class="dashicons dashicons-menu"></span><a href="' . esc_attr( get_edit_post_link( $post->ID ) ) . '" class="item-title">' . esc_html( $post->post_title ) . '</a><span class="item-status' . esc_attr( $post_status_label_class ) . '">' . esc_html( $post_status_label_separator ) . esc_html( $post_status_label ) . '</span>' . wp_kses_post( $has_child_label ) . wp_kses_post( $taxonomies_and_terms ) . wp_kses_post( $short_excerpt ) . '<div class="fader"></div> |
| 372 | </div>'; |
| 373 | if ( !in_array( $post->post_type, array('asenha_code_snippet') ) ) { |
| 374 | echo '<div class="content-additional"> |
| 375 | <a href="' . esc_attr( get_the_permalink( $post->ID ) ) . '" target="_blank" class="button item-view-link">View</a> |
| 376 | </div>'; |
| 377 | } |
| 378 | ?> |
| 379 | </div> |
| 380 | </div> |
| 381 | <?php |
| 382 | } |
| 383 | // if ( $same_language ) |
| 384 | ?> |
| 385 | </li> |
| 386 | <?php |
| 387 | } |
| 388 | |
| 389 | /** |
| 390 | * Enqueue styles for content order pages |
| 391 | * |
| 392 | * @since 5.0.0 |
| 393 | */ |
| 394 | public function enqueue_content_order_styles() { |
| 395 | wp_enqueue_style( |
| 396 | 'content-order-style', |
| 397 | ASENHA_URL . 'assets/css/content-order.css', |
| 398 | array(), |
| 399 | ASENHA_VERSION |
| 400 | ); |
| 401 | } |
| 402 | |
| 403 | /** |
| 404 | * Enqueue scripts for content order pages |
| 405 | * |
| 406 | * @since 5.0.0 |
| 407 | */ |
| 408 | public function enqueue_content_order_scripts() { |
| 409 | global $typenow; |
| 410 | wp_enqueue_script( |
| 411 | 'content-order-jquery-ui-touch-punch', |
| 412 | ASENHA_URL . 'assets/js/jquery.ui.touch-punch.min.js', |
| 413 | array('jquery-ui-sortable'), |
| 414 | '0.2.3', |
| 415 | true |
| 416 | ); |
| 417 | wp_register_script( |
| 418 | 'content-order-nested-sortable', |
| 419 | ASENHA_URL . 'assets/js/jquery.mjs.nestedSortable.js', |
| 420 | array('content-order-jquery-ui-touch-punch'), |
| 421 | '2.0.0', |
| 422 | true |
| 423 | ); |
| 424 | wp_enqueue_script( |
| 425 | 'content-order-sort', |
| 426 | ASENHA_URL . 'assets/js/content-order-sort.js', |
| 427 | array('content-order-nested-sortable'), |
| 428 | ASENHA_VERSION, |
| 429 | true |
| 430 | ); |
| 431 | wp_localize_script( 'content-order-sort', 'contentOrderSort', array( |
| 432 | 'action' => 'save_custom_order', |
| 433 | 'nonce' => wp_create_nonce( 'order_sorting_nonce' ), |
| 434 | 'hirarchical' => ( is_post_type_hierarchical( $typenow ) ? 'true' : 'false' ), |
| 435 | ) ); |
| 436 | } |
| 437 | |
| 438 | /** |
| 439 | * Save custom content order coming from ajax call |
| 440 | * |
| 441 | * @since 5.0.0 |
| 442 | */ |
| 443 | public function save_custom_content_order() { |
| 444 | global $wpdb; |
| 445 | // Check user capabilities |
| 446 | if ( !current_user_can( 'edit_others_posts' ) ) { |
| 447 | wp_send_json( 'Something went wrong.' ); |
| 448 | } |
| 449 | // Verify nonce |
| 450 | if ( !wp_verify_nonce( $_POST['nonce'], 'order_sorting_nonce' ) ) { |
| 451 | wp_send_json( 'Something went wrong.' ); |
| 452 | } |
| 453 | // Get ajax variables |
| 454 | $action = ( isset( $_POST['action'] ) ? $_POST['action'] : '' ); |
| 455 | // Item parent is currently 0, as we only handle sorting of non-child posts |
| 456 | $item_parent = ( isset( $_POST['item_parent'] ) ? absint( $_POST['item_parent'] ) : 0 ); |
| 457 | $menu_order_start = ( isset( $_POST['start'] ) ? absint( $_POST['start'] ) : 0 ); |
| 458 | $post_id = ( isset( $_POST['post_id'] ) ? absint( $_POST['post_id'] ) : 0 ); |
| 459 | $item_menu_order = ( isset( $_POST['menu_order'] ) ? absint( $_POST['menu_order'] ) : 0 ); |
| 460 | $items_to_exclude = ( isset( $_POST['excluded_items'] ) ? absint( $_POST['excluded_items'] ) : array() ); |
| 461 | $post_type = ( isset( $_POST['post_type'] ) ? $_POST['post_type'] : false ); |
| 462 | // Make processing faster by removing certain actions |
| 463 | remove_action( 'pre_post_update', 'wp_save_post_revision' ); |
| 464 | // $response array for ajax response |
| 465 | $response = array(); |
| 466 | // Update the item whose order/position was moved |
| 467 | if ( $post_id > 0 && !isset( $_POST['more_posts'] ) ) { |
| 468 | $wpdb->update( |
| 469 | $wpdb->posts, |
| 470 | // The table |
| 471 | array( |
| 472 | 'menu_order' => $item_menu_order, |
| 473 | ), |
| 474 | array( |
| 475 | 'ID' => $post_id, |
| 476 | ) |
| 477 | ); |
| 478 | clean_post_cache( $post_id ); |
| 479 | $items_to_exclude[] = $post_id; |
| 480 | } |
| 481 | if ( 'attachment' == $post_type ) { |
| 482 | $post_status = array('inherit', 'private'); |
| 483 | } else { |
| 484 | $post_status = array( |
| 485 | 'publish', |
| 486 | 'future', |
| 487 | 'draft', |
| 488 | 'pending', |
| 489 | 'private' |
| 490 | ); |
| 491 | } |
| 492 | // Get all posts from the post type related to ajax request |
| 493 | $query_args = array( |
| 494 | 'post_type' => $post_type, |
| 495 | 'orderby' => 'menu_order title', |
| 496 | 'order' => 'ASC', |
| 497 | 'posts_per_page' => -1, |
| 498 | 'suppress_filters' => true, |
| 499 | 'ignore_sticky_posts' => true, |
| 500 | 'post_status' => $post_status, |
| 501 | 'post__not_in' => $items_to_exclude, |
| 502 | 'update_post_term_cache' => false, |
| 503 | 'update_post_meta_cache' => false, |
| 504 | ); |
| 505 | if ( 'attachment' == $post_type ) { |
| 506 | // do nothing, we do not add post_parent parameter as media items can be attached to other posts, making them the parent. |
| 507 | } else { |
| 508 | // Item parent is currently 0, as we only handle sorting of non-child posts |
| 509 | $query_args['post_parent'] = $item_parent; |
| 510 | } |
| 511 | $posts = new WP_Query($query_args); |
| 512 | if ( $posts->have_posts() ) { |
| 513 | // Iterate through posts and update menu order and post parent |
| 514 | foreach ( $posts->posts as $post ) { |
| 515 | // If the $post is the one being displaced (shited downward) by the moved item, increment it's menu_order by one |
| 516 | if ( $menu_order_start == $item_menu_order && $post_id > 0 ) { |
| 517 | $menu_order_start++; |
| 518 | } |
| 519 | // Only process posts other than the moved item, which has been processed earlier outside this loop |
| 520 | if ( $post_id != $post->ID ) { |
| 521 | // Update menu_order |
| 522 | $wpdb->update( $wpdb->posts, array( |
| 523 | 'menu_order' => $menu_order_start, |
| 524 | ), array( |
| 525 | 'ID' => $post->ID, |
| 526 | ) ); |
| 527 | clean_post_cache( $post->ID ); |
| 528 | } |
| 529 | $items_to_exclude[] = $post->ID; |
| 530 | $menu_order_start++; |
| 531 | } |
| 532 | die( json_encode( $response ) ); |
| 533 | } else { |
| 534 | die( json_encode( $response ) ); |
| 535 | } |
| 536 | } |
| 537 | |
| 538 | /** |
| 539 | * Set default ordering of list tables of sortable post types by 'menu_order' |
| 540 | * |
| 541 | * @link https://developer.wordpress.org/reference/classes/wp_query/#methods |
| 542 | * @since 5.0.0 |
| 543 | */ |
| 544 | public function orderby_menu_order( $query ) { |
| 545 | global $pagenow, $typenow; |
| 546 | $query_post_type = $query->get( 'post_type' ); |
| 547 | $options = get_option( ASENHA_SLUG_U, array() ); |
| 548 | // Hierarchical post types that should be custom ordered |
| 549 | $content_order_for = ( isset( $options['content_order_for'] ) ? $options['content_order_for'] : array() ); |
| 550 | $content_order_enabled_post_types = array(); |
| 551 | if ( is_array( $content_order_for ) && count( $content_order_for ) > 0 ) { |
| 552 | foreach ( $content_order_for as $post_type_slug => $is_custom_order_enabled ) { |
| 553 | if ( $is_custom_order_enabled ) { |
| 554 | $content_order_enabled_post_types[] = $post_type_slug; |
| 555 | } |
| 556 | } |
| 557 | } |
| 558 | $should_be_custom_sorted = false; |
| 559 | // All post types that should be custom ordered |
| 560 | $content_order_post_types = $content_order_enabled_post_types; |
| 561 | // Use custom order in wp-admin listing pages/tables for enabled post types |
| 562 | if ( is_admin() && ('edit.php' == $pagenow || 'upload.php' == $pagenow) && !isset( $_GET['orderby'] ) ) { |
| 563 | if ( in_array( $typenow, $content_order_post_types ) ) { |
| 564 | $query->set( 'orderby', 'menu_order title' ); |
| 565 | $query->set( 'order', 'ASC' ); |
| 566 | } |
| 567 | } |
| 568 | } |
| 569 | |
| 570 | /** |
| 571 | * Make sure newly created posts are assigned the highest menu_order so it's added at the bottom of the existing order |
| 572 | * |
| 573 | * @since 6.2.1 |
| 574 | */ |
| 575 | public function set_menu_order_for_new_posts( $post_id, $post, $update ) { |
| 576 | $options = get_option( ASENHA_SLUG_U, array() ); |
| 577 | $content_order_for = ( isset( $options['content_order_for'] ) ? $options['content_order_for'] : array() ); |
| 578 | $content_order_enabled_post_types = array(); |
| 579 | if ( is_array( $content_order_for ) && count( $content_order_for ) > 0 ) { |
| 580 | foreach ( $content_order_for as $post_type_slug => $is_custom_order_enabled ) { |
| 581 | if ( $is_custom_order_enabled ) { |
| 582 | $content_order_enabled_post_types[] = $post_type_slug; |
| 583 | } |
| 584 | } |
| 585 | } |
| 586 | // Only assign menu_order if there are none assigned when creating the post, i.e. menu_order is 0 |
| 587 | if ( in_array( $post->post_type, $content_order_enabled_post_types ) && ('auto-draft' == $post->post_status || 'publish' == $post->post_status) && $post->menu_order == '0' && false === $update ) { |
| 588 | $post_with_highest_menu_order = get_posts( array( |
| 589 | 'post_type' => $post->post_type, |
| 590 | 'posts_per_page' => 1, |
| 591 | 'orderby' => 'menu_order', |
| 592 | 'order' => 'DESC', |
| 593 | ) ); |
| 594 | if ( $post_with_highest_menu_order ) { |
| 595 | $new_menu_order = (int) $post_with_highest_menu_order[0]->menu_order + 1; |
| 596 | // Assign the one higher menu_order to the new post |
| 597 | $args = array( |
| 598 | 'ID' => $post_id, |
| 599 | 'menu_order' => $new_menu_order, |
| 600 | ); |
| 601 | wp_update_post( $args ); |
| 602 | } |
| 603 | } |
| 604 | } |
| 605 | |
| 606 | } |
| 607 |