Менеджер файлов для нашей CMS Часть 2

 

Добрый день дорогой читатель Блога RS! Добро пожаловать на продолжение цикла статей посвященному разработки блога с нуля. Сегодня мы закончим создания менеджера файлов для нашей CMS. Первая часть поста, где я описывал логику работы нашего нового модуля Вы можете найти по этой ссылке. Поначалу может показаться, что предыдущий пост был пустой тратой времени, но это не так! После теоретической части будет легче понять практическую. В общем хватит лишних слов, приступим к делу

 

 

Подготовка

 

Первым делом хочу сказать, что если Вы на блоге впервые, то эта информация может показаться Вам совершенно не нужной. Этот пост, как впрочем и большинство других, является часть одного цикла статей, посвященному разработки блога с нуля. Если у Вас есть желание на практике научится создавать свой собственные проекты на php, то заходите по ссылке, что я Вам дал, и начинайте с первой части.

Так же, что бы не пропускать новые посты, подпишитесь по RSS через ридер или почту. Так же можете добавить меня в твиттере, я транслирую туда новые посты.

Теперь, что касается графики которая нам сегодня понадобится. Вот Вам архив, засуньте изображения из него в папку /admin/img/

Далее нам понадобится две папки в корне нашего движка.

  • Папка upload, я совершенно случайно оставил эту папку когда архевировал движок, и выкладывал Вам его в посте "Установка нашей CMS". В этой папке мы будем хранить всю графику которую загрузим с помощью нашего менеджера файлов.
  • Папка download. В нее мы будем хранить все архивы, которые загрузим с помощью нашего загрузчика файлов.

Цели и порядок создания нашего менеджера уже есть в предыдущем посте, поэтому приступим к разработки  

 

Ссылка на менеджер файлов

 

Открываем наш админский шаблон menu.html и добавляем в него новую кнопку

<table width="500px" cellpadding="0" cellspacing="0" border="0" align="center">
<tr>
<td width="100px" height="100px" valign="top" align="center"><a href="?page=add_content"><img src="img/add_content.jpg" border="0px"></a></td>
<td width="100px" height="100px" valign="top" align="center"><a href="?page=all_content"><img src="img/all_content.jpg" border="0px"></a></td>
<td width="100px" height="100px" valign="top" align="center"><a href="?page=all_menu"><img src="img/edd_menu.jpg" border="0px"></a></td>
<td width="100px" height="100px" valign="top" align="center"><a href="?page=mfiles"><img src="img/mfiles.jpg" border="0px"></a></td>
<td width="100px" height="100px" valign="top" align="center"><a href="?page=contact"><img src="img/contact.jpg" border="0px"></a></td>
</tr>
</table>

Таким образом получаем вот такое меню

 

Менеджер файлов - Добавление файла

 

>Форма ввода информации

 

Создадим шаблон, с формой, назовем его mfiles.html и поместим в папку с админскими шаблонами

<div>Менеджер файлов</div>
<br/><br/>
<form action="index.php?page=mfiles" method="post" ENCTYPE="multipart/form-data" name="fimg">
<input size="50" name="userfile" type="file">
<br/><br/><input name="submit" type="submit" value="Добавить">
</form>
<br/><div>[_url]</div>

Тут обратите внимание на вот этот атрибут

ENCTYPE="multipart/form-data"

Этот атрибут обезопасит Вас от всяческих неприятностей, например на сервер не переместиться битый архив или не открывающееся изображение!

 

>Функция вывода шаблона

 

Создаем файл mfiles.php и помещаем его в модули нашей админ панели. Вот первая функция нашего нового модуля

function formfiles($linkFORfile)//Функция вывода формы
{
$sm_read = file("templates/mfiles.html");//...подключаем шаблон
$sm_read = implode("",$sm_read);//функция file() возвращаем массив, поэтому склеиваем его

$sm_read = str_replace("[_url]",$linkFORfile,$sm_read);//Меняем код слово на ссылку файла

return $sm_read;//Выводим с генерированный html код
}

Как Вы видите, тут ничего сложного нет, подключается шаблон и выводится результат.

 

>Подключаем функцию вывода шаблона

 

Открываем наш шаблонизатор, index.php, и добавляем туда вот этот код

//МЕНЕДЖЕР ФАЙЛОВ
if($page == "mfiles")
{
include("moduls/mfiles.php");//подключаем модуль

//если сообщение с url не существует..
if(!isset($linkFORfile))$linkFORfile = "";//..то в отчет записываем пустоту
$txt = formfiles($linkFORfile);
}
//МЕНЕДЖЕР ФАЙЛОВ

