options = $options; } /** * Gets all the post ids linked to a set of posts. * * @since 3.3 * @since 3.4 Parameter changed from int[] to WP_Post[]. * @since 3.5 Renamed from get_linked_post_ids and now returns a WP_Post array. * Also added a second parameter for the post types to retrieve. * * @param WP_Post[] $posts The posts for which searching linked posts. * @param string[] $post_types Limits the linked posts search to these post types. * @return WP_Post[] An array of linked post objects. */ public function get_linked_posts( array $posts, array $post_types ) { $linked_ids = array(); foreach ( $posts as $post ) { $linked_ids = array_merge( $linked_ids, $this->get_post_ids_from_post( $post ) ); } $linked_ids = array_unique( $linked_ids ); if ( empty( $linked_ids ) ) { return array(); } // Query all the linked posts outside the PLL_Export_Bulk_Option::translate() loop to avoid multiple SQL queries with get_post() call. return get_posts( array( 'include' => $linked_ids, 'post_type' => $post_types, 'post_status' => 'any', 'orderby' => 'ID', 'order' => 'ASC', ) ); } /** * Gets the post ids from a post, wether it's classic or block edited. * * @since 3.3 * * @param WP_Post $post A given WP_Post object. * @return int[] An array of post ids. */ protected function get_post_ids_from_post( $post ) { $linked_ids = array(); if ( function_exists( 'has_blocks' ) && has_blocks( $post->post_content ) ) { $linked_ids = $this->get_post_ids_from_block_content( $post->post_content ); } elseif ( $this->options['media_support'] ) { $linked_ids = $this->get_medias_from_html_content( $post->post_content ); } if ( $this->options['media_support'] && has_post_thumbnail( $post->ID ) ) { $linked_ids[] = get_post_thumbnail_id( $post->ID ); } $linked_ids = array_filter( $linked_ids ); // Clean up the array. /** * Filters the medias linked to a post. * * @since 3.3 * * @param int[] $linked_ids Post ids attached to a post (could be in content or in post metas). * @param int $post_id The post id the post we get other post from. */ $linked_ids = apply_filters( 'pll_collect_post_ids', $linked_ids, $post->ID ); return array_unique( $linked_ids ); } /** * Gets the post ids from block type content. * * @since 3.3 * * @param string $post_content The content of the post. * @return int[] An array of post ids. */ protected function get_post_ids_from_block_content( $post_content ) { $blocks = parse_blocks( $post_content ); return $this->get_post_ids_from_blocks_deep( $blocks ); } /** * Gets the post ids from blocks. * * @since 3.3 * * @param array $blocks An array of blocks. * @return int[] An array of post ids. */ protected function get_post_ids_from_blocks_deep( $blocks ) { $post_ids = array(); foreach ( $blocks as $block ) { if ( $this->options['media_support'] ) { $post_ids = array_merge( $post_ids, $this->get_media_ids_from_block( $block ) ); } $post_ids = array_merge( $post_ids, $this->get_navigation_block_ids( $block ) ); $post_ids = array_merge( $post_ids, $this->get_reusable_block_ids( $block ) ); } return array_unique( $post_ids ); } /** * Gets the media ids from a block. * * @since 3.3 * * @param array $block A representative array of a block. * @return int[] An array of media ids, empty if none found. */ protected function get_media_ids_from_block( $block ) { $post_ids = array(); switch ( $block['blockName'] ) { case 'core/audio': case 'core/cover': case 'core/file': case 'core/image': case 'core/video': $post_ids[] = $block['attrs']['id']; break; case 'core/gallery': // Backward compatibility with WP < 5.9. if ( isset( $block['attrs']['ids'] ) && is_array( $block['attrs']['ids'] ) ) { $post_ids = array_merge( $post_ids, $block['attrs']['ids'] ); } break; case 'core/media-text': $post_ids[] = $block['attrs']['mediaId']; break; default: if ( ! empty( $block['innerHTML'] ) ) { $post_ids = array_merge( $post_ids, $this->get_medias_from_html_content( $block['innerHTML'] ) ); } break; } if ( ! empty( $block['innerBlocks'] ) ) { $post_ids = array_merge( $post_ids, $this->get_post_ids_from_blocks_deep( $block['innerBlocks'] ) ); } return $post_ids; } /** * Gets the media ids from classic type content. * * @since 3.3 * * @param string $post_content The content of the post. * @return int[] */ protected function get_medias_from_html_content( $post_content ) { return array_merge( $this->get_medias_from_img_tags( $post_content ), $this->get_medias_from_shortcodes( $post_content ) ); } /** * Gets media ids from shortcodes. * * @since 3.3 * * @param string $post_content The content of the required post. * @return int[] The media ids. */ protected function get_medias_from_shortcodes( $post_content ) { $media_ids = array(); if ( preg_match_all( '/' . get_shortcode_regex() . '/s', $post_content, $matches, PREG_SET_ORDER ) ) { foreach ( $matches as $shortcode ) { $attributes = shortcode_parse_atts( $shortcode[3] ); // $shortcode[3] returns the shortcode attributes as string. switch ( $shortcode[2] ) { // $shortcode[2] returns the shortcode name. case 'caption': if ( isset( $attributes['id'] ) ) { preg_match( '/attachment_([0-9]+)/', $attributes['id'], $attr ); $media_ids[] = (int) $attr[1]; } break; case 'gallery': case 'playlist': if ( isset( $attributes['ids'] ) ) { $media_ids = array_merge( $media_ids, array_map( 'intval', explode( ',', $attributes['ids'] ) ) ); } break; } } } return $media_ids; } /** * Gets media ids from img tags * * @since 3.3 * * @param string $post_content The content of the post to search from. * @return int[] An array of media ids (empty if no media is found). */ protected function get_medias_from_img_tags( $post_content ) { $media_ids = array(); $textarr = wp_html_split( $post_content ); if ( ! is_array( $textarr ) ) { return $media_ids; } foreach ( $textarr as $text ) { if ( 0 !== strpos( $text, 'get_post_ids_from_block_content( $linked_block_post->post_content ) ); } return $ids; } /** * Returns the ID from a navigation block. * * @since 3.3 * * @param array $block An array containing block data. * @return int[] An array of navigation post IDs, empty if none found. */ protected function get_navigation_block_ids( $block ) { if ( 'core/navigation' !== $block['blockName'] ) { return array(); } return array( (int) $block['attrs']['ref'] ); } }