4 ], $atts, 'minds_featured_projects' );
$limit = max( 1, min( 12, (int) $atts['limit'] ) );
$projects = $this->get_featured_projects( $limit );
if ( empty( $projects ) ) {
return '
' . esc_html__( 'No featured projects found.', 'academiccrew' ) . '
';
}
ob_start();
echo '';
foreach ( $projects as $p ) {
$this->render_row( $p );
}
echo '';
return ob_get_clean();
}
// -------------------------------------------------------------------------
// Data
// -------------------------------------------------------------------------
private function get_featured_projects( int $limit ): array {
$all = get_posts( [
'post_type' => 'acc_collaboration',
'post_status' => 'publish',
'posts_per_page' => -1,
'meta_query' => [ [ 'key' => '_acc_featured', 'value' => '1', 'compare' => '=' ] ],
'meta_key' => '_acc_featured_order',
'orderby' => 'meta_value_num',
'order' => 'ASC',
] );
// Anchor slots: first industrial → first scientific → rest by order.
$industrial = null;
$scientific = null;
$rest = [];
foreach ( $all as $post ) {
$type = (string) get_post_meta( $post->ID, '_acc_project_type', true );
if ( ! $industrial && $type === 'industrial' ) {
$industrial = $post;
} elseif ( ! $scientific && $type === 'scientific' ) {
$scientific = $post;
} else {
$rest[] = $post;
}
}
$ordered = array_filter( array_merge(
[ $industrial, $scientific ],
$rest
) );
return array_map( [ $this, 'prepare' ], array_slice( array_values( $ordered ), 0, $limit ) );
}
private function prepare( \WP_Post $post ): array {
$get = fn( string $k ) => get_post_meta( $post->ID, $k, true );
$start = (string) ( $get( '_acc_start_date' ) ?: '' );
$end = (string) ( $get( '_acc_end_date' ) ?: '' );
$kw = $get( '_acc_keywords' );
$start_y = $start ? (int) date_i18n( 'Y', strtotime( $start ) ) : 0;
$end_y = $end ? (int) date_i18n( 'Y', strtotime( $end ) ) : 0;
if ( $start_y && $end_y && $start_y !== $end_y ) {
$year_range = $start_y . "\u{2013}" . $end_y;
} elseif ( $start_y && $end_y ) {
$year_range = (string) $start_y;
} elseif ( $start_y ) {
$year_range = $start_y . "\u{2013}" . __( 'ongoing', 'academiccrew' );
} else {
$year_range = '';
}
$linked_page = (int) get_post_meta( $post->ID, '_academiccrew_linked_page_id', true );
$url = $linked_page ? get_permalink( $linked_page ) : get_permalink( $post->ID );
$linked = (array) ( $get( '_acc_linked_members' ) ?: [] );
return [
'title' => get_the_title( $post ),
'url' => (string) $url,
'type' => (string) ( $get( '_acc_project_type' ) ?: '' ),
'status' => ( $end && strtotime( $end ) < time() ) ? 'completed' : 'ongoing',
'keywords' => is_array( $kw ) ? array_values( $kw ) : [],
'year_range' => $year_range,
'pi_name' => CollaborationMeta::extract_pi_name( $linked ),
'short_desc' => (string) ( $get( '_acc_short_desc' ) ?: '' ),
];
}
// -------------------------------------------------------------------------
// Markup
// -------------------------------------------------------------------------
private function render_row( array $p ): void {
$status_label = $p['status'] === 'ongoing'
? __( 'Ongoing', 'academiccrew' )
: __( 'Completed', 'academiccrew' );
$href = $p['url'] ? esc_url( $p['url'] ) : '#';
?>