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

 

Добрый вечер дорогой читатель Блога RS! В ночь с 20 на 21 января 2012 года, мне не спалось. Поэтому я сел подготавливать материал для следующего поста. Подумав немного я решил улучшить наш менеджер файлов. Что же мы добавим сегодня в наш новый модуль? Мне показался печальным тот факт, что список файлов не имеет постраничную навигацию. Ведь придет время и файлов на сервере будет тысячи, что намного понизит производительность нашего модуля. Именно поэтому сегодня мы научим наш список выводить по 40 файлов на каждой страничке.

 

 

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

Я еще добавил пару мелочей, такие как кнопочка с помощью которой можно выделить все файлы сразу, и из пред просмотра изображений сделал ссылки на полное изображение.

Код Вам буду выкладывать методом: Выложил, указал на исправления в коде. Приступим...

 

Определяем переменную отвечающую за номер страницы

 

Нам необходима переменная, которая будет олицетворять номер страницы. По умолчанию эта переменная будет равна единицы, то есть первая страница. При изменение этой переменной, будет меняться ключ у массива, то есть отчет ключа будет уже не с нуля, а с сорока.

//СТРАНИЦА В СПИСКЕ
if(isset($_GET['list']))$list = $_GET['list']; else $list = 1;//определяем страницу списка
if(isset($list))
{
if(!preg_match("/^[0-9]+$/",$list) OR $list < 1)//так как переменная list должна быть числом, то..
{
header("location: index.php?page=mfiles");//..пере направление
exit;//на страницу менеджера если это не так ($list не есть число)
}
}
//СТРАНИЦА В СПИСКЕ

Добавляем этот кусочек кода в самый верх нашего нового модуля mfiles.php

 

Проводим переменную по всем функциям

 

Что я имею введу под словом "проводим". Эта переменная будет участвовать в расчетах, так как все расчеты у нас идут в функциях, то эту переменную нам необходимо объявить в этих функциях.

редактируем функцию вывода формы

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

В самой функции вывода формы есть вызов функции списка, переделаем этот вызов

$result_sm = listFILE($typeSCAN,$sm_read,$list);//запускаем функцию вывода списка

Теперь переделаем саму функцию вывода списка

function listFILE($typeSCAN,$sm_read,$list)//Функция вывода списка
{
...
}

На по следок заходим в index.php и правим вызов функции формы там

$txt = formfiles($linkFORfile,$scan,$list);

 

Постраничная навигация

 

Вот ее код

    //Навигация (расчет количества страниц)
$full = count($files);//Сколько всего файлов
$obj = 40;//по сколько выводить
$links = (($full - 1) / $obj) + 1;//рассчитывается количество страниц
$links = intval($links);//округление
$linkSTART = $list * $obj - $obj;//рассчитывается начальная позиция ( на первой странице начальная позиция равна нулю )
$linkEND = $linkSTART + $obj;//рассчитывается конечная позиция ( по умолчанию 40 )
//Навигация (расчет количества страниц)

Что тут у нас присутствует.

  • Первая строчка узнает сколько у нас всего элементов в массиве
  • Во второй определяется сколько элементов должно находится на каждой странице
  • Следующие две строчки рассчитывают количество страниц
  • Предпоследняя строчка находит первый ключ у массива. По умолчанию первый ключ у нас равен нулю
  • Последняя строчка узнает конечный ключ в массиве, по умолчанию там будет число 40

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

 

Новые код-слова в шаблоне

 

Нам необходимо добавить новый код в наш шаблон, а именно необходимо создать еще одну колонку, где будет выводиться дата нашего файла, и кнопочки с навигацией. Так же я добавил кнопку "Выделить все файлы". Функцию на javascript, для этой кнопки, мы напишем чуть позднее

