Прежде всего, обратите внимание на то, что все настройки мы храним в отдельном конфигурационном файле application/config/downloader.php.
<?php $config['filesdir'] = 'archive'; //имя папки с файлами (которые мы разрешаем скачивать) $config['linktime'] = '120'; //время жизни ссылки на файл (в сек) ?>
Загрузка этого файла выполняется к конструкторе контроллера (строка 14).
Метод index формирует страницу со списком файлов, которые находятся в папке archive. Чтение содержимого папки выполняется с помощью функции get_filenames (входит в File Helper фреймворка), а создание страницы происходит в представлении (application/views/filelist.php).
<?php
//показываем сообщение об ошибке, если оно есть
if ($this->session->flashdata('error')) {
echo '<h3>'.$this->session->flashdata('error').'</h3>';
}
?>
<h2>Список файлов</h2>
<ol>
<?php
if ($files) {
foreach ($files as $file) {
echo '<li>'.anchor('main/confirm/'.$file, $file).'</li>';
}
}
else {
echo '<p>Файлы не найдены</p>';
}
?>
</ol>
Как видите, ссылка на каждый из файлов, ведет на страницу main/confirm/file (строка 12), т.е. вызывает метод confirm контроллера и передает в качестве параметра имя файла.
Теперь разберем метод confirm. Он создает страницу с простой математической captcha, которую должен ввести посетитель для того, чтобы скачать файл.
Если captcha введена правильно, то будет создана временная ссылка (об этом чуть ниже) и отправлен редирект на страницу загрузки файла (main/download/link) (строка 50). В противном случае, посетитель останется на этой же странице.
Переходим к методу download. Здесь мы выполняем проверку временной ссылки и отправляем файл посетителю (строки 102 и 105).
Непосредсвенно отправка файла выполняется в методе _sendFile с помощью функции force_download (тоже входит в File Helper).
Если вы внимательно просматривали код, то конечно заметили использование модели mfilelink.
<?php
/**
* Эта модель предназначена для работы с временными ссылками на файлы
*
* @link https://www.simplecoding.org
* @author Стаценко Владимир <vova_33@gala.net>
*/
class MFileLink extends Model {
function MFileLink() {
parent::Model();
}
/**
* Создает временную ссылку и добавляет ее в базу
*
* @param $fileName - имя файла
* @return ссылку, если она создана, false - если возникла ошибка
*/
function createLink($fileName) {
$userIP = $_SERVER['REMOTE_ADDR'];
$fileLink = md5($userIP.time());
//проверяем существование файла
if (!get_file_info($this->config->item('filesdir').'/'.$fileName)) {
return false;
}
$qCreateLink = 'INSERT INTO file_downloads (ip, fileLink, expired, fileName)'
.' VALUES (?, ?, NOW() + INTERVAL '.$this->config->item('linktime').' SECOND, ?)';
if ($this->db->query($qCreateLink,
array(
$userIP,
$fileLink,
$fileName
))) {
return $fileLink;
}
else {
return false;
}
}
/**
* Проверяет временную ссылку
*
* @param $link - временная ссылка на файл
* @return имя файла - если ссылка рабочая, false - если нет.
*/
function checkFileLink($link) {
$userIP = $_SERVER['REMOTE_ADDR'];
$qCheckLink = 'SELECT fileName FROM file_downloads WHERE ip=? AND fileLink=? AND (expired >= NOW())';
$res = $this->db->query($qCheckLink, array($userIP, $link));
if ($res->num_rows() == 1) {
$r = $res->result_array();
return $r[0]['fileName'];
}
else {
return false;
}
}
}
?>
Как видите, она содержит всего два метода (не считая конструктора).
1) createLink – создает временную ссылку на выбранный файл и сохраняет её в базе данных.
2) checkFileLink – проверяет, можно ли данному посетителю скачивать файл. Для этого, метод ищет подходящую запись в базе данных. Должны совпадать IP, имя ссылки и время завершения её действия должно быть меньше текущего.
Теперь осталось только закрыть доступ к папке archive.
Для этого в корне сайта создаём файл .htaccess со следующим содержимым.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /path_to_site/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond $1 !^(index\.php|images|robots\.txt|css)
RewriteRule ^(.*)$ index.php/$1 [L]
RewriteRule ^(archive.*) index.php/$1 [L]
</IfModule>
<IfModule !mod_rewrite.c>
ErrorDocument 404 /index.php
</IfModule>
Здесь для нас важно только одно правило (строка 10). С его помощью ко всем запросы, которые начинаются со слова archive добавляется index.php. Таким образом, запрос вроде mysite.com/archive/file.name превращается в mysite.com/index.php/archive/file.name.
В результате запрос будет обработан движком CodeIgniter и посетитель увидит стандартную страницу с 404-ой ошибкой.
Продолжение на следующей странице >>>


