
Прежде всего, обратите внимание на то, что все настройки мы храним в отдельном конфигурационном файле 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-ой ошибкой.
Продолжение на следующей странице >>>