is_registered( 'senti/roadmap' ) ) { return; } register_block_type( dirname( __DIR__, 2 ) . '/blocks/roadmap', [ 'render_callback' => [ $this, 'render' ] ] ); } /** * @internal * @param array $attributes */ public function render( array $attributes = [] ): string { $stages = get_terms( [ 'taxonomy' => Identifiers::TAXONOMY_ROADMAP_STAGE, 'hide_empty' => false, 'meta_key' => StageProvisioner::position_meta_key(), // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key -- The small stage collection is ordered by explicit position. 'orderby' => 'meta_value_num', 'order' => 'ASC', ] ); if ( is_wp_error( $stages ) || ! is_array( $stages ) ) { return ''; } $posts = get_posts( [ 'post_type' => Identifiers::POST_TYPE_ROADMAP, 'post_status' => 'publish', 'posts_per_page' => -1, 'no_found_rows' => true, ] ); $post_ids = wp_list_pluck( $posts, 'ID' ); if ( ! empty( $post_ids ) ) { update_object_term_cache( $post_ids, [ Identifiers::TAXONOMY_ROADMAP_STAGE, Identifiers::TAXONOMY_PRODUCT ] ); } $by_stage = []; foreach ( $posts as $entry ) { if ( ! $entry instanceof WP_Post ) { continue; } $terms = wp_get_object_terms( $entry->ID, Identifiers::TAXONOMY_ROADMAP_STAGE, [ 'fields' => 'ids' ] ); if ( is_wp_error( $terms ) || empty( $terms ) ) { continue; } foreach ( $terms as $term_id ) { $by_stage[ (int) $term_id ][] = $entry; } } $groups = []; foreach ( $stages as $stage ) { $stage_entries = $by_stage[ $stage->term_id ] ?? []; usort( $stage_entries, static function ( WP_Post $a, WP_Post $b ): int { $pos_a = (int) get_post_meta( $a->ID, Identifiers::META_ROADMAP_POSITION, true ); $pos_b = (int) get_post_meta( $b->ID, Identifiers::META_ROADMAP_POSITION, true ); if ( $pos_a !== $pos_b ) { return $pos_a <=> $pos_b; } return strcasecmp( $a->post_title, $b->post_title ); } ); $groups[] = [ 'stage' => $stage, 'entries' => $stage_entries, ]; } $context = [ 'links' => [ PortalPages::PORTAL => __( 'Overview', 'senti-feedback' ), PortalPages::FEEDBACK => __( 'Feedback', 'senti-feedback' ), PortalPages::ROADMAP => __( 'Roadmap', 'senti-feedback' ), PortalPages::CHANGELOG => __( 'Changelog', 'senti-feedback' ), ], 'pages' => $this->pages, 'active' => PortalPages::ROADMAP, ]; $classes = 'senti-portal-view senti-portal-view--roadmap alignwide'; $wrapper_attrs = function_exists( 'get_block_wrapper_attributes' ) && WP_Block_Supports::$block_to_render !== null ? get_block_wrapper_attributes( [ 'class' => $classes ] ) : 'class="' . esc_attr( $classes ) . '"'; ob_start(); include dirname( __DIR__, 2 ) . '/templates/portal/navigation.php'; include dirname( __DIR__, 2 ) . '/templates/roadmap/grouped-view.php'; $content = (string) ob_get_clean(); return sprintf( '
%s
', $wrapper_attrs, $content ); } }