<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="500px" cellpadding="0" cellspacing="0" border="0" align="center">
[_file]
<tr>
<td width="40px" height="50px"><a href="[_img]" target="_blank"><img src="[_img]" border="0px" width="40px" height="40px"></a></td>
<td align="center">[_link]</td>
<td align="center">[_date]</td>
<td align="center"><input id="checkbox_[_del]" type="checkbox" name="delF[[_del]]" value="[_delNAME]" /></td>
</tr>
[_file]
</table>
<br/>
<table cellpadding="5" cellspacing="0" border="0" align="center">
<tr>
<td align="right" width="150px"><div id="divSELall" style="cursor:pointer;" onclick="selectCHBOX();">Выделить все файлы</div></td>
<td align="center"><input name="submit" type="submit" value="Удалить выбранные"></td>
</tr>
</table>

</form>
<br/><br/><div>[_list]</div>
</div>
<br/><br/>
  • Я добавил id для чек боксов. Этот id нам понадобится для нахождение этих элементов с помощью JS.
  • Новое код-слово [_date]. Будет меняться на дату нашего файла
  • И новое код-слово [_list]. Будет содержать в себе ссылки на другие страницы списка.

 

Новая функция вывода списка

 

Я выложу полный код функции, и поясню все новое что в ней появилось

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

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

if(isset($files))rsort($files);//сортируем список по дате

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

//Навигация (расчет количества страниц)
$full = count($files);//Сколько всего файлов
$obj = 40;//по сколько выводить
$links = (($full - 1) / $obj) + 1;//рассчитывается количество страниц
$links = intval($links);//округление
$linkSTART = $list * $obj - $obj;//рассчитывается начальная позиция ( на первой странице начальная позиция равна нулю )
$linkEND = $linkSTART + $obj;//рассчитывается конечная позиция ( по умолчанию 40 )
//Навигация (расчет количества страниц)

for($i=$linkSTART;$i<$full AND $i<$linkEND;$i++)//генерируем строчки для таблицы
{
$copy_tp = $copy_sm[1];//делаем копию вырезанной части шаблона
//Определяем директорию из которой админу нужно вывести файлы
if($typeSCAN == 1)$img = $dir."/".$files[$i][1];//формируем пред просмотр ( пред просмотром в списке изображений являются сами изображения )
if($typeSCAN == 2)$img = "img/arh.jpg";//формируем пред просмотр ( пред просмотром в списке архивов является иконка архива )

//замена код слов
$copy_tp = str_replace("[_link]",$files[$i][1],$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][1],$copy_tp);//путь к удаляемому файлу
$copy_tp = str_replace("[_date]",date ("d.m.Y H:i:s",$files[$i][0]),$copy_tp);//переделанная дата вид день.месяц.год часы:мин:сек
//замена код слов

$result_sm[0] .= $copy_tp;//Сохраняем с генерированную строчку таблицы в общую переменную
}
$result_sm[1] = $links;//заносим кол-во страниц (постраничная навигация)

return $result_sm;//Выводим результат работы функции в виде массива
}
  • Появилась новая переменная, $mass. Она позволяет считать ключ массива от нуля до n.
  • Переменная $files теперь массив содержащий в себе еще один массив. Таким образом в главном массиве теперь содержится и время создание и имя файла. Кстати время создание определяется функцией filemtime(путь к файлу). Функция возвращает возраст файла в секундах. Вот описанный мною кусочек кода.
    while (false !== ($one = readdir($data))) //собираем массив из результата сканирования
{
if($one != '.' && $one != '..') //Удаляем точки
{
$files[$mass][0] = filemtime($dir."/".$one);//узнаем дату создания файла
$files[$mass][1] = $one;//формируем массив с именами файлов
$mass++;//увеличиваем первый ключ массива
}
}
  • Далее я ввел сортировку массива. Сортируется массив с помощью функции rsort(). Она позволяет сортировать по первому элементу в массиве, коем является дата создания. Теперь только что загруженный файл будет находится в верху списка. Перед этой функцией стоит условие на существование переменной $files. Если список пустой, то функция без этого условия выдает ошибку. Вот описанный мной кусочек
