Last active
May 22, 2022 22:34
-
-
Save Exieros/64db3c7404f98f0beb75b007cb16d04a to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| * Счетчик скачиваний файлов по attach-id. | |
| * Скачивания будут учитываться если скачивать attach по ссылке вида site.ru/download/{id} | |
| * Чтобы получить кол-во скачиваний вызвать функцию Downloader::get_count($id); | |
| */ | |
| namespace Exieros\Utils; | |
| class Downloader { | |
| private const TABLE = 'downloads'; | |
| protected static string $table; | |
| protected static string $link_base = '/download/'; | |
| public function __construct() { | |
| global $wpdb; | |
| self::$table = $wpdb->prefix . self::TABLE; | |
| add_action( 'init', [ $this, 'rewrite_download_link' ] ); | |
| $query = $wpdb->prepare( 'SHOW TABLES LIKE %s', self::$table ); | |
| if ( $wpdb->get_var( $query ) !== self::$table ) { | |
| $table_name = self::$table; | |
| $wpdb->query(<<<SQL | |
| CREATE TABLE `{$table_name}` ( | |
| `id` bigint(20) UNSIGNED NOT NULL, | |
| `count` bigint(20) UNSIGNED NOT NULL DEFAULT '0' | |
| ) ENGINE=InnoDB DEFAULT CHARSET=utf8; | |
| SQL); | |
| } | |
| } | |
| /** | |
| * Получить кол-во скачиваний по attachment-id | |
| * @param int $id attachment id. | |
| * @return int | |
| */ | |
| public static function get_count( int $id ): int { | |
| global $wpdb; | |
| $record = $wpdb->get_row( | |
| $wpdb->prepare( "SELECT count FROM {$wpdb->prefix}downloads WHERE id = %s", $id ) | |
| ); | |
| return $record->count ?? - 1; | |
| } | |
| /** | |
| * Создать запись в таблице скачиваний по attachment-id | |
| * @param int $id Attachment id | |
| */ | |
| public static function create( int $id ): void { | |
| global $wpdb; | |
| $wpdb->insert( self::$table, [ | |
| 'count' => 1, | |
| 'id' => $id, | |
| ] ); | |
| } | |
| public function rewrite_download_link(): void { | |
| $uri = ''; | |
| if ( isset( $_SERVER['REQUEST_URI'] ) ) { | |
| $uri = filter_var( wp_unslash( $_SERVER['REQUEST_URI'] ), FILTER_SANITIZE_STRING ); | |
| } | |
| $path = wp_parse_url( $uri, PHP_URL_PATH ); | |
| if (str_starts_with(trailingslashit($path), self::$link_base)) { | |
| $download_link = untrailingslashit( $path ); | |
| $id = (int) str_replace(self::$link_base, '', $download_link); | |
| if($id === 0 ){ | |
| return; | |
| } | |
| $real_path = get_attached_file($id); | |
| if($real_path===''){ | |
| return; | |
| } | |
| $this->increment_count( $id ); | |
| self::download_file($id); | |
| } | |
| } | |
| /** | |
| * Скачать файл по attachment-id | |
| * @param int $id attachment id | |
| */ | |
| private static function download_file( int $id ): void { | |
| if ( ! $id ) { | |
| return; | |
| } | |
| $file_path = get_attached_file($id); | |
| if ( !$file_path ) { | |
| return; | |
| } | |
| $file_name = rawurlencode( pathinfo( $file_path, PATHINFO_FILENAME ) ); | |
| $file_extension = rawurlencode( pathinfo( $file_path, PATHINFO_EXTENSION ) ); | |
| $file_size = filesize( $file_path ); | |
| $known_content_types = [ | |
| 'html' => 'text/html', | |
| 'htm' => 'text/html', | |
| 'txt' => 'text/plain', | |
| 'jpg' => 'image/jpg', | |
| 'jpeg' => 'image/jpg', | |
| 'png' => 'image/png', | |
| 'gif' => 'image/gif', | |
| 'tiff' => 'image/tiff', | |
| 'pdf' => 'application/pdf', | |
| 'doc' => 'application/msword', | |
| 'docx' => 'application/msword', | |
| 'xls' => 'application/vnd.ms-excel', | |
| 'xlsx' => 'application/vnd.ms-excel', | |
| 'ppt' => 'application/vnd.ms-powerpoint', | |
| 'pptx' => 'application/vnd.ms-powerpoint', | |
| 'php' => 'text/plain', | |
| 'exe' => 'application/octet-stream', | |
| 'zip' => 'application/zip', | |
| ]; | |
| $content_type = 'application/force-download'; | |
| if ( array_key_exists( $file_extension, $known_content_types ) ) { | |
| $content_type = $known_content_types[ $file_extension ]; | |
| } | |
| 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-Transfer-Encoding: binary' ); | |
| header( "Content-Length: {$file_size}" ); | |
| readfile( $file_path ); | |
| exit(); | |
| } | |
| /** | |
| * Увеличить счетчик скачивания на единицу | |
| * @param int $id | |
| */ | |
| private function increment_count( int $id ): void { | |
| global $wpdb; | |
| $count = self::get_count( $id ); | |
| if($count === -1){ | |
| self::create($id); | |
| }else { | |
| $wpdb->update(self::$table, ['count' => ++$count], ['id' => $id]); | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment