return. if ( empty( $post_types ) ) { return; } foreach ( $post_types as $post_type ) { add_action( "save_post_{$post_type}", [ self::class, 'save_post' ], 10, 2 ); } // add meta box. add_action( 'add_meta_boxes', [ self::class, 'add_meta_boxes' ] ); // add ajax hook. add_action( 'wp_ajax_update-post-order', [ self::class, 'update_post_order' ] ); // load scripts. add_action( 'admin_enqueue_scripts', [ self::class, 'enqueue_scripts' ] ); // sort posts by post order. add_action( 'pre_get_posts', [ self::class, 'order_posts' ] ); // sort for adjacent posts. Adjacent_Post_Order::init(); } /** * Whether the given post type(s) are allowed to be ordered. * * @param string $post_types The post type(s) to check against. * * @return bool */ public static function supports( $post_types = null ) { $post_types ??= get_current_screen()->post_type ?? ''; $post_types = (array) $post_types; foreach ( $post_types as $post_type ) { if ( ! post_type_supports( $post_type, self::$post_type_feature ) ) { return false; } } return true; } /** * Callback for "save_post" action. * * @param int $post_id The post's ID. * @param \WP_Post $post The post object. */ public static function save_post( $post_id, $post ) { if ( ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) || ! check_admin_referer( self::$nonce, self::$nonce ) || ( ! isset( $_POST['post_ID'] ) || intval( $_POST['post_ID'] ) !== intval( $post_id ) ) || ! isset( $_POST[ self::$meta_key ] ) ) { return; } $post_order = sanitize_text_field( wp_unslash( $_POST[ self::$meta_key ] ) ); if ( empty( $post_order ) ) { $post_order = wp_count_posts( $post->post_type )->publish; } update_post_meta( $post_id, self::$meta_key, $post_order ); } /** * Callback for "add_meta_boxes" action. */ public static function add_meta_boxes() { if ( ! self::supports() ) { return; } add_meta_box( 'draggable-post-order', __( 'Post Order', 'draggable-post-order' ), [ self::class, 'add_meta_box' ], '', 'side' ); } /** * Callback for "add_meta_box" function. * * @param \WP_Post $post The post object. */ public static function add_meta_box( $post ) { wp_nonce_field( self::$nonce, self::$nonce ); ?> $post_id ) { $order = intval( $idx ) + 1; update_post_meta( $post_id, self::$meta_key, ( ( $page - 1 ) * $per_page ) + $order ); } } /** * Callback for "admin_enqueue_scripts" action. */ public static function enqueue_scripts() { $current_screen = get_current_screen(); if ( $current_screen->base !== 'edit' || ! self::supports() ) { return; } list('dependencies' => $dependencies, 'version' => $version) = require draggable_post_order_path() . '/build/index.asset.php'; $dependencies[] = 'jquery-ui-sortable'; wp_enqueue_script( 'draggable-post-order', draggable_post_order_assets_url( 'index.js' ), $dependencies, $version, true ); wp_enqueue_style( 'draggable-post-order', draggable_post_order_assets_url( 'index.css' ), [], $version ); wp_localize_script( 'draggable-post-order', 'draggablePostOrder', [ 'nonce' => wp_create_nonce( self::$nonce ), ] ); } /** * Callback for "pre_get_posts" action. * * @param \WP_Query $query The query object. */ public static function order_posts( \WP_Query $query ) { $post_type = $query->get( 'post_type' ); if ( ! self::supports( $post_type ) ) { return; } // if no orderby was set previously. if ( ! $query->get( 'orderby' ) ) { $meta_sub_query = [ 'relation' => 'OR', 'draggable-post-order-clause' => [ 'key' => self::$meta_key, 'type' => 'NUMERIC', ], // get all posts without the meta as well. 'draggable-post-order-exists-clause' => [ 'key' => self::$meta_key, 'compare' => 'NOT EXISTS', ], ]; $meta_query = $query->get( 'meta_query' ) ?: []; $meta_query[] = $meta_sub_query; $order = apply_filters( 'draggable_post_order_order', 'ASC', $post_type, $query ); $orderby = [ 'draggable-post-order-clause' => $order, 'draggable-post-order-exists-clause' => $order, ]; $query->set( 'meta_query', $meta_query ); $query->set( 'orderby', $orderby ); } } }