File "class-wc-download-handler.php"
Full path: /home/kosmetik/public_html/wp-content/plugins/woocommerce/includes/class-wc-download-handler.php
File
size: 17.13 B
MIME-type: text/x-php
Charset: utf-8
Download Open Edit Advanced Editor Back
<?php
defined('ABSPATH') || exit;
class WC_Download_Handler
{
public static function init()
{
if (isset($_GET['download_file'], $_GET['order']) && (isset($_GET['email']) || isset($_GET['uid']))) {
add_action('init', array(__CLASS__, 'download_product'));
}
add_action('woocommerce_download_file_redirect', array(__CLASS__, 'download_file_redirect'), 10, 2);
add_action('woocommerce_download_file_xsendfile', array(__CLASS__, 'download_file_xsendfile'), 10, 2);
add_action('woocommerce_download_file_force', array(__CLASS__, 'download_file_force'), 10, 2);
}
public static function download_product()
{
$product_id = absint($_GET['download_file']);
$product = wc_get_product($product_id);
$data_store = WC_Data_Store::load('customer-download');
if (!$product || empty($_GET['key']) || empty($_GET['order'])) {
self::download_error(__('Invalid download link.', 'woocommerce'));
}
if (empty($_GET['email']) && empty($_GET['uid'])) {
self::download_error(__('Invalid download link.', 'woocommerce'));
}
$order_id = wc_get_order_id_by_order_key(wc_clean(wp_unslash($_GET['order'])));
$order = wc_get_order($order_id);
if (isset($_GET['email'])) {
$email_address = wp_unslash($_GET['email']);
} else {
$email_address = is_a($order, 'WC_Order') ? $order->get_billing_email() : null;
$email_hash = function_exists('hash') ? hash('sha256', $email_address) : sha1($email_address);
if (is_null($email_address) || !hash_equals(wp_unslash($_GET['uid']), $email_hash)) {
self::download_error(__('Invalid download link.', 'woocommerce'));
}
}
$download_ids = $data_store->get_downloads(array('user_email' => sanitize_email(str_replace(' ', '+', $email_address)), 'order_key' => wc_clean(wp_unslash($_GET['order'])), 'product_id' => $product_id, 'download_id' => wc_clean(preg_replace('/\\s+/', ' ', wp_unslash($_GET['key']))), 'orderby' => 'downloads_remaining', 'order' => 'DESC', 'limit' => 1, 'return' => 'ids'));
if (empty($download_ids)) {
self::download_error(__('Invalid download link.', 'woocommerce'));
}
$download = new WC_Customer_Download(current($download_ids));
$file_path = apply_filters('woocommerce_download_product_filepath', $product->get_file_download_path($download->get_download_id()), $email_address, $order, $product, $download);
$parsed_file_path = self::parse_file_path($file_path);
$download_range = self::get_download_range(@filesize($parsed_file_path['file_path']));
self::check_order_is_valid($download);
if (!$download_range['is_range_request']) {
self::check_downloads_remaining($download);
}
self::check_download_expiry($download);
self::check_download_login_required($download);
do_action('woocommerce_download_product', $download->get_user_email(), $download->get_order_key(), $download->get_product_id(), $download->get_user_id(), $download->get_download_id(), $download->get_order_id());
$download->save();
$current_user_id = get_current_user_id();
$ip_address = WC_Geolocation::get_ip_address();
if (!$download_range['is_range_request']) {
$download->track_download($current_user_id > 0 ? $current_user_id : null, !empty($ip_address) ? $ip_address : null);
}
self::download($file_path, $download->get_product_id());
}
private static function check_order_is_valid($download)
{
if ($download->get_order_id()) {
$order = wc_get_order($download->get_order_id());
if ($order && !$order->is_download_permitted()) {
self::download_error(__('Invalid order.', 'woocommerce'), '', 403);
}
}
}
private static function check_downloads_remaining($download)
{
if ('' !== $download->get_downloads_remaining() && 0 >= $download->get_downloads_remaining()) {
self::download_error(__('Sorry, you have reached your download limit for this file', 'woocommerce'), '', 403);
}
}
private static function check_download_expiry($download)
{
if (!is_null($download->get_access_expires()) && $download->get_access_expires()->getTimestamp() < strtotime('midnight', time())) {
self::download_error(__('Sorry, this download has expired', 'woocommerce'), '', 403);
}
}
private static function check_download_login_required($download)
{
if ($download->get_user_id() && 'yes' === get_option('woocommerce_downloads_require_login')) {
if (!is_user_logged_in()) {
if (wc_get_page_id('myaccount')) {
wp_safe_redirect(add_query_arg('wc_error', rawurlencode(__('You must be logged in to download files.', 'woocommerce')), wc_get_page_permalink('myaccount')));
exit;
} else {
self::download_error(__('You must be logged in to download files.', 'woocommerce') . ' <a href="' . esc_url(wp_login_url(wc_get_page_permalink('myaccount'))) . '" class="wc-forward">' . __('Login', 'woocommerce') . '</a>', __('Log in to Download Files', 'woocommerce'), 403);
}
} elseif (!current_user_can('download_file', $download)) {
self::download_error(__('This is not your download link.', 'woocommerce'), '', 403);
}
}
}
public static function count_download($download_data)
{
wc_deprecated_function('WC_Download_Handler::count_download', '4.4.0', '');
}
public static function download($file_path, $product_id)
{
if (!$file_path) {
self::download_error(__('No file defined', 'woocommerce'));
}
$filename = basename($file_path);
if (strstr($filename, '?')) {
$filename = current(explode('?', $filename));
}
$filename = apply_filters('woocommerce_file_download_filename', $filename, $product_id);
$file_download_method = apply_filters('woocommerce_file_download_method', get_option('woocommerce_file_download_method', 'force'), $product_id, $file_path);
add_action('nocache_headers', array(__CLASS__, 'ie_nocache_headers_fix'));
do_action('woocommerce_download_file_' . $file_download_method, $file_path, $filename);
}
public static function download_file_redirect($file_path, $filename = '')
{
header('Location: ' . $file_path);
exit;
}
public static function parse_file_path($file_path)
{
$wp_uploads = wp_upload_dir();
$wp_uploads_dir = $wp_uploads['basedir'];
$wp_uploads_url = $wp_uploads['baseurl'];
$replacements = array($wp_uploads_url => $wp_uploads_dir, network_site_url('/', 'https') => ABSPATH, str_replace('https:', 'http:', network_site_url('/', 'http')) => ABSPATH, site_url('/', 'https') => ABSPATH, str_replace('https:', 'http:', site_url('/', 'http')) => ABSPATH);
$file_path = str_replace(array_keys($replacements), array_values($replacements), $file_path);
$parsed_file_path = wp_parse_url($file_path);
$remote_file = true;
if ('//' === substr($file_path, 0, 2)) {
return array('remote_file' => true, 'file_path' => is_ssl() ? 'https:' . $file_path : 'http:' . $file_path);
}
if (file_exists(ABSPATH . $file_path)) {
$remote_file = false;
$file_path = ABSPATH . $file_path;
} elseif ('/wp-content' === substr($file_path, 0, 11)) {
$remote_file = false;
$file_path = realpath(WP_CONTENT_DIR . substr($file_path, 11));
} elseif ((!isset($parsed_file_path['scheme']) || !in_array($parsed_file_path['scheme'], array('http', 'https', 'ftp'), true)) && isset($parsed_file_path['path']) && file_exists($parsed_file_path['path'])) {
$remote_file = false;
$file_path = $parsed_file_path['path'];
}
return array('remote_file' => $remote_file, 'file_path' => $file_path);
}
public static function download_file_xsendfile($file_path, $filename)
{
$parsed_file_path = self::parse_file_path($file_path);
if ($parsed_file_path['remote_file'] && !apply_filters('woocommerce_use_xsendfile_for_remote', false)) {
do_action('woocommerce_download_file_force', $file_path, $filename);
return;
}
if (function_exists('apache_get_modules') && in_array('mod_xsendfile', apache_get_modules(), true)) {
self::download_headers($parsed_file_path['file_path'], $filename);
$filepath = apply_filters('woocommerce_download_file_xsendfile_file_path', $parsed_file_path['file_path'], $file_path, $filename, $parsed_file_path);
header('X-Sendfile: ' . $filepath);
exit;
} elseif (stristr(getenv('SERVER_SOFTWARE'), 'lighttpd')) {
self::download_headers($parsed_file_path['file_path'], $filename);
$filepath = apply_filters('woocommerce_download_file_xsendfile_lighttpd_file_path', $parsed_file_path['file_path'], $file_path, $filename, $parsed_file_path);
header('X-Lighttpd-Sendfile: ' . $filepath);
exit;
} elseif (stristr(getenv('SERVER_SOFTWARE'), 'nginx') || stristr(getenv('SERVER_SOFTWARE'), 'cherokee')) {
self::download_headers($parsed_file_path['file_path'], $filename);
$xsendfile_path = trim(preg_replace('`^' . str_replace('\\', '/', getcwd()) . '`', '', $parsed_file_path['file_path']), '/');
$xsendfile_path = apply_filters('woocommerce_download_file_xsendfile_x_accel_redirect_file_path', $xsendfile_path, $file_path, $filename, $parsed_file_path);
header("X-Accel-Redirect: /{$xsendfile_path}");
exit;
}
wc_get_logger()->warning(sprintf(__('%1$s could not be served using the X-Accel-Redirect/X-Sendfile method. A Force Download will be used instead.', 'woocommerce'), $file_path));
self::download_file_force($file_path, $filename);
}
protected static function get_download_range($file_size)
{
$start = 0;
$download_range = array('start' => $start, 'is_range_valid' => false, 'is_range_request' => false);
if (!$file_size) {
return $download_range;
}
$end = $file_size - 1;
$download_range['length'] = $file_size;
if (isset($_SERVER['HTTP_RANGE'])) {
$http_range = sanitize_text_field(wp_unslash($_SERVER['HTTP_RANGE']));
$download_range['is_range_request'] = true;
$c_start = $start;
$c_end = $end;
list(, $range) = explode('=', $http_range, 2);
if (strpos($range, ',') !== false) {
return $download_range;
}
if ('-' === $range[0]) {
$c_start = $file_size - substr($range, 1);
} else {
$range = explode('-', $range);
$c_start = isset($range[0]) && is_numeric($range[0]) ? (int) $range[0] : 0;
$c_end = isset($range[1]) && is_numeric($range[1]) ? (int) $range[1] : $file_size;
}
$c_end = $c_end > $end ? $end : $c_end;
if ($c_start > $c_end || $c_start > $file_size - 1 || $c_end >= $file_size) {
return $download_range;
}
$start = $c_start;
$end = $c_end;
$length = $end - $start + 1;
$download_range['start'] = $start;
$download_range['length'] = $length;
$download_range['is_range_valid'] = true;
}
return $download_range;
}
public static function download_file_force($file_path, $filename)
{
$parsed_file_path = self::parse_file_path($file_path);
$download_range = self::get_download_range(@filesize($parsed_file_path['file_path']));
self::download_headers($parsed_file_path['file_path'], $filename, $download_range);
$start = isset($download_range['start']) ? $download_range['start'] : 0;
$length = isset($download_range['length']) ? $download_range['length'] : 0;
if (!self::readfile_chunked($parsed_file_path['file_path'], $start, $length)) {
if ($parsed_file_path['remote_file'] && 'yes' === get_option('woocommerce_downloads_redirect_fallback_allowed')) {
wc_get_logger()->warning(sprintf(__('%1$s could not be served using the Force Download method. A redirect will be used instead.', 'woocommerce'), $file_path));
self::download_file_redirect($file_path);
} else {
self::download_error(__('File not found', 'woocommerce'));
}
}
exit;
}
private static function get_download_content_type($file_path)
{
$file_extension = strtolower(substr(strrchr($file_path, '.'), 1));
$ctype = 'application/force-download';
foreach (get_allowed_mime_types() as $mime => $type) {
$mimes = explode('|', $mime);
if (in_array($file_extension, $mimes, true)) {
$ctype = $type;
break;
}
}
return $ctype;
}
private static function download_headers($file_path, $filename, $download_range = array())
{
self::check_server_config();
self::clean_buffers();
wc_nocache_headers();
header('X-Robots-Tag: noindex, nofollow', true);
header('Content-Type: ' . self::get_download_content_type($file_path));
header('Content-Description: File Transfer');
header('Content-Disposition: attachment; filename="' . $filename . '";');
header('Content-Transfer-Encoding: binary');
$file_size = @filesize($file_path);
if (!$file_size) {
return;
}
if (isset($download_range['is_range_request']) && true === $download_range['is_range_request']) {
if (false === $download_range['is_range_valid']) {
header('HTTP/1.1 416 Requested Range Not Satisfiable');
header('Content-Range: bytes 0-' . ($file_size - 1) . '/' . $file_size);
exit;
}
$start = $download_range['start'];
$end = $download_range['start'] + $download_range['length'] - 1;
$length = $download_range['length'];
header('HTTP/1.1 206 Partial Content');
header("Accept-Ranges: 0-{$file_size}");
header("Content-Range: bytes {$start}-{$end}/{$file_size}");
header("Content-Length: {$length}");
} else {
header('Content-Length: ' . $file_size);
}
}
private static function check_server_config()
{
wc_set_time_limit(0);
if (function_exists('apache_setenv')) {
@apache_setenv('no-gzip', 1);
}
@ini_set('zlib.output_compression', 'Off');
@session_write_close();
}
private static function clean_buffers()
{
if (ob_get_level()) {
$levels = ob_get_level();
for ($i = 0; $i < $levels; $i++) {
@ob_end_clean();
}
} else {
@ob_end_clean();
}
}
public static function readfile_chunked($file, $start = 0, $length = 0)
{
if (!defined('WC_CHUNK_SIZE')) {
define('WC_CHUNK_SIZE', 1024 * 1024);
}
$handle = @fopen($file, 'r');
if (false === $handle) {
return false;
}
if (!$length) {
$length = @filesize($file);
}
$read_length = (int) WC_CHUNK_SIZE;
if ($length) {
$end = $start + $length - 1;
@fseek($handle, $start);
$p = @ftell($handle);
while (!@feof($handle) && $p <= $end) {
if ($p + $read_length > $end) {
$read_length = $end - $p + 1;
}
echo @fread($handle, $read_length);
$p = @ftell($handle);
if (ob_get_length()) {
ob_flush();
flush();
}
}
} else {
while (!@feof($handle)) {
echo @fread($handle, $read_length);
if (ob_get_length()) {
ob_flush();
flush();
}
}
}
return @fclose($handle);
}
public static function ie_nocache_headers_fix($headers)
{
if (is_ssl() && !empty($GLOBALS['is_IE'])) {
$headers['Cache-Control'] = 'private';
unset($headers['Pragma']);
}
return $headers;
}
private static function download_error($message, $title = '', $status = 404)
{
header('Content-Type: ' . get_option('html_type') . '; charset=' . get_option('blog_charset'));
header_remove('Content-Description;');
header_remove('Content-Disposition');
header_remove('Content-Transfer-Encoding');
if (!strstr($message, '<a ')) {
$message .= ' <a href="' . esc_url(wc_get_page_permalink('shop')) . '" class="wc-forward">' . esc_html__('Go to shop', 'woocommerce') . '</a>';
}
wp_die($message, $title, array('response' => $status));
}
}
WC_Download_Handler::init();