(string) self::DEFAULT_POSTS, 'titre' => __( 'Derniers articles', 'agentsia-agents' ), 'categorie' => '', 'auteur' => '', ], (array) $atts, self::SHORTCODE ); $count = absint( $atts['nombre'] ); $count = $count > 0 ? min( $count, self::MAX_POSTS ) : self::DEFAULT_POSTS; $post_id = self::current_post_id(); $category = trim( (string) $atts['categorie'] ); $author = trim( (string) $atts['auteur'] ); $args = [ 'post_type' => 'post', 'post_status' => 'publish', 'posts_per_page' => $count, 'ignore_sticky_posts' => true, 'no_found_rows' => true, 'update_post_term_cache' => false, ]; if ( $post_id > 0 ) { $args['post__not_in'] = [ $post_id ]; } if ( $category === '' && $author === '' ) { // Par défaut : l'auteur relié à la page (page de membre réglée depuis Agentsia), sinon la catégorie // qui porte le slug de la page affichée. $post = $post_id > 0 ? get_post( $post_id ) : null; $linked = $post ? (int) get_post_meta( $post->ID, Site_Members::META_PAGE_AUTHOR, true ) : 0; $linked = $linked > 0 && get_userdata( $linked ) instanceof \WP_User ? $linked : 0; $term = $linked === 0 && $post && $post->post_name !== '' ? get_term_by( 'slug', $post->post_name, 'category' ) : false; if ( $linked > 0 ) { $args['author'] = $linked; } elseif ( ! $term instanceof \WP_Term ) { return self::editor_hint( $post_id, $post /* translators: %s: slug of the page. */ ? sprintf( __( 'Derniers articles : aucune catégorie d\'articles n\'a le slug de cette page (« %s »). Crée-la, ou choisis une catégorie ou un auteur dans les réglages du bloc.', 'agentsia-agents' ), $post->post_name ) : __( 'Derniers articles : choisis une catégorie ou un auteur dans les réglages du bloc.', 'agentsia-agents' ) ); } else { $args['cat'] = (int) $term->term_id; } } else { if ( $category !== '' ) { $term = self::category( $category ); if ( ! $term ) { /* translators: %s: category given in the settings. */ return self::editor_hint( $post_id, sprintf( __( 'Derniers articles : catégorie « %s » introuvable.', 'agentsia-agents' ), $category ) ); } $args['cat'] = (int) $term->term_id; } if ( $author !== '' ) { $user = self::author( $author ); if ( ! $user ) { /* translators: %s: author given in the settings. */ return self::editor_hint( $post_id, sprintf( __( 'Derniers articles : auteur « %s » introuvable.', 'agentsia-agents' ), $author ) ); } $args['author'] = (int) $user->ID; } } $query = new \WP_Query( $args ); if ( empty( $query->posts ) ) { return self::editor_hint( $post_id, __( 'Derniers articles : aucun article publié pour le moment.', 'agentsia-agents' ) ); } $items = ''; foreach ( $query->posts as $article ) { $excerpt = self::excerpt_of( $article ); $items .= sprintf( '
  • %2$s %5$s
  • ', esc_url( get_permalink( $article ) ), esc_html( wp_strip_all_tags( get_the_title( $article ) ) ), esc_attr( (string) get_the_date( 'c', $article ) ), esc_html( (string) get_the_date( '', $article ) ), $excerpt !== '' ? '

    ' . esc_html( $excerpt ) . '

    ' : '' ); } $title = trim( (string) $atts['titre'] ); return '
    ' . ( $title !== '' ? '

    ' . esc_html( $title ) . '

    ' : '' ) . '' . '
    '; } /** Catégorie par identifiant (chiffres) ou par slug. */ private static function category( string $value ): ?\WP_Term { $term = preg_match( '/^\d+$/', $value ) ? get_term( (int) $value, 'category' ) : get_term_by( 'slug', sanitize_title( $value ), 'category' ); return $term instanceof \WP_Term ? $term : null; } /** Auteur par identifiant (chiffres) ou par identifiant de connexion. */ private static function author( string $value ): ?\WP_User { $user = preg_match( '/^\d+$/', $value ) ? get_user_by( 'id', (int) $value ) : get_user_by( 'login', $value ); return $user instanceof \WP_User ? $user : null; } /** * Page affichée : l'objet demandé d'une page seule, ou l'article de l'aperçu du bloc dans l'éditeur (rendu * par l'API REST, l'article y est l'objet global). 0 ailleurs (archives, listes…). */ private static function current_post_id(): int { if ( is_singular() ) { return (int) get_queried_object_id(); } if ( self::is_block_preview() ) { return (int) get_the_ID(); } return 0; } /** Rendu de l'aperçu d'un bloc dans l'éditeur (route REST `wp/v2/block-renderer`). */ private static function is_block_preview(): bool { if ( ! ( defined( 'REST_REQUEST' ) && REST_REQUEST ) || ! isset( $GLOBALS['wp'] ) || ! is_object( $GLOBALS['wp'] ) ) { return false; } $route = (string) ( $GLOBALS['wp']->query_vars['rest_route'] ?? '' ); return strpos( $route, '/wp/v2/block-renderer/' ) === 0; } /** * Extrait léger : l'extrait saisi, sinon les premiers mots du contenu (sans shortcodes ni blocs dynamiques), * sans passer par le filtre `the_content` (lourd, et rendu d'autres extensions au milieu de la page). */ private static function excerpt_of( \WP_Post $article ): string { $text = $article->post_excerpt !== '' ? $article->post_excerpt : excerpt_remove_blocks( strip_shortcodes( $article->post_content ) ); return wp_trim_words( wp_strip_all_tags( $text ), self::EXCERPT_WORDS, '…' ); } /** Indication montrée seulement dans l'aperçu de l'éditeur, à qui peut modifier la page ; rien en ligne. */ private static function editor_hint( int $post_id, string $message ): string { if ( ! self::is_block_preview() || ! ( $post_id > 0 ? current_user_can( 'edit_post', $post_id ) : current_user_can( 'edit_posts' ) ) ) { return ''; } return '

    ' . esc_html( $message ) . '

    '; } }