PluginProbe ʕ •ᴥ•ʔ
Admin and Site Enhancements (ASE) / 7.8.2
Admin and Site Enhancements (ASE) v7.8.2
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-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
592 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 only.
117 if ( 'edit.php' == $pagenow && current_user_can( 'manage_options' ) && (in_array( $typenow, $content_order_enabled_post_types ) || in_array( $typenow, $content_order_other_enabled_post_types )) ) {
118 // Add "Order" button
119 ?>
120 <div id="content-order-button">
121 <a class="button" href="<?php
122 echo esc_url( get_admin_url() );
123 ?>edit.php?post_type=<?php
124 echo esc_attr( $typenow );
125 ?>&page=custom-order-<?php
126 echo esc_attr( $typenow );
127 ?>"><?php
128 _e( 'Order', 'admin-site-enhancements' );
129 ?></a>
130 </div>
131 <?php
132 }
133 }
134
135 /**
136 * Add scripts for content list tables
137 *
138 * @since 7.6.10
139 */
140 public function add_list_tables_scripts( $hook_suffix ) {
141 global $pagenow, $typenow;
142 $common_methods = new Common_Methods();
143 $options = get_option( ASENHA_SLUG_U, array() );
144 $content_order_for = ( isset( $options['content_order_for'] ) ? $options['content_order_for'] : array() );
145 $content_order_enabled_post_types = $common_methods->get_array_of_keys_with_true_value( $content_order_for );
146 $content_order_other_enabled_post_types = array();
147 // List tables of pages, posts and CPTs
148 if ( 'edit.php' == $hook_suffix && current_user_can( 'manage_options' ) && (in_array( $typenow, $content_order_enabled_post_types ) || in_array( $typenow, $content_order_other_enabled_post_types )) ) {
149 wp_enqueue_style(
150 'asenha-list-tables-content-order',
151 ASENHA_URL . 'assets/css/list-tables-content-order.css',
152 array(),
153 ASENHA_VERSION
154 );
155 wp_enqueue_script(
156 'asenha-list-tables-content-order',
157 ASENHA_URL . 'assets/js/list-tables-content-order.js',
158 array('jquery'),
159 ASENHA_VERSION,
160 false
161 );
162 }
163 }
164
165 /**
166 * Maybe perform redirects from the 'Order' submenu link
167 *
168 * @since 7.6.9
169 */
170 public function maybe_perform_menu_link_redirects() {
171 $request_uri = sanitize_text_field( $_SERVER['REQUEST_URI'] );
172 // e.g. /wp-admin/index.php?page=page-slug
173 // Redirect for LearnDash LMS Courses post type ('sfwd-courses')
174 if ( in_array( 'sfwd-lms/sfwd_lms.php', get_option( 'active_plugins', array() ) ) ) {
175 if ( false !== strpos( $request_uri, 'admin.php?page=custom-order-sfwd-courses' ) ) {
176 wp_safe_redirect( get_admin_url() . 'edit.php?post_type=sfwd-courses&page=custom-order-sfwd-courses' );
177 exit;
178 }
179 }
180 }
181
182 /**
183 * Output content for the custom order page for each enabled post types
184 * Not using settings API because all done via AJAX
185 *
186 * @since 5.0.0
187 */
188 public function custom_order_page_output() {
189 $post_status = array(
190 'publish',
191 'future',
192 'draft',
193 'pending',
194 'private'
195 );
196 $parent_slug = get_admin_page_parent();
197 if ( 'edit.php' == $parent_slug ) {
198 $post_type_slug = 'post';
199 } elseif ( 'upload.php' == $parent_slug ) {
200 $post_type_slug = 'attachment';
201 $post_status = array('inherit', 'private');
202 } else {
203 $post_type_slug = str_replace( 'edit.php?post_type=', '', $parent_slug );
204 }
205 // Object with properties for each post status and the count of posts for each status
206 // $post_count_object = wp_count_posts( $post_type_slug );
207 // Number of items with the status 'publish(ed)', 'future' (scheduled), 'draft', 'pending' and 'private'
208 // $post_count = absint( $post_count_object->publish )
209 // + absint( $post_count_object->future )
210 // + absint( $post_count_object->draft )
211 // + absint( $post_count_object->pending )
212 // + absint( $post_count_object->private );
213 ?>
214 <div class="wrap">
215 <div class="page-header">
216 <h2>
217 <?php
218 echo esc_html( get_admin_page_title() );
219 ?>
220 </h2>
221 <div id="toggles" style="display:none;">
222 <input type="checkbox" id="toggle-taxonomy-terms" name="terms" value="" /><label for="toggle-taxonomy-terms">Show taxonomy terms</label>
223 <input type="checkbox" id="toggle-excerpt" name="excerpt" value="" /><label for="toggle-excerpt">Show excerpt</label>
224 </div>
225 </div>
226 <?php
227 // Get posts
228 $args = array(
229 'post_type' => $post_type_slug,
230 'numberposts' => -1,
231 'orderby' => 'menu_order title',
232 'order' => 'ASC',
233 'post_status' => $post_status,
234 );
235 // Add the following to non-attachment post types
236 if ( 'attachment' != $post_type_slug && is_post_type_hierarchical( $post_type_slug ) ) {
237 // In hierarchical post types, only return non-child posts as we currently only sort parent posts
238 $args['post_parent'] = 0;
239 }
240 $posts = get_posts( $args );
241 if ( !empty( $posts ) ) {
242 ?>
243 <ul id="item-list">
244 <?php
245 foreach ( $posts as $post ) {
246 $this->custom_order_single_item_output( $post );
247 }
248 ?>
249 </ul>
250 <div id="updating-order-notice" class="updating-order-notice" style="display: none;"><img src="<?php
251 echo esc_attr( ASENHA_URL ) . 'assets/img/oval.svg';
252 ?>" id="spinner-img" class="spinner-img" /><span class="dashicons dashicons-saved" style="display:none;"></span>Updating order...</div>
253 <?php
254 } else {
255 ?>
256 <h3>There is nothing to sort for this post type.</h3>
257 <?php
258 }
259 ?>
260 </div> <!-- End of div.wrap -->
261 <?php
262 }
263
264 /**
265 * Output single item sortable for custom content order
266 *
267 * @since 5.0.0
268 */
269 private function custom_order_single_item_output( $post ) {
270 if ( is_post_type_hierarchical( $post->post_type ) ) {
271 $post_type_object = get_post_type_object( $post->post_type );
272 $children = get_pages( array(
273 'child_of' => $post->ID,
274 'post_type' => $post->post_type,
275 ) );
276 if ( count( $children ) > 0 ) {
277 $has_child_label = '<span class="has-child-label"> <span class="dashicons dashicons-arrow-right"></span> Has child ' . strtolower( $post_type_object->label ) . '</span>';
278 $has_child = 'true';
279 } else {
280 $has_child_label = '';
281 $has_child = 'false';
282 }
283 } else {
284 $has_child_label = '';
285 $has_child = 'false';
286 }
287 $post_status_label_class = ( $post->post_status == 'publish' ? ' item-status-hidden' : '' );
288 $post_status_object = get_post_status_object( $post->post_status );
289 if ( 'attachment' == $post->post_type ) {
290 $post_status_label_separator = '';
291 $post_status_label = '';
292 // Attachments / media only has the post status 'inherit'. Let's not show it.
293 } else {
294 $post_status_label_separator = '';
295 $post_status_label = $post_status_object->label;
296 }
297 if ( empty( wp_trim_excerpt( '', $post ) ) ) {
298 $short_excerpt = '';
299 } else {
300 $excerpt_trimmed = implode( " ", array_slice( explode( " ", wp_trim_excerpt( '', $post ) ), 0, 30 ) );
301 $short_excerpt = '<span class="item-excerpt"> | ' . $excerpt_trimmed . '</span>';
302 }
303 $taxonomies = get_object_taxonomies( $post->post_type, 'objects' );
304 // vi( $taxonomies );
305 $taxonomies_and_terms = '';
306 foreach ( $taxonomies as $taxonomy ) {
307 $terms = array();
308 if ( $taxonomy->hierarchical ) {
309 $taxonomy_terms = get_the_terms( $post->ID, $taxonomy->name );
310 if ( is_array( $taxonomy_terms ) && !empty( $taxonomy_terms ) ) {
311 foreach ( $taxonomy_terms as $term ) {
312 $terms[] = $term->name;
313 }
314 }
315 }
316 $terms = implode( ', ', $terms );
317 $taxonomies_and_terms .= ' | ' . $taxonomy->label . ': ' . $terms;
318 }
319 if ( !empty( $taxonomies_and_terms ) ) {
320 $taxonomies_and_terms = '<span class="item-taxonomy-terms">' . $taxonomies_and_terms . '</span>';
321 }
322 // If WPML plugin is active, let's get the current language
323 if ( in_array( 'sitepress-multilingual-cms/sitepress.php', get_option( 'active_plugins', array() ) ) ) {
324 $current_language = apply_filters( 'wpml_current_language', null );
325 $current_post_language_info = apply_filters( 'wpml_post_language_details', null, $post->ID );
326 if ( !is_wp_error( $current_post_language_info ) ) {
327 $current_post_language = $current_post_language_info['language_code'];
328 } else {
329 // wpml has not set language information for the post
330 // e.g. post is not translated yet, so, let's use the current site/admin language
331 $current_post_language = $current_language;
332 }
333 $same_language = $current_language === $current_post_language;
334 // true if language is the same, false otherwise
335 } else {
336 // WPML is not active, $same_language is always true, e.g. all posts are in English
337 $same_language = true;
338 }
339 // Only render sortable for posts that have the same language as the current chosen language
340 if ( $same_language ) {
341 ?>
342 <li id="list_<?php
343 echo esc_attr( $post->ID );
344 ?>" data-id="<?php
345 echo esc_attr( $post->ID );
346 ?>" data-menu-order="<?php
347 echo esc_attr( $post->menu_order );
348 ?>" data-parent="<?php
349 echo esc_attr( $post->post_parent );
350 ?>" data-has-child="<?php
351 echo esc_attr( $has_child );
352 ?>" data-post-type="<?php
353 echo esc_attr( $post->post_type );
354 ?>">
355 <div class="row">
356 <div class="row-content">
357 <?php
358 echo '<div class="content-main">
359 <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>
360 </div>
361 <div class="content-additional">
362 <a href="' . esc_attr( get_the_permalink( $post->ID ) ) . '" target="_blank" class="button item-view-link">View</a>
363 </div>';
364 ?>
365 </div>
366 </div>
367 </li>
368 <?php
369 }
370 // if ( $same_language )
371 }
372
373 /**
374 * Enqueue styles for content order pages
375 *
376 * @since 5.0.0
377 */
378 public function enqueue_content_order_styles() {
379 wp_enqueue_style(
380 'content-order-style',
381 ASENHA_URL . 'assets/css/content-order.css',
382 array(),
383 ASENHA_VERSION
384 );
385 }
386
387 /**
388 * Enqueue scripts for content order pages
389 *
390 * @since 5.0.0
391 */
392 public function enqueue_content_order_scripts() {
393 global $typenow;
394 wp_enqueue_script(
395 'content-order-jquery-ui-touch-punch',
396 ASENHA_URL . 'assets/js/jquery.ui.touch-punch.min.js',
397 array('jquery-ui-sortable'),
398 '0.2.3',
399 true
400 );
401 wp_register_script(
402 'content-order-nested-sortable',
403 ASENHA_URL . 'assets/js/jquery.mjs.nestedSortable.js',
404 array('content-order-jquery-ui-touch-punch'),
405 '2.0.0',
406 true
407 );
408 wp_enqueue_script(
409 'content-order-sort',
410 ASENHA_URL . 'assets/js/content-order-sort.js',
411 array('content-order-nested-sortable'),
412 ASENHA_VERSION,
413 true
414 );
415 wp_localize_script( 'content-order-sort', 'contentOrderSort', array(
416 'action' => 'save_custom_order',
417 'nonce' => wp_create_nonce( 'order_sorting_nonce' ),
418 'hirarchical' => ( is_post_type_hierarchical( $typenow ) ? 'true' : 'false' ),
419 ) );
420 }
421
422 /**
423 * Save custom content order coming from ajax call
424 *
425 * @since 5.0.0
426 */
427 public function save_custom_content_order() {
428 global $wpdb;
429 // Check user capabilities
430 if ( !current_user_can( 'edit_others_posts' ) ) {
431 wp_send_json( 'Something went wrong.' );
432 }
433 // Verify nonce
434 if ( !wp_verify_nonce( $_POST['nonce'], 'order_sorting_nonce' ) ) {
435 wp_send_json( 'Something went wrong.' );
436 }
437 // Get ajax variables
438 $action = ( isset( $_POST['action'] ) ? $_POST['action'] : '' );
439 // Item parent is currently 0, as we only handle sorting of non-child posts
440 $item_parent = ( isset( $_POST['item_parent'] ) ? absint( $_POST['item_parent'] ) : 0 );
441 $menu_order_start = ( isset( $_POST['start'] ) ? absint( $_POST['start'] ) : 0 );
442 $post_id = ( isset( $_POST['post_id'] ) ? absint( $_POST['post_id'] ) : 0 );
443 $item_menu_order = ( isset( $_POST['menu_order'] ) ? absint( $_POST['menu_order'] ) : 0 );
444 $items_to_exclude = ( isset( $_POST['excluded_items'] ) ? absint( $_POST['excluded_items'] ) : array() );
445 $post_type = ( isset( $_POST['post_type'] ) ? $_POST['post_type'] : false );
446 // Make processing faster by removing certain actions
447 remove_action( 'pre_post_update', 'wp_save_post_revision' );
448 // $response array for ajax response
449 $response = array();
450 // Update the item whose order/position was moved
451 if ( $post_id > 0 && !isset( $_POST['more_posts'] ) ) {
452 // https://developer.wordpress.org/reference/classes/wpdb/update/
453 $wpdb->update(
454 $wpdb->posts,
455 // The table
456 array(
457 'menu_order' => $item_menu_order,
458 ),
459 array(
460 'ID' => $post_id,
461 )
462 );
463 clean_post_cache( $post_id );
464 $items_to_exclude[] = $post_id;
465 }
466 if ( 'attachment' == $post_type ) {
467 $post_status = array('inherit', 'private');
468 } else {
469 $post_status = array(
470 'publish',
471 'future',
472 'draft',
473 'pending',
474 'private'
475 );
476 }
477 // Get all posts from the post type related to ajax request
478 $query_args = array(
479 'post_type' => $post_type,
480 'orderby' => 'menu_order title',
481 'order' => 'ASC',
482 'posts_per_page' => -1,
483 'suppress_filters' => true,
484 'ignore_sticky_posts' => true,
485 'post_status' => $post_status,
486 'post__not_in' => $items_to_exclude,
487 'update_post_term_cache' => false,
488 'update_post_meta_cache' => false,
489 );
490 if ( 'attachment' == $post_type ) {
491 // do nothing, we do not add post_parent parameter as media items can be attached to other posts, making them the parent.
492 } else {
493 // Item parent is currently 0, as we only handle sorting of non-child posts
494 $query_args['post_parent'] = $item_parent;
495 }
496 $posts = new WP_Query($query_args);
497 if ( $posts->have_posts() ) {
498 // Iterate through posts and update menu order and post parent
499 foreach ( $posts->posts as $post ) {
500 // If the $post is the one being displaced (shited downward) by the moved item, increment it's menu_order by one
501 if ( $menu_order_start == $item_menu_order && $post_id > 0 ) {
502 $menu_order_start++;
503 }
504 // Only process posts other than the moved item, which has been processed earlier outside this loop
505 if ( $post_id != $post->ID ) {
506 // Update menu_order
507 $wpdb->update( $wpdb->posts, array(
508 'menu_order' => $menu_order_start,
509 ), array(
510 'ID' => $post->ID,
511 ) );
512 clean_post_cache( $post->ID );
513 }
514 $items_to_exclude[] = $post->ID;
515 $menu_order_start++;
516 }
517 die( json_encode( $response ) );
518 } else {
519 die( json_encode( $response ) );
520 }
521 }
522
523 /**
524 * Set default ordering of list tables of sortable post types by 'menu_order'
525 *
526 * @link https://developer.wordpress.org/reference/classes/wp_query/#methods
527 * @since 5.0.0
528 */
529 public function orderby_menu_order( $query ) {
530 global $pagenow, $typenow;
531 $query_post_type = $query->get( 'post_type' );
532 $options = get_option( ASENHA_SLUG_U, array() );
533 // Hierarchical post types that should be custom ordered
534 $content_order_for = ( isset( $options['content_order_for'] ) ? $options['content_order_for'] : array() );
535 $content_order_enabled_post_types = array();
536 if ( is_array( $content_order_for ) && count( $content_order_for ) > 0 ) {
537 foreach ( $content_order_for as $post_type_slug => $is_custom_order_enabled ) {
538 if ( $is_custom_order_enabled ) {
539 $content_order_enabled_post_types[] = $post_type_slug;
540 }
541 }
542 }
543 $should_be_custom_sorted = false;
544 // All post types that should be custom ordered
545 $content_order_post_types = $content_order_enabled_post_types;
546 // Use custom order in wp-admin listing pages/tables for enabled post types
547 if ( is_admin() && ('edit.php' == $pagenow || 'upload.php' == $pagenow) && !isset( $_GET['orderby'] ) ) {
548 if ( in_array( $typenow, $content_order_post_types ) ) {
549 $query->set( 'orderby', 'menu_order title' );
550 $query->set( 'order', 'ASC' );
551 }
552 }
553 }
554
555 /**
556 * Make sure newly created posts are assigned the highest menu_order so it's added at the bottom of the existing order
557 *
558 * @since 6.2.1
559 */
560 public function set_menu_order_for_new_posts( $post_id, $post, $update ) {
561 $options = get_option( ASENHA_SLUG_U, array() );
562 $content_order_for = ( isset( $options['content_order_for'] ) ? $options['content_order_for'] : array() );
563 $content_order_enabled_post_types = array();
564 if ( is_array( $content_order_for ) && count( $content_order_for ) > 0 ) {
565 foreach ( $content_order_for as $post_type_slug => $is_custom_order_enabled ) {
566 if ( $is_custom_order_enabled ) {
567 $content_order_enabled_post_types[] = $post_type_slug;
568 }
569 }
570 }
571 // Only assign menu_order if there are none assigned when creating the post, i.e. menu_order is 0
572 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 ) {
573 $post_with_highest_menu_order = get_posts( array(
574 'post_type' => $post->post_type,
575 'posts_per_page' => 1,
576 'orderby' => 'menu_order',
577 'order' => 'DESC',
578 ) );
579 if ( $post_with_highest_menu_order ) {
580 $new_menu_order = (int) $post_with_highest_menu_order[0]->menu_order + 1;
581 // Assign the one higher menu_order to the new post
582 $args = array(
583 'ID' => $post_id,
584 'menu_order' => $new_menu_order,
585 );
586 wp_update_post( $args );
587 }
588 }
589 }
590
591 }
592