Сниппет закачки файлов со статистикой

Это сниппет писался для сайта-каталога программ.
Основные требования:
— доступ к файлу только через скрипт, никаких прямых ссылок
— файл отдается через промежуточную страницу с задержкой 5 сек
— вести подсчет количества закачек
— поддержка докачки

Итак, для начала надо создать TV-параметр типа file, название пусть будет тоже file. Сюда будет вводится путь к файлу, поэтому его нужно привязать к шаблону, который выводит страницу с описанием программы.

Далее для счетчика закачек создадим в базе данных таблицу modx_downloads с полями:

id    int(10)    Primary key
file    varchar
(255)    utf8_general_ci
count    
int(10)


После этого созданим сниппет getFile, который и будет обрабатывать закачку:

<?php
function is_bot() {
    $botlist
= array("Teoma", "alexa", "froogle", "Gigabot", "inktomi",
   
"looksmart", "URL_Spider_SQL", "Firefly", "NationalDirectory",
   
"Ask Jeeves", "TECNOSEEK", "InfoSeek", "WebFindBot", "girafabot",
   
"crawler", "www.galaxy.com", "Googlebot", "Scooter", "Slurp",
   
"msnbot", "appie", "FAST", "WebBug", "Spade", "ZyBorg", "rabaz",
   
"Baiduspider", "Feedfetcher-Google", "TechnoratiSnoop", "Rankivabot",
   
"Mediapartners-Google", "Sogou web spider", "WebAlta Crawler","TweetmemeBot",
   
"Butterfly","Twitturls","Me.dium","Twiceler");
 
   
foreach($botlist as $bot) {
       
if(strpos($_SERVER['HTTP_USER_AGENT'],$bot)!==false)
       
return true;    // Это бот
   
}
 
   
return false;   // Не бот
}

if ($_GET['id']) {
   
global $modx;
    $id_tv
= $modx->getTemplateVarOutput(array('file'), $_GET['id']); // Получаем значение TV file
    $file
= $id_tv['file']; // Получаем путь к файлу
   
   
if (file_exists($file)) { // Если файл существует...
       
if (!is_bot() && $_GET['go'] == true) { // ... а посетитель не бот, и стоит GET-параметр go, то отдаем файл на закачку
       
            $table
= $modx->getFullTableName('downloads');
            $id
= $modx->db->escape($_GET['id']);
            $file_path
= $modx->db->escape($file);
            $sql
= "INSERT INTO $table (id, file, count) VALUES ('$id', '$file_path', 1) ON DUPLICATE KEY UPDATE count=count+1"; // Готовим строку запроса
            $result
= $modx->db->query($sql); // Обновляем данные счетчика
           
if (!$result) die('Error: Query Failed!');
           
            $file_name
= basename($file); // Получаем имя файла
            $fsize
= filesize($file); // и его размер
            $ftime
= date("D, d M Y H:i:s T", filemtime($file));
           
            $file_handler
= @fopen($file, "rb");
           
           
if (!$file_handler) {
                header
("HTTP/1.0 403 Forbidden");
               
exit;
           
}
           
           
if ($HTTP_SERVER_VARS["HTTP_RANGE"]) {
           
                $range
= $HTTP_SERVER_VARS["HTTP_RANGE"];
                $range
= str_replace("bytes=", "", $range);
                $range
= str_replace("-", "", $range);
               
               
if ($range) {
                    fseek
($file_handler, $range);
               
}
           
}
           
           
           
if ($range) {
                header
("HTTP/1.1 206 Partial Content");
           
} else {
                header
("HTTP/1.1 200 OK");
           
}
           
            header
("Content-Disposition: attachment; filename=$file_name");
            header
("Last-Modified: $ftime");
            header
("Accept-Ranges: bytes");
            header
("Content-Length: ".($fsize-$range));
            header
("Content-Range: bytes $range-".($fsize-1)."/".$fsize);
            header
("Content-type: application/octet-stream");
           
           
while (!feof ($file_handler)) {
                echo fread
($file_handler, 100);
           
           
}
           
// Отдали файл на закачку
           
            fclose
($file_handler);
           
exit;
       
}
   
} else { // Если файл не существует, возвращаем 404
        header
("HTTP/1.0 404 Not Found");
       
exit;
   
};
   
} else { die('Error: Missing parameter id'); }
?>


Создадим еще один сниппет getFileUrl, вспомогательный, который будет выводить ссылку на закачку,:

<?php
if ($_GET['id']) {
   
return 'download.html?id='.$_GET['id'].'&go=true';
} else { die('Error: Missing parameter id'); }
?>


При наличии GET-параметра go=true файл отдается сразу, без задержки.

Создадим шаблон download, который должен иметь примерно такой вид:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ru">
   
<head>
       
<title>Начинается загрузка файла :: Omegicus LLC</title>
       
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
       
<base href="https://omegicus.org/" />
       
<meta name="keywords" content="" />
       
<meta name="description" content="" />
       
<meta http-equiv="refresh" content="5; url=" />
       
<link rel="stylesheet" href="assets/templates/soft/style.css" type="text/css"media="screen" />
       
<!--[if IE]><link rel="stylesheet" href="assets/templates/soft/ie.css" type="text/css" media="screen" /><![endif]-->
   
</head>
   
<body>  
       
<table class="download">
           
<tr>
               
<td>
                   
<h5>Загрузка программы начнется через 5 секунд. Если этого не произошло, то нажмите <a href="">здесь</a>.</h5>
                   

Это сниппет писался для сайта-каталога программ.
Основные требования:
— доступ к файлу только через скрипт, никаких прямых ссылок
— файл отдается через промежуточную страницу с задержкой 5 сек
— вести подсчет количества закачек
— поддержка докачки


               
</td>
           
</tr>
       
</table>
   
</body>
</html>


И наконец, создаем страницу download, через которую и будет отдаваться файл. Нужно присвоить ей шаблон download, скинуть галки «Доступен для поиска» и «Кешируемый», а в контент вставить вызов сниппета getFile:


Теперь достаточно создать документ, залить файл, и в контенте разместить ссылку на скачивание файла, которая должна иметь вид ([docid] — id страницы программы):

http://yoursite.com/download.html?id=[docid]


При нажатии на ссылку открывается страница download.html, идет пауза 5 сек, и открывается окно сохранения файла.

Отправить заявку на создание сайта

Сообщение отправлено