is_main_query() ) { return $clauses; } if ( 'mlsimport_property' !== $query->get( 'post_type' ) || 'mlsimport_featured' !== $query->get( 'orderby' ) ) { return $clauses; } global $wpdb; $clauses['join'] .= $wpdb->prepare( " LEFT JOIN {$wpdb->postmeta} mlsimport_featured_pm ON ( {$wpdb->posts}.ID = mlsimport_featured_pm.post_id AND mlsimport_featured_pm.meta_key = %s )", self::META ); $order = ( 'ASC' === strtoupper( (string) $query->get( 'order' ) ) ) ? 'ASC' : 'DESC'; $clauses['orderby'] = "( mlsimport_featured_pm.meta_value = '1' ) $order, {$wpdb->posts}.post_date DESC"; return $clauses; } /** * Offer the two bulk actions in the Properties list dropdown. * * @param array $actions Bulk actions (key => label). * @return array */ public static function bulk_actions( $actions ): array { $actions = (array) $actions; $actions['mlsimport_mark_featured'] = __( 'Mark featured', 'mlsimport' ); $actions['mlsimport_remove_featured'] = __( 'Remove featured', 'mlsimport' ); return $actions; } /** * Apply "Mark featured" / "Remove featured" to the ticked listings. * * WordPress has already verified the bulk nonce and that the user may edit * this post type before calling the filter; each post is still checked * individually so a listing the user cannot edit is skipped. * * @param string $redirect Where WordPress sends the browser afterwards. * @param string $action The chosen bulk action key. * @param array $post_ids The ticked post IDs. * @return string The redirect URL, carrying the changed count for notice(). */ public static function handle_bulk( $redirect, $action, $post_ids ) { // Step 1: leave every bulk action that is not ours untouched. if ( 'mlsimport_mark_featured' !== $action && 'mlsimport_remove_featured' !== $action ) { return $redirect; } $value = 'mlsimport_mark_featured' === $action ? '1' : ''; $changed = 0; foreach ( (array) $post_ids as $post_id ) { $post_id = (int) $post_id; // Step 2: only our post type, and only listings this user may edit. The // capability check is skipped under WP-CLI, which has no current user. if ( 'mlsimport_property' !== get_post_type( $post_id ) ) { continue; } if ( ! ( defined( 'WP_CLI' ) && WP_CLI ) && ! current_user_can( 'edit_post', $post_id ) ) { continue; } // Step 3: write the same meta the edit-screen checkbox writes... update_post_meta( $post_id, self::META, $value ); // Step 4: ...then re-index, which is what moves the flag into the fast // listings table the front end sorts and badges from. if ( class_exists( 'Mlsimport_Standalone_Reindex' ) ) { Mlsimport_Standalone_Reindex::rebuild_post( $post_id ); } ++$changed; /** Fires after a listing's featured flag changed from the list screen. @since 7.2.2 */ do_action( 'mlsimport_property_featured_changed', $post_id, '1' === $value ); } // Step 5: hand the count to notice() through the redirect URL. return add_query_arg( 'mlsimport_featured_changed', $changed, (string) $redirect ); } /** * Confirm a finished bulk action on the Properties list. * * @return void */ public static function notice(): void { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- read-only count for a notice. if ( ! isset( $_GET['mlsimport_featured_changed'] ) ) { return; } // phpcs:ignore WordPress.Security.NonceVerification.Recommended $count = absint( wp_unslash( $_GET['mlsimport_featured_changed'] ) ); /* translators: %s: number of listings. */ $text = sprintf( _n( '%s listing updated.', '%s listings updated.', $count, 'mlsimport' ), number_format_i18n( $count ) ); echo '

' . esc_html( $text ) . '

'; } /** * Add the Featured column just before the native Date column. * * @param array $columns Columns (key => label). * @return array */ public static function columns( $columns ): array { $out = array(); foreach ( (array) $columns as $key => $label ) { // Slot ours in immediately ahead of Date. if ( 'date' === $key ) { $out['mlsimport_featured'] = esc_html__( 'Featured', 'mlsimport' ); } $out[ $key ] = $label; } // No Date column on this screen (hidden by another plugin): append at the end. if ( ! isset( $out['mlsimport_featured'] ) ) { $out['mlsimport_featured'] = esc_html__( 'Featured', 'mlsimport' ); } return $out; } /** * Render the Featured cell: a star + "Featured" for a flagged listing, a dash * (WordPress's usual "nothing here") otherwise. * * @param string $column Column key. * @param int $post_id Property post ID. * @return void */ public static function render( $column, $post_id ): void { if ( 'mlsimport_featured' !== $column ) { return; } if ( '1' === (string) get_post_meta( $post_id, self::META, true ) ) { echo ' ' . esc_html__( 'Featured', 'mlsimport' ); return; } echo ''; } }