Relevanssi can handle Download Monitor files without significant problems. If you want to use the “Index PDF contents for the parent page” option, there’s a problem, though. Download Monitor comes in between: the PDF post is attached to the Download Monitor dlm_download
post and not the page where the [download]
shortcode is.
It’s easiest if the shortcode is in a custom field, in which case we can pick up the custom field, get the download post ID from that and then use that in the query to get the attachment content.
Add this to your site and replace download
in the get_post_meta()
with the name of the custom field that has the [download]
shortcode:
add_filter( 'relevanssi_pdf_for_parent_query', 'rlv_download_monitor', 10, 2 ); /** * Modifies the attachment content query. * * @param string $query The MySQL query for fetching the attachment content. * @param int $post_id The post ID of the post where the PDF content is added. * * @return string The modified MySQL query. */ function rlv_download_monitor( string $query, int $post_id ) : string { $meta_field_value = get_post_meta( $post_id, 'download', true ); if ( $meta_field_value ) { // The [download id="1234"] shortcode format has one digit in it, so let's grab that. $download_id = preg_replace( '/[^\d]/', '', $meta_field_value ); if ( $download_id ) { // Replace the original post_parent ID with the new one. $query = preg_replace( '/post_parent = \d+/', "post_parent = $download_id", $query ); } } return $query; }
If the [download]
shortcode is somewhere in the post content, the method is slightly different:
add_filter( 'relevanssi_pdf_for_parent_query', 'rlv_download_monitor', 10, 2 ); /** * Modifies the attachment content query. * * @param string $query The MySQL query for fetching the attachment content. * @param int $post_id The post ID of the post where the PDF content is added. * * @return string The modified MySQL query. */ function rlv_download_monitor( $query, $post_id ) { $post_object = relevanssi_get_post( $post_id ); $id_matches = preg_match_all( '/\[download id=.(\d+).\]/ims', $post_object->post_content, $matches ); if ( $id_matches ) { $download_id = implode( ',', $matches[1] ); $query = preg_replace( '/post_parent = \d+/', "post_parent IN ($download_id)", $query ); } return $query; }
Here the code looks for [download id="1234"]
shortcode somewhere in post_content
and picks up the digits in it. This function works even if there are multiple shortcodes in the post.
Hello,
Would it be possible for you to add a third code example for the ‘multiple matches’ per post instead of just saying replace x with y? Above it states: “This works if there’s just one shortcode in the post; this takes the first match. If there are multiple matches, you need use preg_match_all() and change the post_parent to IN(1, 2, 3) matching.”? Are these ‘exact’ changes or examples of what needs to be modified? IN(1, 2 ,3) seems like its an array but not sure where the numbers 1, 2, 3 come into play.
I’d like to add this functionality but want to make sure I add it correctly and I’m not familiar with PHP code.
Thanks,
Ryan
Ryan, I’ve updated the function so that it works with multiple shortcodes.
Thank you!