if(isset($files))rsort($files);//сортируем список по дате
  • Далее идет расчет навигации, о ней мы говорили выше.
  • Небольшим изменением подверглась строка условия цикла for. В переменную i помещается число которое было высчитано нашей навигацией. Так же в условии теперь стоит порог на прокрутку цикла. Максимум сколько раз будет работать цикл, это 40! Вот описанный мной кусочек
    for($i=$linkSTART;$i<$full AND $i<$linkEND;$i++)//генерируем строчки для таблицы
{
...
}
  • Следующее нововедение, это замена код слова [_date] да дату. Дата представляет собой такой вид: день.месяц.год часы:мин:сек

Добивается такой вид с помощью встроенной функции date() она автоматически из секунд, которые мы получили с помощью функции filemtime(путь к файлу), создает нам, указанный выше, вид. Очень удобно

        $copy_tp = str_replace("[_date]",date ("d.m.Y H:i:s",$files[$i][0]),$copy_tp);//переделанная дата вид день.месяц.год часы:мин:сек
  • Затем идет еще одно очень важное исправление. Переменная $result_sm в этой функции теперь является массивом. В первом элементе массива будет храниться весь с генерированный html код. Во втором же элементе содержится количество страниц. Если файлов меньше чем 40, то этот элемент массива будет содержать число один, то есть одна страница.
...
$result_sm[0] .= $copy_tp;//Сохраняем с генерированную строчку таблицы в общую переменную
}
$result_sm[1] = $links;//заносим кол-во страниц (постраничная навигация)

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

 

Новая функция вывода формы

 

Объясню нововведение так же как и выше. Вот полный код функции

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

if($typeSCAN != 0)//Определяем открыл ли админ какой-нить список
{
$result_sm = listFILE($typeSCAN,$sm_read,$list);//запускаем функцию вывода списка

//Если результат функции пустота..
if($result_sm[0] == "")$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[0],$sm_read);//заменяем часть таблицы в шаблоне на с генерированный результат работы выше

//Вывод постраничной навигации
if($result_sm[1] > 1)//Если страниц больше одной
{
for($i=1;$i<=$result_sm[1];$i++)//крутим цикл пока страницы не закончатся
{
if($i == $list)$colLINK = "#000";else $colLINK = "#aaa";//выбираем цвет для выбранной страницы и для остальных
$linksLIST .= "<a style='color:$colLINK' href='index.php?page=mfiles&scan=$typeSCAN&list=$i'>[$i]</a>";//формируем ссылку в одну переменную
}
$sm_read = str_replace("[_list]",$linksLIST,$sm_read);//Меняем код слово на постраничную навигацию
}
else $sm_read = str_replace("[_list]","",$sm_read);//Меняем код слово постраничной навигации на пустоту
//Вывод постраничной навигации

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

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

Здесь из нововведений пажалуй лишь две вещи. Это исправлена переменная $result_sm на $result_sm[0]

    //Если результат функции пустота..
if($result_sm[0] == "")$sm_read = str_replace("[_style]","none",$sm_read);//..то прячем всю таблицу с глаз долой
//Если же не результат функции НЕ пустота
else $sm_read = str_replace("[_style]","block",$sm_read);//..то показываем таблицу админу

и добавлен скрипт позволяющий вывести постраничную навигацию на экран

//Вывод постраничной навигации
if($result_sm[1] > 1)//Если страниц больше одной
{
for($i=1;$i<=$result_sm[1];$i++)//крутим цикл пока страницы не закончатся
{
if($i == $list)$colLINK = "#000";else $colLINK = "#aaa";//выбираем цвет для выбранной страницы и для остальных
$linksLIST .= "<a style='color:$colLINK' href='index.php?page=mfiles&scan=$typeSCAN&list=$i'>[$i]</a>";//формируем ссылку в одну переменную
}
$sm_read = str_replace("[_list]",$linksLIST,$sm_read);//Меняем код слово на постраничную навигацию
}
else $sm_read = str_replace("[_list]","",$sm_read);//Меняем код слово постраничной навигации на пустоту
//Вывод постраничной навигации