В $linkFORfile хранится отчет о загрузки, то есть ссылка на файл, который мы загрузили. Если отчета нет, то есть мы еще не загружали файл, то мы в принудительном порядке записываем в отчет пустоту. Вот результат проделанной нами работы

 

>Обработчик добавление файла

 

В файле mfiles.php, в верху вставляем следующий код

//ДОБАВЛЕНИЕ ФАЙЛА
//Если форма была заполнена и отправлена то определяем переменную в которую запихнем файл
if(isset($_FILES['userfile']))$loadfile = $_FILES['userfile'];

if(isset($loadfile))//Если файл был отправлен
{
//Определяем тип файла
if($loadfile['type'] == "application/x-rar-compressed")$type = ".rar";
if($loadfile['type'] == "application/zip")$type = ".zip";
if($loadfile['type'] == "image/jpeg")$type = ".jpg";
if($loadfile['type'] == "image/gif")$type = ".gif";
if($loadfile['type'] == "image/png")$type = ".png";
if($loadfile['type'] == "image/bmp")$type = ".bmp";
//Определяем тип файла

if(isset($type))//Если тип определен и соответствует требованиям
{
//генерируем новое имя для файла
$name_f = date("His");//имя состоит из даты
$indifikator = mt_rand(1, 10000);//с генерированного числа от 1 до 10000
$name_f .= $indifikator;//склеиваем дату и с генерированное число
//генерируем новое имя для файла

//Определяем в какую папку загрузить файл
if($type == ".rar" OR $type == ".zip")//Если файл является архивом то..
{
$name_f = "download_".$name_f.$type;//...прикручиваем к названию файла приставку download и тип (download_имя.rar)
$folder = "../download/";//так же определяем имя папки куда загрузится файл
}
else//Если файл является изображением
{
$name_f = $name_f.$type;//...прикручиваем к названию файла тип (имя.jpg)
$folder = "../upload/";//так же определяем имя папки куда загрузится файл
}

copy($loadfile['tmp_name'], $folder.$name_f);//Копируем файл с новым именем в определенную папку
$linkFORfile = $folder.$name_f;//Составляем ссылку которую покажем на экране
}
else $linkFORfile = "Некорректный тип файла";//Сообщение о некорректности типа файла
}
//ДОБАВЛЕНИЕ ФАЙЛА

В коде все за комментировано, даже не знаю что добавить. Единственное, что я пожалуй сделаю, это еще раз поясню логику.

  • Первым делом скрипт узнает, был ли послан файл. Если да, то определит тип этого файла.
  • Затем с генерирует новое имя для него.
  • После, по типу определить папку в которой необходимо сохранить файл.
  • Сохранит файл
  • С генерирует сообщение, которое в последствие увидит администратор.

На этом логика окончена.

После внедрения этого кусочка кода, наш менеджер файлов, сможет сохранять необходимые нам файлы на сервере

 

Менеджер файлов - Реализация списка файлов

 

Список будет иметь три режима. Режим будет определяться значением $scan, которая будет объявляться с помощью GET запроса. По умолчанию режим списка будет равен нулю, то есть закрыт.

  • При $scan равной ноль таблица с списком будет прятаться с помощью стиля display:none; ( С этим элементом мы работали при реализации всплывающего меню на JS ).
  • При $scan равной единице, скрипт будет сканировать папку upload и выведет на экран все файлы что находятся в этой папке. display будет иметь значение block
  • При $scan равной двум, скрипт будет сканировать папку download тем самым выведет нам на экран все архивы. display будет иметь значение block

 

>Переделываем шаблон

 

Начнем с переделки нашего шаблона mfiles.html. Нам, в нем, необходимо создать таблицу, которая будет находится в блоковом теге див. У дива будет определен стиль display. Манипулировать этим стилем мы уже будем с помощью скрипта.

Вот переделанный шаблон

<div>Менеджер файлов</div>
<br/><br/>
<form action="index.php?page=mfiles" method="post" ENCTYPE="multipart/form-data" name="fimg">
<input size="50" name="userfile" type="file">
<br/><br/><input name="submit" type="submit" value="Добавить">
</form>
<br/><div>[_url]</div>
<br/><br/>
<a href="index.php?page=mfiles&scan=1">Список изображений</a> ::
<a href="index.php?page=mfiles&scan=2">Список архивов</a> ::
<a href="index.php?page=mfiles&scan=0">Закрыть список</a>

<br/><br/>
<div style="display:[_style];">
<form action="index.php?page=mfiles" method="post" name="del">
<table width="350px" cellpadding="0" cellspacing="0" border="0" align="center">
[_file]
<tr>
<td width="40px"><img src="[_img]" border="0px" width="40px" height="40px"></td>
<td align="center">[_link]</td>
<td align="center"><input type="checkbox" name="delF[[_del]]" value="[_delNAME]" /></td>
</tr>
[_file]
</table>
<br/><br/><input name="submit" type="submit" value="Удалить выбранные">
</form>
</div>

