Email Subscribe for Downloads in WordPress

The following is not the best solution. It is a simple solution that can be / should be improved and it is intended only to give you a direction.

Create a CPT ‘resource’.

register_post_type('resource', $args);

For args refer here.

Under your WP root folder (the one where you have /wp-admin, /wp-includes and /wp-content), via FTP add another folder, name it /resources.

In this folder create an .htaccess file with:

Options All -Indexes
Order Deny, Allow
Deny from all

Upload in this folder all your resource files.

Start creating your resource posts. Create it normally: title, content, taxonomies: whatever you want.

Use custom fields to link these posts with resource files, using the key: ‘resource’

enter image description here

After that create you template file: single-resource.php

In this file create your for form:

<form action="" method="post">
  <input type="text" name="resource" value="<?php the_the_ID() ?>">
  <p>Enter your email here to download:<br />
  <input type="text" name="email" value="">
  </p>
  <input type="submit" name="submit" value="Download">
</form>

In this file you should implement some js validation, that I skip for semplicity.

In a plugin or in your functions.php create code that handle the form submission:

add_action('template_redirect', 'maybe_download');

function maybe_download() {
  if (
    ! is_single() || empty($_POST) ||
    ! isset($_POST['resource']) || ! is_single($_POST['resource']) ||
    ! isset($_POST['email']) || ! is_email($_POST['email'])
   ) return;
   // get already saved emails from option
   $emails = get_option('subscribers') ? : array();
   if ( ! in_array($_POST['email'], $emails) ) {
     $emails[] = $_POST['email'];
     update_option('subscribers', $emails);
   }
   $res = get_post_meta( $post->ID, 'resource', true);
   if ( empty($res) ) return;
   // avoid same user download again same file in the next 10 minutes
   if ( get_transient('downloaded_' . $_POST['email'] . '_' . $res) ) {
     wp_redirect( get_permalink() );
     exit();
   }
   // file path
   $file = trailingslashit( ABSPATH ) . 'resources/' . trim($res);
   if ( ! file_exists($file) ) return;
   // avoid same user download again same file in the next 10 minutes
   set_transient('downloaded_' . $_POST['email'] . '_' . $res, 1, 600 );
   // download count for the resource
   $count = get_post_meta($post->ID, '_download', true) ? : 0;
   update_post_meta($post->ID, '_download', $count+1);
   // force download of file
   header("Cache-Control: public");
   header("Content-Description: File Transfer");
   header("Content-Disposition: attachment; filename= " . basename($file) );
   header("Content-Transfer-Encoding: binary");
   readfile($file);
   exit();
}

To retrieve all suscribers you have to: get_option('subscribers').

With get_post_meta($post->ID, '_download', true) you can know how many time a file has been downloaded.

Again this is a very simple workflow, but you can use as starting point.

Please note that code is completely untested.