Posted on

WP Download Manager

WP Download Manager is a popular file management plugin for WordPress. It’s unfortunately incompatible with Relevanssi attachment content reading out of the box, as Relevanssi expects the attachments to be stored in the Media Library, and WP Download Manager stores the files outside Media Library.

Fortunately, Relevanssi includes the necessary filter hooks that make it possible to access WP Download Manager files.

Changing the attachment query

The first one we need is relevanssi_get_attachment_posts_query, which is used to fetch the attachment posts for indexing. By default, Relevanssi looks for posts with the post type attachment, post status inherit and a suitable MIME type. These all need to be changed, because the WP Download Manager posts have the post type wpdmpro, status of publish and no MIME type.

The necessary filter function looks like this:

add_filter( 'relevanssi_get_attachment_posts_query', 'rlv_wpdmpro_query' );
function rlv_wpdmpro_query( $query ) {
  return str_replace(
    "post_type = 'attachment' AND post_status = 'inherit' AND post_mime_type LIKE %s",
    "post_type = 'wpdmpro' AND post_status = 'publish' AND (post_mime_type LIKE %s OR post_mime_type = '')",
    $query
  );
}

Changing the file name

Since WP Download Manager is a tool to control who gets to access the files, it’s likely your files will not be publicly accessible. That’s not a problem: Relevanssi attachment reading can work in two ways, it can either fetch the files from your site if they’re public, or you can send the files from your server.

So, check the “Upload files for reading” option on the Relevanssi attachment settings page to avoid these issues.

When you upload the files to the Relevanssi attachment reading server, Relevanssi uses the get_attached_file() function to get the file name, but that does not work with WP Download Manager. Thus we need to use the relevanssi_get_attached_file filter hook to provide the file name and path for Relevanssi.

add_filter( 'relevanssi_get_attached_file', 'rlv_wpdmpro_file', 10, 2 );
function rlv_wpdmpro_file( $filename, $post_id ) {
  $files      = get_package_data( $post_id, 'files' );
  $upload_dir = wp_get_upload_dir();
  $filename   = $upload_dir['basedir'] . '/download-manager-files/' . $files[0];

  return $filename;
}

This function fetches the files attached to the WP Download Manager post with get_package_data(). To get the path, this function assumes WP Download Manager uploads are stored in /wp-content/uploads/download-manager-files/. wp_get_upload_dir() is used to get the path to the uploads directory and the rest is hard-coded. If your uploads are stored somewhere else, you need to modify this function to get the right path.

The file name array format may be different, in which case the function above needs to be changed to this:

  $filename   = $upload_dir['basedir'] . '/download-manager-files/' . array_values( $files )[0];

Limitations

With these two small functions, Relevanssi can read the files attached to WP Download Manager posts. There’s one major limitation: WP Download Manager posts can contain multiple files, but Relevanssi can only read one file per post. That’s a hard limit that cannot be changed, unfortunately, because it would require a major refactoring of the Relevanssi code – in WordPress attachments, there’s only one attachment per post, and that’s what Relevanssi expects.

If you have multiple files in your posts, Relevanssi can index one of those. You need to specify which one you want in the rlv_wpdmpro_file() function. Currently, it’s just taking the first file ($files[0]), but you can add more logic to it, for example, you can look through the $files array (it’s an array of file name strings) and grab the one PDF in the set.

Read files on upload

Relevanssi cannot automatically read new WP Download Manager files, because they don’t trigger the same action hook WordPress attachments do. This function helps with that:

add_action( 'wp_after_insert_post', function( $post_id ) {
    $post = get_post( $post_id );
    if ( 'wpdmpro' === $post->post_type ) {
        $files   = get_package_data( $post_id, 'files' );
        $content = get_post_meta( $post_id, '_relevanssi_pdf_content', true );
        if ( ! empty( $files ) && empty( $content ) ) {
            relevanssi_index_pdf( $post_id, false );
        }
    }
}, 90 );

The WPDM Directory add-on adds an advanced search with the [wpdb_archive_filter] shortcode. That search does not use Relevanssi by default, but it can be modified to make use of Relevanssi with this little function you can add to your site:

add_filter( 'wpdm_packages_query_params', 'rlv_use_relevanssi' );
function rlv_use_relevanssi( $params ) {
  if ( isset( $params['s'] ) ) {
    $params['relevanssi'] = true;
  }
  return $params;
}

Access

If your files have limited access, you need to limit the access in the search as well. That is also straightforward using the relevanssi_post_ok filter hook and the wpdm_user_has_access() function:

add_filter( 'relevanssi_post_ok', 'rlv_wpdmpro_access', 10, 2 );
function rlv_wpdmpro_access( $ok, $post_id ) {
  if ( 'wpdmpro' === relevanssi_get_post_type( $post_id ) ) {
    $ok = wpdm_user_has_access( $post_id );
  }
  return $ok;
}

Now only the users with proper access will see the files in the search results.

Relevanssi can cause problems with the WPDM Frontend Editor Search: the search may stop working, and disabling Relevanssi will fix the problem. In that case, you can keep Relevanssi active and the search working by adding this function to your site:

add_filter( 'relevanssi_prevent_default_request', function( $prevent ) {
    if ( isset( $_POST['do'] ) ) {
        $prevent = false;
    }
    return $prevent;
}, 10 );

Leave a Reply

Are you a Relevanssi Premium customer looking for support? Please use the Premium support form.

Your email address will not be published. Required fields are marked *