Я добавил ссылки на списки, так же саму таблицу. Давайте разберем код слова таблицы

  • [_style] - Будет содержать значение none или block для стиля display
  • [_file]...[_file] - Все что в этих код словах будет копировать многократно.
  • [_img] - будет содержать ссылку на иконку файла. В случае с изображениями, иконкой будет являться само изображение уменьшенное на 40 на 40 пикселей. В случае же с архивом, иконкой будет служить специально подготовленная картинка.
  • [_link] - Имя файла
  • [_del] - Так как у инпута с типом чек бокс в атрибуте name стоит массив, то это код слово будет обозначать идентификатор от 0 до n
  • [_delNAME] - Путь к удаляемому файлу.

Я все расписал очень подробно, надеюсь Вы разобрались

 

>Функция вывода списка

 

Разместим функцию, которую я приведу ниже, в файле mfiles.php в самом низу

function listFILE($typeSCAN,$sm_read)//Функция вывода списка
{
//Определяем какую папку открыл админ
if($typeSCAN == 1)$dir = '../upload';//папку с изображениями
if($typeSCAN == 2)$dir = '../download';//или папку с архивами

$data = opendir($dir); //сканируем файлы в папке
while (false !== ($one = readdir($data))) //собираем массив из результата сканирования
{
if($one != '.' AND $one != '..') //Удаляем точки
{
$files[] = $one;//формируем массив с именами файлов
}
}
closedir ($data);//закрываем папку

preg_match("/\[_file\](.*?)\[_file\]/s",$sm_read,$copy_sm);//вырезаем копию из шаблона (<tr>...</tr>)

for($i=0;isset($files[$i]);$i++)//генерируем строчки для таблицы
{
$copy_tp = $copy_sm[1];//делаем копию вырезанной части шаблона

//Определяем директорию из которой админу нужно вывести файлы
if($typeSCAN == 1)$img = $dir."/".$files[$i];//формируем пред просмотр ( пред просмотром в списке изображений являются сами изображения )
if($typeSCAN == 2)$img = "img/arh.jpg";//формируем пред просмотр ( пред просмотром в списке архивов является иконка архива )

//замена код слов
$copy_tp = str_replace("[_link]",$files[$i],$copy_tp);
$copy_tp = str_replace("[_img]",$img,$copy_tp);
$copy_tp = str_replace("[_del]",$i,$copy_tp);
$copy_tp = str_replace("[_delNAME]",$dir."/".$files[$i],$copy_tp);
//замена код слов

$result_sm .= $copy_tp;//Сохраняем с генерированную строчку таблицы в общую переменную
}

return $result_sm;//Выводим результат работы функции
}

Для старта функции нам понадобится знать режим открытия списка и копия шаблона. Я за комментировал каждую строчку в коде, я уверен Вы разберетесь

 

>Вызов функции вывода списка

 

Вызов этой функции будет происходить из функции вывода формы. То есть нам сейчас необходимо переделать первую нашу функцию

function formfiles($linkFORfile,$typeSCAN)//Функция вывода формы
{
$sm_read = file("templates/mfiles.html");//...подключаем шаблон
$sm_read = implode("",$sm_read);//функция file() возвращаем массив, поэтому склеиваем его

//-------------НОВЫЙ КУСОЧЕК КОДА
if($typeSCAN != 0)//Определяем открыл ли админ какой-нить список
{
$result_sm = listFILE($typeSCAN,$sm_read);//запускаем функцию вывода списка

//Если результат функции пустота..
if($result_sm == "")$sm_read = str_replace("[_style]","none",$sm_read);//..то прячем всю таблицу с глаз долой
//Если же не результат функции НЕ пустота
else $sm_read = str_replace("[_style]","block",$sm_read);//..то показываем таблицу админу
}
else $sm_read = str_replace("[_style]","none",$sm_read);//Если админ НЕ открыл/закрыл список то прячем таблицу
$sm_read = preg_replace("/\[_file\].*?\[_file\]/s",$result_sm,$sm_read);//заменяем часть таблицы в шаблоне на с генерированный результат работы выше
//-------------НОВЫЙ КУСОЧЕК КОДА

$sm_read = str_replace("[_url]",$linkFORfile,$sm_read);//Меняем код слово на ссылку файла
return $sm_read;//Выводим с генерированный html код
}

Я выделил где новый кусочек кода, он за комментирован, так что разобраться в нем не составит труда. Там по сути происходит проверка результат функции вывода списка. Если пустота то стиль меняется на none если же нет, то стиль меняется на block.

