Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
A class to hide downloadable links and count downloads.
<?php
/**
* Class to hide file download links and count download number.
*/
/**
* Class Downloader.
*
* Requires the following table in database:
*
* CREATE TABLE `wp_downloads` (
* `id` bigint(20) UNSIGNED NOT NULL,
* `url` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '',
* `download_link` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '',
* `count` bigint(20) UNSIGNED NOT NULL DEFAULT '0'
* ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
*
*/
class Downloader {
/**
* Class table name.
*/
const TABLE = 'downloads';
/**
* Class table name.
*
* @var string $table
*/
protected static $table;
/**
* Base of download links.
*
* @var string $link_base
*/
protected static $link_base = '/downloads/';
/**
* Downloader constructor.
*/
public function __construct() {
/** @var wpdb $wpdb */
global $wpdb;
self::$table = $wpdb->prefix . self::TABLE;
add_action( 'init', array( $this, 'rewrite_download_link' ) );
}
/**
* Get download link from url.
*
* @param $url
*
* @return string
*/
public static function get_link( $url ) {
/** @var wpdb $wpdb */
global $wpdb;
$record = $wpdb->get_row(
$wpdb->prepare( 'SELECT download_link from wp_downloads where url = %s', $url )
);
$download_link = ! empty( $record ) ? $record->download_link : '';
return $download_link;
}
/**
* Get url from download link.
*
* @param $download_link
*
* @return string
*/
public static function get_url( $download_link ) {
/** @var wpdb $wpdb */
global $wpdb;
$record = $wpdb->get_row(
$wpdb->prepare( 'SELECT url from wp_downloads where download_link = %s', $download_link )
);
$url = ! empty( $record ) ? $record->url : '';
return $url;
}
/**
* Get download count.
*
* @param $url
*
* @return int
*/
public static function get_count( $url ) {
/** @var wpdb $wpdb */
global $wpdb;
$record = $wpdb->get_row(
$wpdb->prepare( 'SELECT count from wp_downloads where url = %s', $url )
);
$count = ! empty( $record ) ? $record->count : - 1;
return $count;
}
/**
* Create new download link from $url.
*
* @param $url
*
* @return string
*/
public static function create( $url ) {
/** @var wpdb $wpdb */
global $wpdb;
$download_link = self::get_link( $url );
if ( $download_link ) {
return '';
}
$download_link = self::$link_base . wp_hash( $url );
$data = array(
'url' => $url,
'download_link' => $download_link,
);
$result = $wpdb->insert( self::$table, $data );
$download_link = $result ? $download_link : '';
return $download_link;
}
/**
* Rewrite download link by its url.
* Increase download count.
*/
public function rewrite_download_link() {
/** @var wpdb $wpdb */
global $wpdb;
$uri = $_SERVER['REQUEST_URI'];
$path = wp_parse_url( $uri, PHP_URL_PATH );
if ( 0 === strpos( trailingslashit( $path ), self::$link_base ) ) {
$download_link = untrailingslashit( $path );
$url = self::get_url( $download_link );
if ( $url ) {
$count = self::get_count( $url );
$data = array(
'count' => ++ $count,
);
$where = array(
'url' => $url,
);
$wpdb->update( self::$table, $data, $where );
self::download_file( $url );
}
}
}
/**
* Download file.
*
* @param string $url file url.
*/
private static function download_file( $url ) {
if ( ! $url ) {
return;
}
$file_path = ABSPATH . wp_make_link_relative( $url );
$file_name = pathinfo( $file_path, PATHINFO_FILENAME );
$file_extension = pathinfo( $file_path, PATHINFO_EXTENSION );
switch ( $file_extension ) {
case 'png':
$content_type = 'image/png';
break;
case 'gif':
$content_type = 'image/gif';
break;
case 'tiff':
$content_type = 'image/tiff';
break;
case 'jpeg':
case 'jpg':
$content_type = 'image/jpg';
break;
default:
$content_type = 'application/force-download';
}
header( 'Expires: 0' );
header( 'Cache-Control: no-cache, no-store, must-revalidate' );
header( 'Cache-Control: pre-check=0, post-check=0, max-age=0', false );
header( 'Pragma: no-cache' );
header( "Content-type: {$content_type}" );
header( "Content-Disposition:attachment; filename={$file_name}.{$file_extension}" );
header( 'Content-Type: application/force-download' );
// @codingStandardsIgnoreLine
readfile( "{$file_path}" );
exit();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.