Ejemplo n.º 1
0
 /**
  * Handles Download Access permissions.
  *
  * @package s2Member\Files
  * @since 3.5
  *
  * @attaches-to ``add_action('init');``
  * @also-called-by API Function {@link s2Member\API_Functions\s2member_file_download_url()}, w/ ``$create_file_download_url`` param.
  *
  * @param null|array $create_file_download_url Optional. If this function is called directly, we can pass arguments through this array.
  *   Possible array elements: `file_download` *(required)*, `file_download_key`, `file_stream`, `file_inline`, `file_storage`, `file_remote`, `file_ssl`, `file_rewrite`, `file_rewrite_base`, `skip_confirmation`, `url_to_storage_source`, `count_against_user`, `check_user`.
  *
  * @return null|string If called directly with ``$create_file_download_url``, returns a string with the URL, based on configuration.
  *   Else, this function may exit script execution after serving a File Download.
  */
 public static function check_file_download_access($create_file_download_url = NULL)
 {
     foreach (array_keys(get_defined_vars()) as $__v) {
         $__refs[$__v] =& ${$__v};
     }
     do_action('ws_plugin__s2member_before_file_download_access', get_defined_vars());
     unset($__refs, $__v);
     // Housekeeping.
     $_g = !empty($_GET) ? $_GET : array();
     $_g = c_ws_plugin__s2member_utils_strings::trim_deep(stripslashes_deep($_g));
     $creating = is_array($create = $create_file_download_url) ? TRUE : FALSE;
     // Creating URL?
     $serving = !$creating ? TRUE : FALSE;
     // If NOT creating a File Download URL, we're serving one.
     $serving_range = $range = FALSE;
     // Default values (so these variables DO get defined at all times).
     if ($serving) {
         $range = (string) @$_SERVER['HTTP_RANGE'];
         if (!$range && function_exists('apache_request_headers')) {
             foreach ((array) apache_request_headers() as $_header => $_value) {
                 // Note: ``apache_request_headers()`` works in FastCGI too, starting w/ PHP v5.4.
                 if (is_string($_header) && strcasecmp($_header, 'range') === 0) {
                     $range = $_value;
                 }
             }
         }
         unset($_header, $_value);
         // Housekeeping.
         if ($range) {
             $serving_range = TRUE;
         }
     }
     $req['file_download'] = $creating ? @$create['file_download'] : @$_g['s2member_file_download'];
     $req['file_download_key'] = $creating ? @$create['file_download_key'] : @$_g['s2member_file_download_key'];
     $req['file_stream'] = $creating ? @$create['file_stream'] : @$_g['s2member_file_stream'];
     $req['file_inline'] = $creating ? @$create['file_inline'] : @$_g['s2member_file_inline'];
     $req['file_storage'] = $creating ? @$create['file_storage'] : @$_g['s2member_file_storage'];
     $req['file_remote'] = $creating ? @$create['file_remote'] : @$_g['s2member_file_remote'];
     $req['file_ssl'] = $creating ? @$create['file_ssl'] : @$_g['s2member_file_ssl'];
     $req['file_rewrite'] = $creating ? @$create['file_rewrite'] : NULL;
     $req['file_rewrite_base'] = $creating ? @$create['file_rewrite_base'] : NULL;
     $req['skip_confirmation'] = $creating ? @$create['skip_confirmation'] : NULL;
     $req['url_to_storage_source'] = $creating ? @$create['url_to_storage_source'] : NULL;
     $req['count_against_user'] = $creating ? @$create['count_against_user'] : NULL;
     $req['check_user'] = $creating ? @$create['check_user'] : NULL;
     if ($req['file_download'] && is_string($req['file_download']) && ($req['file_download'] = trim($req['file_download'], '/'))) {
         if (strpos($req['file_download'], '..') === FALSE && strpos(basename($req['file_download']), '.') !== 0) {
             $using_amazon_cf_storage = (!$req['file_storage'] || strcasecmp((string) $req['file_storage'], 'cf') === 0) && c_ws_plugin__s2member_utils_conds::using_amazon_cf_storage() ? TRUE : FALSE;
             $using_amazon_s3_storage = (!$req['file_storage'] || strcasecmp((string) $req['file_storage'], 's3') === 0) && c_ws_plugin__s2member_utils_conds::using_amazon_s3_storage() ? TRUE : FALSE;
             $using_amazon_storage = $using_amazon_cf_storage || $using_amazon_s3_storage ? TRUE : FALSE;
             $excluded = apply_filters('ws_plugin__s2member_check_file_download_access_excluded', FALSE, get_defined_vars());
             $valid_file_download_key = $req['file_download_key'] && is_string($req['file_download_key']) && $creating && (!isset($req['check_user']) || !filter_var($req['check_user'], FILTER_VALIDATE_BOOLEAN)) && (!isset($req['count_against_user']) || !filter_var($req['count_against_user'], FILTER_VALIDATE_BOOLEAN)) ? TRUE : FALSE;
             $valid_file_download_key = !$valid_file_download_key && $req['file_download_key'] && is_string($req['file_download_key']) ? c_ws_plugin__s2member_files_in::check_file_download_key($req['file_download'], $req['file_download_key']) : FALSE;
             $checking_user = $excluded || $valid_file_download_key || $creating && (!isset($req['check_user']) || !filter_var($req['check_user'], FILTER_VALIDATE_BOOLEAN)) && (!isset($req['count_against_user']) || !filter_var($req['count_against_user'], FILTER_VALIDATE_BOOLEAN)) ? FALSE : TRUE;
             $updating_user_counter = $serving_range || !$checking_user || $creating && (!isset($req['count_against_user']) || !filter_var($req['count_against_user'], FILTER_VALIDATE_BOOLEAN)) ? FALSE : TRUE;
             if (($serving || $creating) && $checking_user) {
                 if (!$using_amazon_storage && !file_exists($GLOBALS['WS_PLUGIN__']['s2member']['c']['files_dir'] . '/' . $req['file_download'])) {
                     if ($serving) {
                         status_header(404);
                         header('Content-Type: text/html; charset=UTF-8');
                         while (@ob_end_clean()) {
                         }
                         // Clean any existing output buffers.
                         exit(_x('<strong>404: Sorry, file not found.</strong> Please contact Support for assistance.', 's2member-front', 's2member'));
                     }
                     return FALSE;
                     // Else return false.
                 } else {
                     if ($req['file_download_key'] && is_string($req['file_download_key']) && !$valid_file_download_key) {
                         if ($serving) {
                             status_header(503);
                             header('Content-Type: text/html; charset=UTF-8');
                             while (@ob_end_clean()) {
                             }
                             // Clean any existing output buffers.
                             exit(_x('<strong>503 (Invalid Key):</strong> Sorry, your access to this file has expired. Please contact Support for assistance.', 's2member-front', 's2member'));
                         }
                         return FALSE;
                         // Else return false.
                     } else {
                         if ($serving) {
                             // We only need remote functionality when/if we're actually serving.
                             if (!has_filter('ws_plugin__s2member_check_file_download_access_user', 'c_ws_plugin__s2member_files_in::check_file_remote_authorization')) {
                                 add_filter('ws_plugin__s2member_check_file_download_access_user', 'c_ws_plugin__s2member_files_in::check_file_remote_authorization', 10, 2);
                             }
                         }
                         if ($creating) {
                             // We only need remote functionality when/if we're actually serving.
                             if (has_filter('ws_plugin__s2member_check_file_download_access_user', 'c_ws_plugin__s2member_files_in::check_file_remote_authorization')) {
                                 remove_filter('ws_plugin__s2member_check_file_download_access_user', 'c_ws_plugin__s2member_files_in::check_file_remote_authorization', 10, 2);
                             }
                         }
                         if (!$GLOBALS['WS_PLUGIN__']['s2member']['o']['membership_options_page']) {
                             if ($serving) {
                                 status_header(503);
                                 header('Content-Type: text/html; charset=UTF-8');
                                 while (@ob_end_clean()) {
                                 }
                                 // Clean any existing output buffers.
                                 exit(_x('<strong>503: Basic File Downloads are NOT enabled yet.</strong> Please contact Support for assistance. If you are the site owner, please configure: <strong>s2Member → General Options → Membership Options Page</strong>.', 's2member-front', 's2member'));
                             }
                             return FALSE;
                             // Else return false.
                         } else {
                             if (($file_downloads_enabled_by_site_owner = $min_level_4_downloads = c_ws_plugin__s2member_files::min_level_4_downloads()) === FALSE) {
                                 if ($serving) {
                                     status_header(503);
                                     header('Content-Type: text/html; charset=UTF-8');
                                     while (@ob_end_clean()) {
                                     }
                                     // Clean any existing output buffers.
                                     exit(_x('<strong>503: Basic File Downloads are NOT enabled yet.</strong> Please contact Support for assistance. If you are the site owner, please configure: <strong>s2Member → Download Options → Basic Download Restrictions</strong>.', 's2member-front', 's2member'));
                                 }
                                 return FALSE;
                                 // Else return false.
                             } else {
                                 if (!is_object($user = apply_filters('ws_plugin__s2member_check_file_download_access_user', is_user_logged_in() ? wp_get_current_user() : FALSE, get_defined_vars())) || empty($user->ID) || !($user_id = $user->ID) || !is_array($user_file_downloads = c_ws_plugin__s2member_files::user_downloads($user)) || !$user->has_cap('administrator') && (!$user_file_downloads['allowed'] || !$user_file_downloads['allowed_days'])) {
                                     if (preg_match('/(?:^|\\/)access[_\\-]s2member[_\\-]level([0-9]+)\\//', $req['file_download'], $m) && strlen($req_level = $m[1]) && (!is_object($user) || empty($user->ID) || !$user->has_cap('access_s2member_level' . $req_level))) {
                                         if ($serving) {
                                             // We only need this section when/if we're actually serving.
                                             c_ws_plugin__s2member_mo_page::wp_redirect_w_mop_vars('file', $req['file_download'], 'level', $req_level, $_SERVER['REQUEST_URI']) . exit;
                                         }
                                         return FALSE;
                                         // Else return false.
                                     } else {
                                         if (preg_match('/(?:^|\\/)access[_\\-]s2member[_\\-]ccap[_\\-](.+?)\\//', $req['file_download'], $m) && strlen($req_ccap = preg_replace('/-/', '_', $m[1])) && (!is_object($user) || empty($user->ID) || !$user->has_cap('access_s2member_ccap_' . $req_ccap))) {
                                             if ($serving) {
                                                 // We only need this section when/if we're actually serving.
                                                 c_ws_plugin__s2member_mo_page::wp_redirect_w_mop_vars('file', $req['file_download'], 'ccap', $req_ccap, $_SERVER['REQUEST_URI']) . exit;
                                             }
                                             return FALSE;
                                             // Else return false.
                                         } else {
                                             if ($serving) {
                                                 // We only need this section when/if we're actually serving.
                                                 c_ws_plugin__s2member_mo_page::wp_redirect_w_mop_vars('file', $req['file_download'], 'level', $min_level_4_downloads, $_SERVER['REQUEST_URI']) . exit;
                                             }
                                         }
                                     }
                                     return FALSE;
                                     // Else return false.
                                 } else {
                                     if (preg_match('/(?:^|\\/)access[_\\-]s2member[_\\-]level([0-9]+)\\//', $req['file_download'], $m) && strlen($req_level = $m[1]) && !$user->has_cap('access_s2member_level' . $req_level)) {
                                         if ($serving) {
                                             // We only need this section when/if we're actually serving.
                                             c_ws_plugin__s2member_mo_page::wp_redirect_w_mop_vars('file', $req['file_download'], 'level', $req_level, $_SERVER['REQUEST_URI']) . exit;
                                         }
                                         return FALSE;
                                         // Else return false.
                                     } else {
                                         if (preg_match('/(?:^|\\/)access[_\\-]s2member[_\\-]ccap[_\\-](.+?)\\//', $req['file_download'], $m) && strlen($req_ccap = preg_replace('/-/', '_', $m[1])) && !$user->has_cap('access_s2member_ccap_' . $req_ccap)) {
                                             if ($serving) {
                                                 // We only need this section when/if we're actually serving.
                                                 c_ws_plugin__s2member_mo_page::wp_redirect_w_mop_vars('file', $req['file_download'], 'ccap', $req_ccap, $_SERVER['REQUEST_URI']) . exit;
                                             }
                                             return FALSE;
                                             // Else return false.
                                         } else {
                                             if ($serving || $creating) {
                                                 $user_previous_file_downloads = 0;
                                                 // Downloads the User has already; in current period/cycle.
                                                 $user_already_downloaded_this_file = $user_already_downloaded_a_streaming_variation_of_this_file = FALSE;
                                                 $user_file_download_access_log = is_array($user_file_download_access_log = get_user_option('s2member_file_download_access_log', $user_id)) ? $user_file_download_access_log : array();
                                                 $user_file_download_access_arc = is_array($user_file_download_access_arc = get_user_option('s2member_file_download_access_arc', $user_id)) ? $user_file_download_access_arc : array();
                                                 $streaming_file_extns = c_ws_plugin__s2member_utils_strings::preg_quote_deep($GLOBALS['WS_PLUGIN__']['s2member']['c']['streaming_file_extns'], '/');
                                                 $streaming_variations = '/\\.(' . implode('|', $streaming_file_extns) . ')$/i';
                                                 // Only count one streaming media file variation.
                                                 foreach ($user_file_download_access_log as $user_file_download_access_log_entry_key => $user_file_download_access_log_entry) {
                                                     if (isset($user_file_download_access_log_entry['date'], $user_file_download_access_log_entry['file'])) {
                                                         if (strtotime($user_file_download_access_log_entry['date']) < strtotime('-' . $user_file_downloads['allowed_days'] . ' days')) {
                                                             unset($user_file_download_access_log[$user_file_download_access_log_entry_key]);
                                                             // Remove it from the `log`.
                                                             $user_file_download_access_arc[] = $user_file_download_access_log_entry;
                                                             // Move `log` entry to the `archive` now.
                                                         } else {
                                                             if (strtotime($user_file_download_access_log_entry['date']) >= strtotime('-' . $user_file_downloads['allowed_days'] . ' days')) {
                                                                 $user_previous_file_downloads++;
                                                                 // Previous files always count against this User/Member.
                                                                 $_user_file_download_access_log_entry =& $user_file_download_access_log[$user_file_download_access_log_entry_key];
                                                                 $_user_already_downloaded_this_file = $_user_already_downloaded_a_streaming_variation_of_this_file = FALSE;
                                                                 if ($user_file_download_access_log_entry['file'] === $req['file_download']) {
                                                                     // Already downloaded this file? If yes, mark this flag as true.
                                                                     $user_already_downloaded_this_file = $_user_already_downloaded_this_file = TRUE;
                                                                 } else {
                                                                     if (preg_replace($streaming_variations, '', $user_file_download_access_log_entry['file']) === preg_replace($streaming_variations, '', $req['file_download'])) {
                                                                         $user_already_downloaded_this_file = $_user_already_downloaded_this_file = $user_already_downloaded_a_streaming_variation_of_this_file = $_user_already_downloaded_a_streaming_variation_of_this_file = TRUE;
                                                                     }
                                                                 }
                                                                 if ($updating_user_counter && ($_user_already_downloaded_this_file || $_user_already_downloaded_a_streaming_variation_of_this_file)) {
                                                                     $_user_file_download_access_log_entry['ltime'] = time();
                                                                     // First, we update the last download time for this file.
                                                                     if (!empty($user_file_download_access_log_entry['counter'])) {
                                                                         // Backward compatibility here. Is this even set?
                                                                         $_user_file_download_access_log_entry['counter'] = (int) $user_file_download_access_log_entry['counter'] + 1;
                                                                     } else {
                                                                         // Backward compatibility here. Default value to `1`, if this is NOT even set yet.
                                                                         $_user_file_download_access_log_entry['counter'] = 1 + 1;
                                                                     }
                                                                 }
                                                             }
                                                         }
                                                     } else {
                                                         // Weed out empty log entries. Some older versions of s2Member may have corrupt/empty log entries.
                                                         unset($user_file_download_access_log[$user_file_download_access_log_entry_key]);
                                                     }
                                                     // Remove.
                                                 }
                                                 if ($updating_user_counter && !$user_already_downloaded_this_file && !$user_already_downloaded_a_streaming_variation_of_this_file) {
                                                     // Do we need a new log entry for this file?
                                                     $user_file_download_access_log[] = array('date' => date('Y-m-d'), 'time' => time(), 'ltime' => time(), 'file' => $req['file_download'], 'counter' => 1);
                                                 }
                                                 if ($user_previous_file_downloads >= $user_file_downloads['allowed'] && !$user_already_downloaded_this_file && !$user_already_downloaded_a_streaming_variation_of_this_file && !$user->has_cap('administrator')) {
                                                     if ($serving) {
                                                         // We only need this section when/if we're actually serving.
                                                         wp_redirect(add_query_arg(urlencode_deep(array('_s2member_seeking' => array('type' => 'file', 'file' => $req['file_download'], '_uri' => base64_encode($_SERVER['REQUEST_URI'])), 's2member_seeking' => 'file-' . $req['file_download'])), get_page_link($GLOBALS['WS_PLUGIN__']['s2member']['o']['file_download_limit_exceeded_page'])), apply_filters('ws_plugin__s2member_content_redirect_status', 301, get_defined_vars())) . exit;
                                                     }
                                                     return FALSE;
                                                     // Else return false.
                                                 } else {
                                                     if ($updating_user_counter) {
                                                         // Save/update counter? By default, we do NOT update the counter when a URL is simply being created for access.
                                                         update_user_option($user_id, 's2member_file_download_access_log', c_ws_plugin__s2member_utils_arrays::array_unique($user_file_download_access_log)) . update_user_option($user_id, 's2member_file_download_access_arc', c_ws_plugin__s2member_utils_arrays::array_unique($user_file_download_access_arc));
                                                     }
                                                 }
                                             }
                                         }
                                     }
                                 }
                             }
                         }
                     }
                 }
             } else {
                 if (!$using_amazon_storage && !file_exists($GLOBALS['WS_PLUGIN__']['s2member']['c']['files_dir'] . '/' . $req['file_download'])) {
                     if ($serving) {
                         status_header(404);
                         header('Content-Type: text/html; charset=UTF-8');
                         while (@ob_end_clean()) {
                         }
                         // Clean any existing output buffers.
                         exit(_x('<strong>404: Sorry, file not found.</strong> Please contact Support for assistance.', 's2member-front', 's2member'));
                     }
                     return FALSE;
                     // Else return false.
                 }
             }
             if ($serving || $creating) {
                 $basename = basename($req['file_download']);
                 $mimetypes = parse_ini_file(dirname(dirname(dirname(__FILE__))) . '/includes/mime-types.ini');
                 $extension = strtolower(substr($req['file_download'], strrpos($req['file_download'], '.') + 1));
                 $key = $req['file_download_key'] && is_string($req['file_download_key']) ? $req['file_download_key'] : FALSE;
                 $stream = isset($req['file_stream']) ? filter_var($req['file_stream'], FILTER_VALIDATE_BOOLEAN) : (in_array($extension, preg_split('/[' . "\r\n\t" . '\\s;,]+/', $GLOBALS['WS_PLUGIN__']['s2member']['o']['file_download_stream_extensions'])) ? TRUE : FALSE);
                 $inline = !$stream && isset($req['file_inline']) ? filter_var($req['file_inline'], FILTER_VALIDATE_BOOLEAN) : ($stream || in_array($extension, preg_split('/[' . "\r\n\t" . '\\s;,]+/', $GLOBALS['WS_PLUGIN__']['s2member']['o']['file_download_inline_extensions'])) ? TRUE : FALSE);
                 $ssl = isset($req['file_ssl']) ? filter_var($req['file_ssl'], FILTER_VALIDATE_BOOLEAN) : (is_ssl() ? TRUE : FALSE);
                 $storage = $req['file_storage'] && is_string($req['file_storage']) ? strtolower($req['file_storage']) : FALSE;
                 $remote = isset($req['file_remote']) ? filter_var($req['file_remote'], FILTER_VALIDATE_BOOLEAN) : FALSE;
                 $_basename_dir_app_data = c_ws_plugin__s2member_utils_dirs::basename_dir_app_data($GLOBALS['WS_PLUGIN__']['s2member']['c']['files_dir']);
                 $rewrite_base_guess = is_dir(dirname($GLOBALS['WS_PLUGIN__']['s2member']['c']['dir']) . '/' . $_basename_dir_app_data) ? dirname($GLOBALS['WS_PLUGIN__']['s2member']['c']['dir_url']) . '/' . $_basename_dir_app_data : content_url('/' . $_basename_dir_app_data);
                 $rewrite_base = $req['file_rewrite_base'] && is_string($req['file_rewrite_base']) ? $req['file_rewrite_base'] : FALSE;
                 $rewrite = $rewriting = !$rewrite_base && isset($req['file_rewrite']) ? filter_var($req['file_rewrite'], FILTER_VALIDATE_BOOLEAN) : ($rewrite_base ? TRUE : FALSE);
                 unset($_basename_dir_app_data);
                 // A little housekeeping here.
                 $skip_confirmation = isset($req['skip_confirmation']) ? filter_var($req['skip_confirmation'], FILTER_VALIDATE_BOOLEAN) : FALSE;
                 $url_to_storage_source = isset($req['url_to_storage_source']) ? filter_var($req['url_to_storage_source'], FILTER_VALIDATE_BOOLEAN) : FALSE;
                 $file = $GLOBALS['WS_PLUGIN__']['s2member']['c']['files_dir'] . '/' . $req['file_download'];
                 $pathinfo = !$using_amazon_storage && $file ? pathinfo($file) : array();
                 $mimetype = $mimetypes[$extension] ? $mimetypes[$extension] : 'application/octet-stream';
                 $disposition = ($inline ? 'inline' : 'attachment') . '; filename="' . c_ws_plugin__s2member_utils_strings::esc_dq($basename) . '"; filename*=UTF-8\'\'' . rawurlencode($basename);
                 $length = !$using_amazon_storage && $file ? filesize($file) : -1;
                 foreach (array_keys(get_defined_vars()) as $__v) {
                     $__refs[$__v] =& ${$__v};
                 }
                 do_action('ws_plugin__s2member_during_file_download_access', get_defined_vars());
                 unset($__refs, $__v);
                 // Housekeeping.
                 if ($using_amazon_storage && $using_amazon_cf_storage && ($serving || $creating && $url_to_storage_source)) {
                     if ($serving) {
                         // We only need this section when/if we're actually serving.
                         wp_redirect(c_ws_plugin__s2member_files_in::amazon_cf_url($req['file_download'], $stream, $inline, $ssl, $basename, $mimetype)) . exit;
                     }
                     return apply_filters('ws_plugin__s2member_file_download_access_url', c_ws_plugin__s2member_files_in::amazon_cf_url($req['file_download'], $stream, $inline, $ssl, $basename, $mimetype), get_defined_vars());
                 } else {
                     if ($using_amazon_storage && $using_amazon_s3_storage && ($serving || $creating && $url_to_storage_source)) {
                         if ($serving) {
                             // We only need this section when/if we're actually serving.
                             wp_redirect(c_ws_plugin__s2member_files_in::amazon_s34_url($req['file_download'], $stream, $inline, $ssl, $basename, $mimetype)) . exit;
                         }
                         return apply_filters('ws_plugin__s2member_file_download_access_url', c_ws_plugin__s2member_files_in::amazon_s34_url($req['file_download'], $stream, $inline, $ssl, $basename, $mimetype), get_defined_vars());
                     } else {
                         if ($creating && $rewriting) {
                             // Note: we don't URL encode unreserved chars. Improves media player compatibility.
                             $_url_e_key = $key ? c_ws_plugin__s2member_utils_strings::urldecode_ur_chars_deep(urlencode($key)) : '';
                             $_url_e_storage = $storage ? c_ws_plugin__s2member_utils_strings::urldecode_ur_chars_deep(urlencode($storage)) : '';
                             $_url_e_file = c_ws_plugin__s2member_utils_strings::urldecode_ur_chars_deep(urlencode($req['file_download']));
                             $_url_e_file = str_ireplace('%2F', '/', $_url_e_file);
                             $url = $rewrite_base ? rtrim($rewrite_base, '/') : rtrim($rewrite_base_guess, '/');
                             $url .= isset($req['file_download_key']) ? $key && $_url_e_key ? '/s2member-file-download-key-' . $_url_e_key : '' : '';
                             $url .= isset($req['file_stream']) ? $stream ? '/s2member-file-stream' : '/s2member-file-stream-no' : '';
                             $url .= isset($req['file_inline']) ? $inline ? '/s2member-file-inline' : '/s2member-file-inline-no' : '';
                             $url .= isset($req['file_storage']) ? $storage && $_url_e_storage ? '/s2member-file-storage-' . $_url_e_storage : '' : '';
                             $url .= isset($req['file_remote']) ? $remote ? '/s2member-file-remote' : '/s2member-file-remote-no' : '';
                             $url .= isset($req['skip_confirmation']) ? $skip_confirmation ? '/s2member-skip-confirmation' : '/s2member-skip-confirmation-no' : '';
                             $url = $url . '/' . $_url_e_file;
                             // File Download Access URL via `mod_rewrite` functionality.
                             $url = $ssl ? preg_replace('/^https?/', 'https', $url) : preg_replace('/^https?/', 'http', $url);
                             return apply_filters('ws_plugin__s2member_file_download_access_url', $url, get_defined_vars());
                         } else {
                             if ($creating) {
                                 // Note: we don't URL encode unreserved chars. Improves media player compatibility.
                                 $_url_e_key = $key ? c_ws_plugin__s2member_utils_strings::urldecode_ur_chars_deep(urlencode($key)) : '';
                                 $_url_e_storage = $storage ? c_ws_plugin__s2member_utils_strings::urldecode_ur_chars_deep(urlencode($storage)) : '';
                                 $_url_e_file = c_ws_plugin__s2member_utils_strings::urldecode_ur_chars_deep(urlencode($req['file_download']));
                                 $_url_e_file = str_ireplace('%2F', '/', $_url_e_file);
                                 $url = isset($req['file_download_key']) ? $key && $_url_e_key ? '&s2member_file_download_key=' . $_url_e_key : '' : '';
                                 $url .= isset($req['file_stream']) ? $stream ? '&s2member_file_stream=yes' : '&s2member_file_stream=no' : '';
                                 $url .= isset($req['file_inline']) ? $inline ? '&s2member_file_inline=yes' : '&s2member_file_inline=no' : '';
                                 $url .= isset($req['file_storage']) ? $storage && $_url_e_storage ? '&s2member_file_storage=' . $_url_e_storage : '' : '';
                                 $url .= isset($req['file_remote']) ? $remote ? '&s2member_file_remote=yes' : '&s2member_file_remote=no' : '';
                                 $url .= isset($req['skip_confirmation']) ? $skip_confirmation ? '&s2member_skip_confirmation=yes' : '&s2member_skip_confirmation=no' : '';
                                 $url = home_url('/?' . ltrim($url . '&s2member_file_download=/' . $_url_e_file, '&'));
                                 $url = $ssl ? preg_replace('/^https?/', 'https', $url) : preg_replace('/^https?/', 'http', $url);
                                 return apply_filters('ws_plugin__s2member_file_download_access_url', $url, get_defined_vars());
                             } else {
                                 if ($serving) {
                                     @set_time_limit(0);
                                     @ini_set('zlib.output_compression', 0);
                                     if (function_exists('apache_setenv')) {
                                         @apache_setenv('no-gzip', '1');
                                     }
                                     $content_encoding_header = 'Content-Encoding:';
                                     // Default value; standards compliant.
                                     if ($GLOBALS['WS_PLUGIN__']['s2member']['o']['file_download_content_encodong_none']) {
                                         $content_encoding_header = 'Content-Encoding: none';
                                     }
                                     while (@ob_end_clean()) {
                                     }
                                     // Cleans existing output buffers.
                                     if ($range) {
                                         if (strpos($range, '=') === FALSE) {
                                             status_header(416);
                                             nocache_headers();
                                             header($content_encoding_header);
                                             header('Accept-Ranges: bytes');
                                             header('Content-Type: ' . $mimetype);
                                             header('Content-Length: ' . $length);
                                             header('Content-Disposition: ' . $disposition);
                                             exit;
                                             // Stop here (invalid).
                                         }
                                         list($range_type, $byte_range) = preg_split('/\\s*\\=\\s*/', $range, 2);
                                         $range_type = strtolower(trim($range_type));
                                         $byte_range = trim($byte_range);
                                         if ($range_type !== 'bytes') {
                                             status_header(416);
                                             nocache_headers();
                                             header($content_encoding_header);
                                             header('Accept-Ranges: bytes');
                                             header('Content-Type: ' . $mimetype);
                                             header('Content-Length: ' . $length);
                                             header('Content-Disposition: ' . $disposition);
                                             exit;
                                             // Stop here (invalid).
                                         }
                                         $byte_ranges = preg_split('/\\s*,\\s*/', $byte_range);
                                         if (strpos($byte_ranges[0], '-') === FALSE) {
                                             status_header(416);
                                             nocache_headers();
                                             header($content_encoding_header);
                                             header('Accept-Ranges: bytes');
                                             header('Content-Type: ' . $mimetype);
                                             header('Content-Length: ' . $length);
                                             header('Content-Disposition: ' . $disposition);
                                             exit;
                                             // Stop here (invalid).
                                         }
                                         // Only dealing with the first byte range. Others are simply ignored here.
                                         list($byte_range_start, $byte_range_stops) = preg_split('/\\s*\\-\\s*/', $byte_ranges[0], 2);
                                         $byte_range_start = trim($byte_range_start);
                                         $byte_range_stops = trim($byte_range_stops);
                                         $byte_range_start = $byte_range_start === '' ? NULL : (int) $byte_range_start;
                                         $byte_range_stops = $byte_range_stops === '' ? NULL : (int) $byte_range_stops;
                                         if (!isset($byte_range_start) && $byte_range_stops > 0 && $byte_range_stops <= $length) {
                                             $byte_range_start = $length - $byte_range_stops;
                                             $byte_range_stops = $length - 1;
                                             // The last X number of bytes.
                                         } else {
                                             if (!isset($byte_range_stops) && $byte_range_start >= 0 && $byte_range_start < $length - 1) {
                                                 $byte_range_stops = $length - 1;
                                                 // To the end of the file in this case.
                                             } else {
                                                 if (isset($byte_range_start, $byte_range_stops) && $byte_range_start >= 0 && $byte_range_start < $length - 1 && $byte_range_stops > $byte_range_start && $byte_range_stops <= $length - 1) {
                                                     // Nothing to do in this case, starts/stops already defined properly.
                                                 } else {
                                                     status_header(416);
                                                     nocache_headers();
                                                     header($content_encoding_header);
                                                     header('Accept-Ranges: bytes');
                                                     header('Content-Type: ' . $mimetype);
                                                     header('Content-Length: ' . $length);
                                                     header('Content-Disposition: ' . $disposition);
                                                     exit;
                                                     // Stop here (invalid).
                                                 }
                                             }
                                         }
                                         status_header(206);
                                         nocache_headers();
                                         header($content_encoding_header);
                                         header('Accept-Ranges: bytes');
                                         header('Content-Type: ' . $mimetype);
                                         header('Content-Range: bytes ' . $byte_range_start . '-' . $byte_range_stops . '/' . $length);
                                         $byte_range_size = $byte_range_stops - $byte_range_start + 1;
                                         header('Content-Length: ' . $byte_range_size);
                                         header('Content-Disposition: ' . $disposition);
                                     } else {
                                         status_header(200);
                                         nocache_headers();
                                         header($content_encoding_header);
                                         header('Accept-Ranges: bytes');
                                         header('Content-Type: ' . $mimetype);
                                         header('Content-Length: ' . $length);
                                         header('Content-Disposition: ' . $disposition);
                                     }
                                     if (is_resource($resource = fopen($file, 'rb'))) {
                                         if ($range && isset($byte_range_size, $byte_range_start)) {
                                             $_bytes_to_read = $byte_range_size;
                                             fseek($resource, $byte_range_start);
                                         } else {
                                             $_bytes_to_read = $length;
                                         }
                                         // Entire file.
                                         $chunk_size = apply_filters('ws_plugin__s2member_file_downloads_chunk_size', 2097152, get_defined_vars());
                                         while ($_bytes_to_read > 0) {
                                             $_bytes_to_read -= $_reading = $_bytes_to_read > $chunk_size ? $chunk_size : $_bytes_to_read;
                                             echo fread($resource, $_reading);
                                             // Serve file in chunks (default chunk size is 2MB).
                                             flush();
                                             // Flush each chunk to the browser as it is served (avoids high memory consumption).
                                         }
                                         fclose($resource);
                                         // Close file resource handle.
                                         unset($_bytes_to_read, $_reading);
                                         // Housekeeping.
                                     }
                                     exit;
                                     // Stop execution now (the file has been served).
                                 }
                             }
                         }
                     }
                 }
             }
         } else {
             if ($serving && $req['file_download']) {
                 status_header(503);
                 header('Content-Type: text/html; charset=UTF-8');
                 while (@ob_end_clean()) {
                 }
                 // Clean any existing output buffers.
                 exit(_x('<strong>503: Access denied.</strong> Invalid File Download specs.', 's2member-front', 's2member'));
             } else {
                 if ($creating) {
                     return FALSE;
                 }
             }
         }
     }
     // We only need this section when/if we're creating a URL.
     do_action('ws_plugin__s2member_after_file_download_access', get_defined_vars());
     return $creating ? FALSE : NULL;
     // If creating, false.
 }