Да и еще, обратите внимание на вот эту строчку

function formfiles($linkFORfile,$typeSCAN)//Функция вывода формы

Я добавил сюда еще одну стартовую переменную, стало быть нам необходимо будет переделать подключение в index.php. Но прежде чем переделывать подключение, нам необходимо объявить нашу $scan

 

>$scan

 

В самом верху, файла mfiles.php, вставляем вот этот кусочек кода

//ОПРЕДЕЛЯЕМ КАКОЙ СПИСОК ОТКРЫЛ АДМИН
if(isset($_GET['scan']))$scan = $_GET['scan']; else $scan = 0;//определяем какой список открыл админ, и открыл ли его вообще
if(isset($scan))
{
if(!preg_match("/^[0-9]+$/",$scan) OR $scan > 2)//так как переменная scan должна быть числом, то..
{
header("location: index.php?page=mfiles");//..перенаправление
exit;//на страницу менеджера если это не так ($scan не есть число)
}
}
//ОПРЕДЕЛЯЕМ КАКОЙ СПИСОК ОТКРЫЛ АДМИН

Почему я отдельно остановился на этих строчка кода. Я по привычке воткнул проверку переменной. Для чего? Для того, что бы в эту переменную не пытались засунуть какой нить код, который мог бы повредить нашему движку. Суть защиты проста. Я знаю, что переменная должна содержать лишь 3 варианта значений, и при этом все три варианта являются числовым значением. Я просто проверяю переменную, является ли она числом. Если нет то скрипт останавливается. Вот и весь смысл

В скором будущем, я напишу пост, о защите блога, в котором мы будем подвергать такой проверки почти каждую переменную в нашем движке!

Кстати, в данном коде присутствует регулярное выражение, если вы не умеете ими пользоваться то почитайте вот этот пост

 

>Редактируем подключение модуля "Менеджер файлов"

 

Заходим в файл index.php и редактируем наше подключение

//МЕНЕДЖЕР ФАЙЛОВ
if($page == "mfiles")
{
include("moduls/mfiles.php");//подключаем модуль
//если сообщение с url не сущесвует..
if(!isset($linkFORfile))$linkFORfile = "";//..то в отчет записываем пустоту
$txt = formfiles($linkFORfile,$scan);
}
//МЕНЕДЖЕР ФАЙЛОВ

Думаю тут без комментариев

Ну что ж. Теперь наш менеджер умеет открывать списки. Осталось реализовать удаление, и наш загрузчик будет готов!


Менеджер файлов - Удаление

 

Мы в шаблоне mfiles.html уже ввели форму для удаления. Чек боксы и соответствующая кнопка ведь присутствую ( скин выше тому доказательства ). Так что осталось написать обработчик, и дело в шляпе. Обработчик, который я сейчас выложу необходимо вклеить в файл mfiles.php между определением переменной scan и обработчиком добавления файла

//УДАЛЕНИЕ ФАЙЛА
if(isset($_POST['delF']))$delF = $_POST['delF'];//определяем запущен ли процесс удаление файлов
if(isset($delF))//если да
{
$allDEL = count($delF);//узнаем сколько файлов необходимо удалить
$nowDEL = 0;//считалка удаленных файлов
for($i=0;$nowDEL < $allDEL;$i++)
{
if(isset($delF[$i]))//если наткнулись на существующий элемент массива
{
unlink($delF[$i]);//удаляем файл который содержится в массиве
$nowDEL++;//подтверждаем что удалили еще один файл
}
}
header("location: index.php?page=mfiles");//Пере направление
exit;//на главную страницу менеджера
}
//УДАЛЕНИЕ ФАЙЛА

Все за комментировано, стало быть предельно ясно

 

Заключение

 

Сегодня, я потратил около 6 часов на написание этого поста. При этом сам код я писал около 30 минут, и это при том что я понятие не имел как считывать файлы из директории. Не смотря на такой, как мне кажется, длинный пост мы сегодня реализовали менеджер файлов для нашего движка. С чем я Вас и поздравляю!

Если не считать некоторых "дырок" у движка, им уже можно пользоваться в полной мере. В скором времени мы эти явные "дырочки" прикроем, и напишем защиту от спама для некоторых форм, после чего этим скриптом можно будет пользоваться в всемирной паутине, что меня не может не радовать, ибо это первый мой проект, с очень (ИМХО) чистым кодом

Если Вам понравился мой блог, то подпишитесь на него через ридер, или же по почте.

Если есть какие вопросы/отзывы/комментарии, то пользуйтесь формой ниже

У этого поста есть продолжение.

Всего Вам наилучшего! У меня все!

Исходник

Возможно Вам будут интересны следующие заметки