PluginProbe ʕ •ᴥ•ʔ
Admin and Site Enhancements (ASE) / 7.9.7
Admin and Site Enhancements (ASE) v7.9.7
9.1.0 9.0.2 9.0.1 9.0.0 8.9.2 8.9.1 8.9.0 8.8.8 8.8.7 8.8.6 8.8.5 8.8.4 8.8.3 8.8.2 8.8.1 8.8.0 8.7.3 8.7.2 8.7.1 8.2.1 8.2.2 8.2.3 8.3.0 8.3.1 8.3.2 8.4.0 8.4.1 8.4.2 8.5.0 8.5.1 8.5.2 8.6.0 8.6.1 8.6.2 8.7.0 5.0.1 5.0.2 5.0.2.1 5.0.2.2 5.0.2.3 5.0.2.4 5.1.0 5.2.0 5.2.1 5.2.10 5.2.11 5.2.2 5.2.3 5.2.4 5.2.5 5.2.6 5.2.7 5.2.8 5.2.9 5.3.0 5.3.1 5.3.2 5.4.0 5.4.1 5.5.0 5.5.1 5.5.2 5.6.0 5.6.1 5.6.2 5.7.0 5.7.1 5.8.0 5.8.1 6.0.0 6.0.3 6.0.4 6.0.5 6.0.5.1 6.0.6 6.0.7 6.0.8.1 6.1.0 6.1.3 6.2.0 6.2.1 6.2.2 6.2.3 6.2.4 6.2.5 6.2.6 6.2.7 6.3.0 6.3.1 6.3.2 6.4.0 6.5.0 6.5.1 6.6.0 6.7.0 6.8.0 6.8.2 6.8.3 6.9.0 6.9.1 6.9.10 6.9.11 6.9.12 6.9.13.1 6.9.13.2 6.9.2 6.9.3 6.9.4 6.9.5 6.9.6 6.9.7 6.9.8 6.9.9 7.0.0 7.0.2 7.0.2.1 7.0.2.2 7.0.2.3 7.0.3 7.1.0 7.1.1 7.1.2 7.1.3 7.1.4 7.1.5 7.2.0 7.2.1 7.3.0 7.3.1 7.3.2 7.3.3 7.4.0 7.4.2 7.4.4 7.4.5 7.4.6 7.4.7 7.4.8 7.5.0 7.5.1 7.5.2 7.5.3 7.5.4 7.6.0 7.6.1 7.6.1.1 7.6.10 7.6.11 7.6.2 7.6.3 7.6.4 7.6.5 7.6.6 7.6.7 7.6.7.1 7.6.8 7.6.9 7.7.0 7.8.0 7.8.1 7.8.10 7.8.11 7.8.12 7.8.13 7.8.14 7.8.15 7.8.16 7.8.17 7.8.18 7.8.2 7.8.3 7.8.4 7.8.5 7.8.5.1 7.8.6 7.8.7 7.8.8 7.8.9 7.9.0 7.9.1 7.9.10 7.9.11 7.9.2 7.9.3 7.9.4 7.9.5 7.9.6 7.9.7 7.9.8 7.9.9 8.0.0 8.0.1 8.0.2 8.0.3 8.0.4 8.0.5 8.0.6 8.0.7 8.0.8 8.1.0 8.1.1 8.1.2 8.1.3 8.1.4 8.2.0 trunk 1.0.0 1.1.0 1.2.0 1.3.0 1.4.0 1.5.0 1.6.0 1.7.0 1.8.0 1.9.0 2.0.0 2.1.0 2.2.0 2.3.0 2.4.0 2.5.0 2.6.0 2.7.0 2.8.0 2.8.1 2.8.2 2.8.3 2.9.0 3.0.0 3.0.1 3.0.2 3.0.3 3.0.4 3.0.5 3.0.6 3.1.0 3.2.0 3.3.0 3.4.0 3.5.0 3.6.1 3.7.0 3.8.0 3.9.0 3.9.1 3.9.2 4.0.0 4.0.1 4.1.0 4.2.0 4.2.1 4.2.2 4.3.0 4.3.1 4.4.0 4.5.0 4.6.0 4.7.0 4.7.1 4.7.2 4.7.3 4.7.4 4.8.0 4.8.1 4.8.2 4.8.3 4.9.0 4.9.1 4.9.2 4.9.3 5.0.0
admin-site-enhancements / classes / class-content-order.php
admin-site-enhancements / classes Last commit date
class-activation.php 1 year ago class-admin-menu-organizer.php 1 year ago class-auto-publish-posts-with-missed-schedule.php 1 year ago class-avif-upload.php 1 year ago class-captcha-protection.php 1 year ago class-change-login-url.php 1 year ago class-cleanup-admin-bar.php 1 year ago class-common-methods.php 1 year ago class-content-duplication.php 1 year ago class-content-order.php 1 year ago class-custom-admin-footer-text.php 1 year ago class-custom-body-class.php 1 year ago class-custom-css.php 1 year ago class-custom-nav-menu-items-in-new-tab.php 1 year ago class-deactivation.php 1 year ago class-disable-author-archives.php 1 year ago class-disable-comments.php 1 year ago class-disable-dashboard-widgets.php 1 year ago class-disable-feeds.php 1 year ago class-disable-gutenberg.php 1 year ago class-disable-rest-api.php 1 year ago class-disable-smaller-components.php 1 year ago class-disable-updates.php 1 year ago class-disable-xml-rpc.php 1 year ago class-display-system-summary.php 1 year ago class-email-address-obfuscator.php 1 year ago class-email-delivery.php 1 year ago class-enhance-list-tables.php 1 year ago class-external-permalinks.php 1 year ago class-heartbeat-control.php 1 year ago class-hide-admin-bar.php 1 year ago class-hide-admin-notices.php 1 year ago class-image-sizes-panel.php 1 year ago class-image-upload-control.php 1 year ago class-insert-head-body-footer-code.php 1 year ago class-last-login-column.php 1 year ago class-limit-login-attempts.php 1 year ago class-login-id-type.php 1 year ago class-login-logout-menu.php 1 year ago class-maintenance-mode.php 1 year ago class-manage-ads-appads-txt.php 1 year ago class-manage-robots-txt.php 1 year ago class-media-replacement.php 1 year ago class-multiple-user-roles.php 1 year ago class-obfuscate-author-slugs.php 1 year ago class-open-external-links-in-new-tab.php 1 year ago class-password-protection.php 1 year ago class-redirect-after-login.php 1 year ago class-redirect-after-logout.php 1 year ago class-redirect-fourofour.php 1 year ago class-registration-date-column.php 1 year ago class-revisions-control.php 1 year ago class-search-engines-visibility.php 1 year ago class-settings-fields-render.php 1 year ago class-settings-sanitization.php 1 year ago class-settings-sections-fields.php 1 year ago class-show-custom-taxonomy-filters.php 1 year ago class-site-identity-on-login-page.php 1 year ago class-svg-upload.php 1 year ago class-various-admin-ui-enhancements.php 1 year ago class-view-admin-as-role.php 1 year ago class-wider-admin-menu.php 1 year ago class-wp-config-transformer.php 1 year ago
class-content-order.php
597 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 * Add "Custom Order" sub-menu for post types
14 *
15 * @since 5.0.0
16 */
17 public function add_content_order_submenu( $context ) {
18 $options = get_option( ASENHA_SLUG_U, array() );
19 $content_order_for = ( isset( $options['content_order_for'] ) ? $options['content_order_for'] : array() );
20 $content_order_enabled_post_types = array();
21 if ( is_array( $content_order_for ) && count( $content_order_for ) > 0 ) {
22 foreach ( $content_order_for as $post_type_slug => $is_custom_order_enabled ) {
23 if ( $is_custom_order_enabled ) {
24 $post_type_object = get_post_type_object( $post_type_slug );
25 if ( is_object( $post_type_object ) && property_exists( $post_type_object, 'labels' ) ) {
26 $post_type_name_plural = $post_type_object->labels->name;
27 if ( 'post' == $post_type_slug ) {
28 $hook_suffix = add_posts_page(
29 $post_type_name_plural . ' Order',
30 // Page title
31 __( 'Order', 'admin-site-enhancements' ),
32 // Menu title
33 'edit_others_posts',
34 // Capability required
35 'custom-order-posts',
36 // Menu and page slug
37 [$this, 'custom_order_page_output']
38 );
39 } else {
40 if ( 'sfwd-courses' == $post_type_slug ) {
41 // LearnDash LMS Courses
42 // Add 'Order' submenu item under LearnDash menu
43 // Linked URL will be /wp-admin/admin.php?page=custom-order-sfwd-courses
44 // We will add a redirect to the correct URL via $this->maybe_perform_menu_link_redirects() hooked in admin_init
45 $hook_suffix = add_submenu_page(
46 'learndash-lms',
47 // Parent (menu) slug. Ref: https://developer.wordpress.org/reference/functions/add_submenu_page/#comment-1404
48 $post_type_name_plural . ' ' . __( 'Order', 'admin-site-enhancements' ),
49 // Page title
50 $post_type_name_plural . ' ' . __( 'Order', 'admin-site-enhancements' ),
51 // Menu title
52 'edit_others_posts',
53 // Capability required
54 'custom-order-' . $post_type_slug,
55 // Menu and page slug
56 [$this, 'custom_order_page_output'],
57 // Callback function that outputs page content
58 9999
59 );
60 // Add the actual, functional 'Order' submenu page at /edit.php?post_type=sfwd-courses&page=custom-order-sfwd-courses
61 // 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
62 $hook_suffix = add_submenu_page(
63 'edit.php?post_type=' . $post_type_slug,
64 // Parent (menu) slug. Ref: https://developer.wordpress.org/reference/functions/add_submenu_page/#comment-1404
65 // 'learndash-lms', // Parent (menu) slug. Ref: https://developer.wordpress.org/reference/functions/add_submenu_page/#comment-1404
66 $post_type_name_plural . ' ' . __( 'Order', 'admin-site-enhancements' ),
67 // Page title
68 $post_type_name_plural . ' ' . __( 'Order', 'admin-site-enhancements' ),
69 // Menu title
70 'edit_others_posts',
71 // Capability required
72 'custom-order-' . $post_type_slug,
73 // Menu and page slug
74 [$this, 'custom_order_page_output'],
75 // Callback function that outputs page content
76 9999
77 );
78 } else {
79 $hook_suffix = add_submenu_page(
80 'edit.php?post_type=' . $post_type_slug,
81 // Parent (menu) slug. Ref: https://developer.wordpress.org/reference/functions/add_submenu_page/#comment-1404
82 $post_type_name_plural . ' Order',
83 // Page title
84 __( 'Order', 'admin-site-enhancements' ),
85 // Menu title
86 'edit_others_posts',
87 // Capability required
88 'custom-order-' . $post_type_slug,
89 // Menu and page slug
90 [$this, 'custom_order_page_output'],
91 // Callback function that outputs page content
92 9999
93 );
94 }
95 }
96 add_action( 'admin_print_styles-' . $hook_suffix, [$this, 'enqueue_content_order_styles'] );
97 add_action( 'admin_print_scripts-' . $hook_suffix, [$this, 'enqueue_content_order_scripts'] );
98 }
99 }
100 }
101 }
102 }
103
104 /**
105 * Add additinal HTML elements on list tables
106 *
107 * @since 7.6.10
108 */
109 public function add_additional_elements() {
110 global $pagenow, $typenow;
111 $common_methods = new Common_Methods();
112 $options = get_option( ASENHA_SLUG_U, array() );
113 $content_order_for = ( isset( $options['content_order_for'] ) ? $options['content_order_for'] : array() );
114 $content_order_enabled_post_types = $common_methods->get_array_of_keys_with_true_value( $content_order_for );
115 $content_order_other_enabled_post_types = array();
116 // List tables of pages, posts and CPTs. Administrators and Editors only.
117 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 )) ) {
118 // Add "Order" button
119 if ( 'post' == $typenow ) {
120 $typenow = 'posts';
121 }
122 ?>
123 <div id="content-order-button">
124 <a class="button" href="<?php
125 echo esc_url( get_admin_url() );
126 ?>edit.php?post_type=<?php
127 echo esc_attr( $typenow );
128 ?>&page=custom-order-<?php
129 echo esc_attr( $typenow );
130 ?>"><?php
131 _e( 'Order', 'admin-site-enhancements' );
132 ?></a>
133 </div>
134 <?php
135 }
136 }
137
138 /**
139 * Add scripts for content list tables
140 *
141 * @since 7.6.10
142 */
143 public function add_list_tables_scripts( $hook_suffix ) {
144 global $pagenow, $typenow;
145 $common_methods = new Common_Methods();
146 $options = get_option( ASENHA_SLUG_U, array() );
147 $content_order_for = ( isset( $options['content_order_for'] ) ? $options['content_order_for'] : array() );
148 $content_order_enabled_post_types = $common_methods->get_array_of_keys_with_true_value( $content_order_for );
149 $content_order_other_enabled_post_types = array();
150 // List tables of pages, posts and CPTs
151 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 )) ) {
152 wp_enqueue_style(
153 'asenha-list-tables-content-order',
154 ASENHA_URL . 'assets/css/list-tables-content-order.css',
155 array(),
156 ASENHA_VERSION
157 );
158 wp_enqueue_script(
159 'asenha-list-tables-content-order',
160 ASENHA_URL . 'assets/js/list-tables-content-order.js',
161 array('jquery'),
162 ASENHA_VERSION,
163 false
164 );
165 }
166 }
167
168 /**
169 * Maybe perform redirects from the 'Order' submenu link
170 *
171 * @since 7.6.9
172 */
173 public function maybe_perform_menu_link_redirects() {
174 $request_uri = sanitize_text_field( $_SERVER['REQUEST_URI'] );
175 // e.g. /wp-admin/index.php?page=page-slug
176 // Redirect for LearnDash LMS Courses post type ('sfwd-courses')
177 if ( in_array( 'sfwd-lms/sfwd_lms.php', get_option( 'active_plugins', array() ) ) ) {
178 if ( false !== strpos( $request_uri, 'admin.php?page=custom-order-sfwd-courses' ) ) {
179 wp_safe_redirect( get_admin_url() . 'edit.php?post_type=sfwd-courses&page=custom-order-sfwd-courses' );
180 exit;
181 }
182 }
183 }
184
185 /**
186 * Output content for the custom order page for each enabled post types
187 * Not using settings API because all done via AJAX
188 *
189 * @since 5.0.0
190 */
191 public function custom_order_page_output() {
192 $post_status = array(
193 'publish',
194 'future',
195 'draft',
196 'pending',
197 'private'
198 );
199 $parent_slug = get_admin_page_parent();
200 if ( 'edit.php' == $parent_slug ) {
201 $post_type_slug = 'post';
202 } elseif ( 'upload.php' == $parent_slug ) {
203 $post_type_slug = 'attachment';
204 $post_status = array('inherit', 'private');
205 } else {
206 $post_type_slug = str_replace( 'edit.php?post_type=', '', $parent_slug );
207 }
208 // Object with properties for each post status and the count of posts for each status
209 // $post_count_object = wp_count_posts( $post_type_slug );
210 // Number of items with the status 'publish(ed)', 'future' (scheduled), 'draft', 'pending' and 'private'
211 // $post_count = absint( $post_count_object->publish )
212 // + absint( $post_count_object->future )
213 // + absint( $post_count_object->draft )
214 // + absint( $post_count_object->pending )
215 // + absint( $post_count_object->private );
216 ?>
217 <div class="wrap">
218 <div class="page-header">
219 <h2>
220 <?php
221 echo esc_html( get_admin_page_title() );
222 ?>
223 </h2>
224 <div id="toggles" style="display:none;">
225 <input type="checkbox" id="toggle-taxonomy-terms" name="terms" value="" /><label for="toggle-taxonomy-terms">Show taxonomy terms</label>
226 <input type="checkbox" id="toggle-excerpt" name="excerpt" value="" /><label for="toggle-excerpt">Show excerpt</label>
227 </div>
228 </div>
229 <?php
230 // Get posts
231 $args = array(
232 'post_type' => $post_type_slug,
233 'numberposts' => -1,
234 'orderby' => 'menu_order title',
235 'order' => 'ASC',
236 'post_status' => $post_status,
237 );
238 // Add the following to non-attachment post types
239 if ( 'attachment' != $post_type_slug && is_post_type_hierarchical( $post_type_slug ) ) {
240 // In hierarchical post types, only return non-child posts as we currently only sort parent posts
241 $args['post_parent'] = 0;
242 }
243 $posts = get_posts( $args );
244 if ( !empty( $posts ) ) {
245 ?>
246 <ul id="item-list">
247 <?php
248 foreach ( $posts as $post ) {
249 $this->custom_order_single_item_output( $post );
250 }
251 ?>
252 </ul>
253 <div id="updating-order-notice" class="updating-order-notice" style="display: none;"><img src="<?php
254 echo esc_attr( ASENHA_URL ) . 'assets/img/oval.svg';
255 ?>" id="spinner-img" class="spinner-img" /><span class="dashicons dashicons-saved" style="display:none;"></span>Updating order...</div>
256 <?php
257 } else {
258 ?>
259 <h3>There is nothing to sort for this post type.</h3>
260 <?php
261 }
262 ?>
263 </div> <!-- End of div.wrap -->
264 <?php
265 }
266
267 /**
268 * Output single item sortable for custom content order
269 *
270 * @since 5.0.0
271 */
272 private function custom_order_single_item_output( $post ) {
273 if ( is_post_type_hierarchical( $post->post_type ) ) {
274 $post_type_object = get_post_type_object( $post->post_type );
275 $children = get_pages( array(
276 'child_of' => $post->ID,
277 'post_type' => $post->post_type,
278 ) );
279 if ( count( $children ) > 0 ) {
280 $has_child_label = '<span class="has-child-label"> <span class="dashicons dashicons-arrow-right"></span> Has child ' . strtolower( $post_type_object->label ) . '</span>';
281 $has_child = 'true';
282 } else {
283 $has_child_label = '';
284 $has_child = 'false';
285 }
286 } else {
287 $has_child_label = '';
288 $has_child = 'false';
289 }
290 $post_status_label_class = ( $post->post_status == 'publish' ? ' item-status-hidden' : '' );
291 $post_status_object = get_post_status_object( $post->post_status );
292 if ( 'attachment' == $post->post_type ) {
293 $post_status_label_separator = '';
294 $post_status_label = '';
295 // Attachments / media only has the post status 'inherit'. Let's not show it.
296 } else {
297 $post_status_label_separator = '';
298 $post_status_label = $post_status_object->label;
299 }
300 if ( empty( wp_trim_excerpt( $post->post_excerpt, $post ) ) ) {
301 $short_excerpt = '';
302 } else {
303 $excerpt_trimmed = implode( " ", array_slice( explode( " ", wp_trim_excerpt( $post->post_excerpt, $post ) ), 0, 30 ) );
304 $short_excerpt = '<span class="item-excerpt"> | ' . $excerpt_trimmed . '</span>';
305 }
306 $taxonomies = get_object_taxonomies( $post->post_type, 'objects' );
307 // vi( $taxonomies );
308 $taxonomies_and_terms = '';
309 foreach ( $taxonomies as $taxonomy ) {
310 $terms = array();
311 if ( $taxonomy->hierarchical ) {
312 $taxonomy_terms = get_the_terms( $post->ID, $taxonomy->name );
313 if ( is_array( $taxonomy_terms ) && !empty( $taxonomy_terms ) ) {
314 foreach ( $taxonomy_terms as $term ) {
315 $terms[] = $term->name;
316 }
317 }
318 }
319 $terms = implode( ', ', $terms );
320 $taxonomies_and_terms .= ' | ' . $taxonomy->label . ': ' . $terms;
321 }
322 if ( !empty( $taxonomies_and_terms ) ) {
323 $taxonomies_and_terms = '<span class="item-taxonomy-terms">' . $taxonomies_and_terms . '</span>';
324 }
325 // If WPML plugin is active, let's get the current language
326 if ( in_array( 'sitepress-multilingual-cms/sitepress.php', get_option( 'active_plugins', array() ) ) ) {
327 $current_language = apply_filters( 'wpml_current_language', null );
328 $current_post_language_info = apply_filters( 'wpml_post_language_details', null, $post->ID );
329 if ( !is_wp_error( $current_post_language_info ) ) {
330 $current_post_language = $current_post_language_info['language_code'];
331 } else {
332 // wpml has not set language information for the post
333 // e.g. post is not translated yet, so, let's use the current site/admin language
334 $current_post_language = $current_language;
335 }
336 $same_language = $current_language === $current_post_language;
337 // true if language is the same, false otherwise
338 } else {
339 // WPML is not active, $same_language is always true, e.g. all posts are in English
340 $same_language = true;
341 }
342 // Only render sortable for posts that have the same language as the current chosen language
343 if ( $same_language ) {
344 ?>
345 <li id="list_<?php
346 echo esc_attr( $post->ID );
347 ?>" data-id="<?php
348 echo esc_attr( $post->ID );
349 ?>" data-menu-order="<?php
350 echo esc_attr( $post->menu_order );
351 ?>" data-parent="<?php
352 echo esc_attr( $post->post_parent );
353 ?>" data-has-child="<?php
354 echo esc_attr( $has_child );
355 ?>" data-post-type="<?php
356 echo esc_attr( $post->post_type );
357 ?>">
358 <div class="row">
359 <div class="row-content">
360 <?php
361 echo '<div class="content-main">
362 <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>
363 </div>';
364 if ( !in_array( $post->post_type, array('asenha_code_snippet') ) ) {
365 echo '<div class="content-additional">
366 <a href="' . esc_attr( get_the_permalink( $post->ID ) ) . '" target="_blank" class="button item-view-link">View</a>
367 </div>';
368 }
369 ?>
370 </div>
371 </div>
372 </li>
373 <?php
374 }
375 // if ( $same_language )
376 }
377
378 /**
379 * Enqueue styles for content order pages
380 *
381 * @since 5.0.0
382 */
383 public function enqueue_content_order_styles() {
384 wp_enqueue_style(
385 'content-order-style',
386 ASENHA_URL . 'assets/css/content-order.css',
387 array(),
388 ASENHA_VERSION
389 );
390 }
391
392 /**
393 * Enqueue scripts for content order pages
394 *
395 * @since 5.0.0
396 */
397 public function enqueue_content_order_scripts() {
398 global $typenow;
399 wp_enqueue_script(
400 'content-order-jquery-ui-touch-punch',
401 ASENHA_URL . 'assets/js/jquery.ui.touch-punch.min.js',
402 array('jquery-ui-sortable'),
403 '0.2.3',
404 true
405 );
406 wp_register_script(
407 'content-order-nested-sortable',
408 ASENHA_URL . 'assets/js/jquery.mjs.nestedSortable.js',
409 array('content-order-jquery-ui-touch-punch'),
410 '2.0.0',
411 true
412 );
413 wp_enqueue_script(
414 'content-order-sort',
415 ASENHA_URL . 'assets/js/content-order-sort.js',
416 array('content-order-nested-sortable'),
417 ASENHA_VERSION,
418 true
419 );
420 wp_localize_script( 'content-order-sort', 'contentOrderSort', array(
421 'action' => 'save_custom_order',
422 'nonce' => wp_create_nonce( 'order_sorting_nonce' ),
423 'hirarchical' => ( is_post_type_hierarchical( $typenow ) ? 'true' : 'false' ),
424 ) );
425 }
426
427 /**
428 * Save custom content order coming from ajax call
429 *
430 * @since 5.0.0
431 */
432 public function save_custom_content_order() {
433 global $wpdb;
434 // Check user capabilities
435 if ( !current_user_can( 'edit_others_posts' ) ) {
436 wp_send_json( 'Something went wrong.' );
437 }
438 // Verify nonce
439 if ( !wp_verify_nonce( $_POST['nonce'], 'order_sorting_nonce' ) ) {
440 wp_send_json( 'Something went wrong.' );
441 }
442 // Get ajax variables
443 $action = ( isset( $_POST['action'] ) ? $_POST['action'] : '' );
444 // Item parent is currently 0, as we only handle sorting of non-child posts
445 $item_parent = ( isset( $_POST['item_parent'] ) ? absint( $_POST['item_parent'] ) : 0 );
446 $menu_order_start = ( isset( $_POST['start'] ) ? absint( $_POST['start'] ) : 0 );
447 $post_id = ( isset( $_POST['post_id'] ) ? absint( $_POST['post_id'] ) : 0 );
448 $item_menu_order = ( isset( $_POST['menu_order'] ) ? absint( $_POST['menu_order'] ) : 0 );
449 $items_to_exclude = ( isset( $_POST['excluded_items'] ) ? absint( $_POST['excluded_items'] ) : array() );
450 $post_type = ( isset( $_POST['post_type'] ) ? $_POST['post_type'] : false );
451 // Make processing faster by removing certain actions
452 remove_action( 'pre_post_update', 'wp_save_post_revision' );
453 // $response array for ajax response
454 $response = array();
455 // Update the item whose order/position was moved
456 if ( $post_id > 0 && !isset( $_POST['more_posts'] ) ) {
457 // https://developer.wordpress.org/reference/classes/wpdb/update/
458 $wpdb->update(
459 $wpdb->posts,
460 // The table
461 array(
462 'menu_order' => $item_menu_order,
463 ),
464 array(
465 'ID' => $post_id,
466 )
467 );
468 clean_post_cache( $post_id );
469 $items_to_exclude[] = $post_id;
470 }
471 if ( 'attachment' == $post_type ) {
472 $post_status = array('inherit', 'private');
473 } else {
474 $post_status = array(
475 'publish',
476 'future',
477 'draft',
478 'pending',
479 'private'
480 );
481 }
482 // Get all posts from the post type related to ajax request
483 $query_args = array(
484 'post_type' => $post_type,
485 'orderby' => 'menu_order title',
486 'order' => 'ASC',
487 'posts_per_page' => -1,
488 'suppress_filters' => true,
489 'ignore_sticky_posts' => true,
490 'post_status' => $post_status,
491 'post__not_in' => $items_to_exclude,
492 'update_post_term_cache' => false,
493 'update_post_meta_cache' => false,
494 );
495 if ( 'attachment' == $post_type ) {
496 // do nothing, we do not add post_parent parameter as media items can be attached to other posts, making them the parent.
497 } else {
498 // Item parent is currently 0, as we only handle sorting of non-child posts
499 $query_args['post_parent'] = $item_parent;
500 }
501 $posts = new WP_Query($query_args);
502 if ( $posts->have_posts() ) {
503 // Iterate through posts and update menu order and post parent
504 foreach ( $posts->posts as $post ) {
505 // If the $post is the one being displaced (shited downward) by the moved item, increment it's menu_order by one
506 if ( $menu_order_start == $item_menu_order && $post_id > 0 ) {
507 $menu_order_start++;
508 }
509 // Only process posts other than the moved item, which has been processed earlier outside this loop
510 if ( $post_id != $post->ID ) {
511 // Update menu_order
512 $wpdb->update( $wpdb->posts, array(
513 'menu_order' => $menu_order_start,
514 ), array(
515 'ID' => $post->ID,
516 ) );
517 clean_post_cache( $post->ID );
518 }
519 $items_to_exclude[] = $post->ID;
520 $menu_order_start++;
521 }
522 die( json_encode( $response ) );
523 } else {
524 die( json_encode( $response ) );
525 }
526 }
527
528 /**
529 * Set default ordering of list tables of sortable post types by 'menu_order'
530 *
531 * @link https://developer.wordpress.org/reference/classes/wp_query/#methods
532 * @since 5.0.0
533 */
534 public function orderby_menu_order( $query ) {
535 global $pagenow, $typenow;
536 $query_post_type = $query->get( 'post_type' );
537 $options = get_option( ASENHA_SLUG_U, array() );
538 // Hierarchical post types that should be custom ordered
539 $content_order_for = ( isset( $options['content_order_for'] ) ? $options['content_order_for'] : array() );
540 $content_order_enabled_post_types = array();
541 if ( is_array( $content_order_for ) && count( $content_order_for ) > 0 ) {
542 foreach ( $content_order_for as $post_type_slug => $is_custom_order_enabled ) {
543 if ( $is_custom_order_enabled ) {
544 $content_order_enabled_post_types[] = $post_type_slug;
545 }
546 }
547 }
548 $should_be_custom_sorted = false;
549 // All post types that should be custom ordered
550 $content_order_post_types = $content_order_enabled_post_types;
551 // Use custom order in wp-admin listing pages/tables for enabled post types
552 if ( is_admin() && ('edit.php' == $pagenow || 'upload.php' == $pagenow) && !isset( $_GET['orderby'] ) ) {
553 if ( in_array( $typenow, $content_order_post_types ) ) {
554 $query->set( 'orderby', 'menu_order title' );
555 $query->set( 'order', 'ASC' );
556 }
557 }
558 }
559
560 /**
561 * Make sure newly created posts are assigned the highest menu_order so it's added at the bottom of the existing order
562 *
563 * @since 6.2.1
564 */
565 public function set_menu_order_for_new_posts( $post_id, $post, $update ) {
566 $options = get_option( ASENHA_SLUG_U, array() );
567 $content_order_for = ( isset( $options['content_order_for'] ) ? $options['content_order_for'] : array() );
568 $content_order_enabled_post_types = array();
569 if ( is_array( $content_order_for ) && count( $content_order_for ) > 0 ) {
570 foreach ( $content_order_for as $post_type_slug => $is_custom_order_enabled ) {
571 if ( $is_custom_order_enabled ) {
572 $content_order_enabled_post_types[] = $post_type_slug;
573 }
574 }
575 }
576 // Only assign menu_order if there are none assigned when creating the post, i.e. menu_order is 0
577 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 ) {
578 $post_with_highest_menu_order = get_posts( array(
579 'post_type' => $post->post_type,
580 'posts_per_page' => 1,
581 'orderby' => 'menu_order',
582 'order' => 'DESC',
583 ) );
584 if ( $post_with_highest_menu_order ) {
585 $new_menu_order = (int) $post_with_highest_menu_order[0]->menu_order + 1;
586 // Assign the one higher menu_order to the new post
587 $args = array(
588 'ID' => $post_id,
589 'menu_order' => $new_menu_order,
590 );
591 wp_update_post( $args );
592 }
593 }
594 }
595
596 }
597