Давайте поясню этот код.

  • Первое что нам необходимо, это узнать, сколько страниц. Если страница одна, то нам незачем выводить на экран кнопки и поэтому код-слово просто заменяется на пустоту. Число страниц в эту функцию пришло из функции формирования списка. ($links)
  • Далее запускается цикл for. Цикл будет выполняться до тех пор, пока количества страниц не закончится.
  • В цикле мы делаем две вещи. Формируем ссылку, и меняем стиль для ссылки. Кнопочка будет иметь черный цвет, при условие что мы находимся на этой страницы. Все остальные кнопки будут серого цвета.

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

Прежде чем мы перейдем к написанию JS функции, давайте сделаем небольшой исправление в обработчике удаления. Мне не нравится, что при удаление файлов, нас перекидывает на главную страницу менеджера. То есть по сути закрывается список, чего не особо то хочется. Поэтому я предлагаю перенаправлять админа на страницу с которой он пришел. Как это сделать. Очень просто, нам необходимо переделать ссылку в функции header обработчика удаления. Вот как это выглядит

//УДАЛЕНИЕ ФАЙЛА
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: ".getenv('HTTP_REFERER'));//Пере направление
exit;//на главную страницу
}
//УДАЛЕНИЕ ФАЙЛА

Функция getenv с переменной окружения HTTP_REFERER возвращает нам ссылку откуда мы пришли. То есть после того как как обработчик сделает свою работу, админа перенесет на страницу откуда он пришел. Очень удобно

 

Функция javascript

 

На по следок напишем функцию javascript которая позволит одним кликом выбрать все файлы. Открываем наш файл js.js и вставляем туда вот такую функцию

function selectCHBOX()
{
for(var i=0;document.getElementById("checkbox_"+i);i++)
{
if(document.getElementById("checkbox_"+i).checked == false) document.getElementById("checkbox_"+i).checked = true;
else document.getElementById("checkbox_"+i).checked = false;
}
if(document.getElementById("divSELall").innerHTML == "Выделить все файлы") document.getElementById("divSELall").innerHTML = "Снять выделение"
else document.getElementById("divSELall").innerHTML = "Выделить все файлы"
}

Работа функции очень проста. Найти все элементы чек бокс и если они не отмечены, то отметить их. Так же при нажатие на кнопку второй раз, со всех элементов снимется выделение. Последние три строчки отвечают за замену текста на кнопке с "Выделить все файлы" на "Снять выделение" и обратно. Все нужные параметры ( атрибут id ) уже есть в шаблоне. Так же в шаблоне присутствует вызов этой функции JS

 

Заключение

 

Сегодня я объяснял работу немного в другом стиле. Надеюсь что Вы все усвоили Если есть какие вопросы, то пишите комментарии, отвечу с удовольствием ( если, конечно, в моих силах ответить на Ваш вопрос )

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

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

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

Исходник
 

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

Комментарии (3)

Ваше имя *
Сайт
Ваш E-mail *
Ваше сообщение *
 
Вы не подтвердили условия политики конфиденциальности.
CoopeR, 11 Июня 2013 г. 08:52 пишет:
Читатель
Добрый день, Во-первых БОЛЬШОЕ спасибо за интересные статьи!))) дошел уже до данной статьи, хотелось спросить - если файлы называются на русском языке то менеджер файлов выводит крякообразы, как подправить? заранее спасибо!)
CoopeR, 11 Июня 2013 г. 08:56 пишет:
Читатель
PS: я знаю что по многие будут спрашивать зачем загружать фото с названием на русском языке, но я спрашиваю так для информации(хочу немного разнообразить свой менеджер добавив функцию скачки, перемещения и хотелось бы ещё переименовывать и тд)
Ответ для пользователя: CoopeR
Алексей, 12 Июня 2013 г. 09:30 пишет:
Автор
Дальше есть статья
http://rio-shaman.ru/razrabotka-cms/uluchshenija/translit/
В ней я расписывал функцию транслита для ЧПУ. Данную функцию можно использовать для преобразование имен файлов
Ответ для пользователя: CoopeR