Источник: http://www.webscript.ru/
ПРЕДИСЛОВИЕ
В общем-то скриптов фотогалерей, как платных так и бесплатных в сети Интернет довольно достаточно, но всегда все хочется сделать самому, поэтому попробуем определить как нам правильно этос делать, причем что бы это было красиво и легко управлялось. Так как такое понятие как Админ-интерфейс, часто отсутствует, а чаще создано на каком-то минимальном уровне, то особое внимание уделим именно ему. Идею создания подобного скрипта навеяла статья опубликованая на webcsript.ru, как практическое примение модулей для работы с графикой.
ПОСТАНОВКА ЗАДАЧИ:
Какой должна быть собственно фотогалерея? Она должна выводить маленькие иконки фотографий в таблице и постранично, должны быть подписи к фоторгафиям, а сами иконки (а может и подписи тоже) должны быть ссылками на большие фотографии - это внешняя сторона. А что должно быть во внутренней:
Теперь самое интересное, что для этого нужно:
собственно сервер, на котором мы будем все это обкатывать, с установленным Perl и MySQL (для тех кто не хочет работать с файловыми БД, я лично отношусь к их числу);
к Perl должны быть установленны модули: CGI (для передачи переменных окружениея), DBI и DBD::mysql (для работы с MySQL), Image::Magick (для работы с графикой).
СТРУКТУРА АДМИН ИНТЕРФЕЙСА:
Итак какую структуру данных мы можем обрисовать:
Какие действия будет производить наш админ-интерфейс:
ОПИСАНИЕ АДМИН-ИНТЕРФЕЙСА:
Для начала создадим таблице в базе MySQL их всего две:
Скрипт создания таблиц:
#!/usr/bin/perl
use DBI;
$name_base_mysql = "mybase"; # база данных
MySQL
$host_base_mysql = "localhost"; # host
MySQL
$port_base_mysql = "3306";
# порт MySQL
$user_base_mysql = "user"; # пользователь
MySQL
$pass_base_mysql = "qwerty";
# пароль пользователя MySQL
$dbh = "DBI:mysql:$name_base_mysql:$host_base_mysql:
$port_base_mysql";
$dbh
= DBI->connect($dbh, $user_base_mysql, $pass_base_mysql);
$dbh
-> do("CREATE TABLE IF
NOT EXISTS image_table (
id
MEDIUMINT NOT NULL
AUTO_INCREMENT,
gallery MEDIUMINT
NOT NULL,
name VARCHAR(250) NOT
NULL,
type_image VARCHAR(50) NOT
NULL,
PRIMARY KEY
(id),
INDEX
(gallery))");
$dbh -> do("CREATE TABLE IF NOT EXISTS gallery_table
(
id MEDIUMINT NOT NULL
AUTO_INCREMENT,
name VARCHAR(250)
NOT NULL,
titling VARCHAR(250) NOT
NULL,
template TEXT NOT
NULL,
x_icon VARCHAR(5) NOT
NULL,
y_icon VARCHAR(5) NOT
NULL,
row_list VARCHAR(5) NOT
NULL,
column_list VARCHAR(5) NOT
NULL,
PRIMARY KEY
(id))");
print "Content-type: text/html;
charset=windows-1251\n\n";
print qq "Create table OK!";
exit;
Здесь в принципе ничего сложного нет, только единственное иногда некоторые администраторы не дают привилегии для создания и удаления таблиц, поэтому если не работает, бегом к администратору...
Теперь перейдем непостредственно к нашему скрипту админ-интерфейса. Для этого нам понадобится четыре шаблона:
шаблон загрузки изображения (upload.htm):
<html>
<head>
<meta
http-equiv="Content-Type" content="text/html;
charset=windows-1251">
<title>Загрузка
фoтoграфии</title>
</head>
<body>
<table
width="98%" border="0" align="center" cellpadding="4"
cellspacing="1">
<tr>
<td
bgcolor="#B0B0B0"
colspan="2">
<font
color="#f5f5f5"><b>Загрузка фотографии</b></font>
</td>
</tr>
<form
name="form1" method="post" action="%script_url%"
enctype="multipart/form-data">
<tr>
<td
width="200" valign="top">Название фотографии:</td>
<td
align="left">
<input
class="input" name="fdb0" type="text" size="40" maxlength="250"
value="">
</td>
</tr>
<tr>
<td
width="200" valign="top">Галерея фотографии:</td>
<td
align="left">
<select
name="fdb1">
<!-- 1
--> <option value="%id_category%" %selected%>
%name_category%</option>
<!--
1_insert -->
</select>
</td>
</tr>
<tr>
<td
width="200" valign="top">Путь к файлу:</td>
<td
align="left">
<input
class="input" name="image" type="file"
size="250">
</td>
</tr>
<tr>
<td
bgcolor="#F5F5F5" width="200"
valign="top"></td>
<td
bgcolor="#F5F5F5" height="30"
align="left">
<input
type="hidden" name="mod" size="40" maxlength="256" value="%mod%">
<input type="hidden" name="edit" size="40"
maxlength="256" value="%edit%">
<input
type="hidden" name="doing" size="40"
maxlength="256" value="afform">
<input
class="input" type="submit" name="Submit"
value="Загрузить">
<input
class="input" type="reset"
value="Очистить">
</td>
</tr>
</form>
</table>
</body>
</html>
шаблон редактирования (он же удаления) изображения (edit.htm):
<html>
<head>
<meta
http-equiv="Content-Type" content="text/html;
charset=windows-1251">
<title>Форма
редактирования (удаления) изображения</title>
</head>
<body>
<table
width="98%" border="0" align="center" cellpadding="4"
cellspacing="1">
<tr>
<td
bgcolor="#B0B0B0"
colspan="2">
<font
color="#f5f5f5"><b>%doing% изображения</b></font>
</td>
</tr>
<form
name="form1" method="post" action="%script_url%"
enctype="text/html">
<tr>
<td
width="200" valign="top">Название изображения:</td>
<td
align="left">
<input
class="input" name="fdb0" type="text" size="40" maxlength="250"
value="%name%">
</td>
</tr>
<tr>
<td
width="200" valign="top">Галерея изображения:</td>
<td
align="left">
<select
name="fdb1">
<!-- 1
--> <option value="%id_category%"
%selected%> %name_category%</option>
<!--
1_insert -->
</select>
</td>
</tr>
<tr>
<td
width="200"
valign="top"></td>
<td
align="left">
<a
href="%link_image%" target="_blank"><img src="%link_icon%" border="0"
align="middle" vspace="2"
hspace="2"></a>
</td>
</tr>
<tr>
<td
bgcolor="#F5F5F5" width="200"
valign="top"></td>
<td
bgcolor="#F5F5F5" height="30"
align="left">
<input
type="hidden" name="mod" size="40" maxlength="256" value="%mod%">
<input
type="hidden" name="edit" size="40" maxlength="256" value="%edit%">
<input
type="hidden" name="id" size="40" maxlength="256" value="%id%">
<input
type="hidden" name="doing" size="40"
maxlength="256" value="afform">
<input
class="input" type="submit" name="Submit" value="%doing%">
<input
class="input" type="reset"
value="Очистить">
</td>
</tr>
</form>
</table>
</body>
</html>
шаблон редактирования (он же создания и удаления) галереи (gallery.htm):
<html>
<head>
<meta
http-equiv="Content-Type" content="text/html;
charset=windows-1251">
<title>Форма добавления,
редактирования и удаления фотогалереи</title>
</head>
<body>
<table
width="98%" border="0" align="center" cellpadding="4"
cellspacing="1">
<tr>
<td
bgcolor="#B0B0B0"
colspan="2">
<font
color="#f5f5f5"><b>%doing% галереи</b></font>
</td>
</tr>
<form
name="form1" method="post" action="%script_url%"
enctype="text/html">
<tr>
<td
width="200" valign="top">Название галереи:</td>
<td
align="left">
<input
class="input" name="fdb0" type="text" size="40" maxlength="250"
value="%name%">
</td>
</tr>
<tr>
<td
width="200" valign="top">Описание галереи:</td>
<td
align="left">
<input
class="input" name="fdb1" type="text" size="40" maxlength="250"
value="%titling%">
</td>
</tr>
<tr>
<td
width="200" valign="top">Количество строк:</td>
<td
align="left">
<input
class="input" name="fdb2" type="text" size="5" maxlength="5" value="%row%">
</td>
</tr>
<tr>
<td
width="200" valign="top">Количество колонок:</td>
<td
align="left">
<input
class="input" name="fdb3" type="text" size="5" maxlength="5" value="%column%">
</td>
</tr>
<tr>
<td
width="200" valign="top">Высота иконки:</td>
<td
align="left">
<input
class="input" name="fdb4" type="text" size="5" maxlength="5" value="%y_icon%">
(px)
</td>
</tr>
<tr>
<td
width="200" valign="top">Ширина иконки:</td>
<td
align="left">
<input
class="input" name="fdb5" type="text" size="5" maxlength="5" value="%x_icon%">
(px)
</td>
</tr>
<tr>
<td
width="200" valign="top">Шаблон вывода галереи:</td>
<td
align="left">
<table
width="100%" border="0" cellpadding="0" cellspacing="0"
summary="">
<tr>
<td>
<textarea
name="fdb6"
cols="70" rows="20">%html%</textarea>
</td>
</tr>
</table>
</td>
</tr>
<tr>
<td
bgcolor="#F5F5F5" width="200"
valign="top"></td>
<td
bgcolor="#F5F5F5" height="30"
align="left">
<input
type="hidden" name="mod" size="40" maxlength="256" value="%mod%">
<input
type="hidden" name="edit" size="40" maxlength="256" value="%edit%">
<input
type="hidden" name="id" size="40" maxlength="256" value="%id%">
<input
type="hidden" name="doing" size="40"
maxlength="256" value="afform">
<input
class="input" type="submit" name="Submit" value="%doing%">
<input
class="input" type="reset"
value="Очистить">
</td>
</tr>
</form>
</table>
</body>
</html>
шаблон вывода списка фотографий (show.htm):
<html>
<head>
<meta
http-equiv="Content-Type" content="text/html;
charset=windows-1251">
<title>Список изображений</title>
</head>
<body>
<table
width="98%" border="0" align="center" cellpadding="4"
cellspacing="1">
<tr>
<td
bgcolor="#B0B0B0"
colspan="2">
<font
color="#f5f5f5"><b>Список
фотогалерей</b></font>
</td>
</tr>
<tr>
<td
width="50"></td>
<td
align="left">
<table
width="60%" border="0" align="left" cellpadding="0" cellspacing="0"
summary="">
<tr>
<form
action="%script_url%"
method="get">
<td>
<input
type="hidden" name="mod" value="category"
enctype="text/html">
<input
type="hidden" name="edit" value="new">
<input
type="submit" value="Новая
фотогалерея">
</td>
</form>
<form
action="%script_url%"
method="get">
<td>
<input
type="hidden" name="mod" value="image"
enctype="text/html">
<input
type="hidden" name="edit" value="upload">
<input
type="hidden" name="cat" value="%edit%">
<input
type="submit" value="Загрузить
изображение">
</td>
</form>
</tr>
</table>
</td>
</tr>
<tr>
<td
bgcolor="#B0B0B0"
colspan="2">
<font
color="#f5f5f5"><b>Список
фотографий</b></font>
</td>
</tr>
<tr>
<td
align="left"
colspan="2">
<table
width="100%" border="0" cellspacing="0"
cellpadding="0">
<tr>
<td>
<!-- 1 --><table
width="100%" border="0" cellspacing="0"
cellpadding="0">
<!-- 1
--> <form
action="%script_url%" method="get">
<!-- 1
--> <tr
bgcolor="#B0C4DE">
<!-- 1
--> <td
width="300" valign="middle">
<!--
1 --> <b>
[ %name_category% </b>
<!-- 1 --> <a
href="%script_url%?edit=%id%">Раскрыть</a>
<!-- 1
--> </td>
<!-- 1
--> <td width="230"
valign="middle">
<!-- 1
--> <input
name="mod"
type="hidden" value="category">
<!-- 1
--> <input
name="edit"
type="hidden" value="edit">
<!-- 1 --> <input
name="id"
type="hidden" value="%id%">
<!-- 1 --> <input
class="input" name="" type="submit"
value="Редактировать">
<!-- 1
--> </td>
<!-- 1 --> </form>
<!-- 1 --> <form
action="%script_url%" method="get">
<!-- 1
--> <td
valign="middle">
<!-- 1
--> <input
name="mod"
type="hidden" value="category">
<!-- 1
--> <input
name="edit"
type="hidden" value="delete">
<!-- 1
--> <input
name="id"
type="hidden" value="%id%">
<!-- 1 --> <input
class="input" name="" type="submit"
value="Удалить">
<!-- 1
--> </td>
<!-- 1 --> </tr>
<!-- 1 --> </form>
<!-- 1 --></table>
<!-- 2
--><table width="100%" border="0"
cellspacing="0" cellpadding="0">
<!-- 2 --> <form
action="%script_url%" method="get">
<!-- 2
--> <tr>
<!-- 2 --> <td
width="300"> [ %name_image% ]
</td>
<!-- 2
--> <td
width="120">
<!-- 2
--> <input
name="mod"
type="hidden" value="image">
<!-- 2
--> <input
name="edit"
type="hidden" value="edit">
<!-- 2 --> <input
name="id"
type="hidden" value="%id%">
<!-- 2 --> <input
class="input" name="" type="submit"
value="Редактировать">
<!-- 2
--> </td>
<!-- 2 --> </form>
<!-- 2 --> <form
action="%script_url%" method="get">
<!-- 2
--> <td
align="left" width="70">
<!-- 2
--> <input
name="mod"
type="hidden" value="image">
<!-- 2
--> <input
name="edit"
type="hidden" value="delete">
<!-- 2
--> <input
name="id"
type="hidden" value="%id%">
<!-- 2 --> <input
class="input" name="" type="submit"
value="Удалить">
<!-- 2
--> </td>
<!-- 2 --> <td
align="center">
<!-- 2
--> <a
href="%link_image%" target="_blank">
<!-- 2 --> <img
src="%link_icon%" border="0" align="middle" vspace="2"
hspace="2"></a>
<!-- 2
--> </td>
<!-- 2 --> </tr>
<!-- 2 --> </form>
<!-- 2 --> <tr><td
colspan="4"><hr size="1"
color="#F5F5F5"></td></tr>
<!-- 2 --></table>
<!--
1_insert -->
</td>
</tr>
</table>
</body>
</html>
Теперь обсудим какие
что же у нас жа шаблоны получились. Первые три обычные формы без
особых сложностей, единственно параметр формы загрузки
изображения enctype="multipart/form-data" так
как мы должны передать не текст, а файл. Так же в первых двух
шаблонах есть динамические внедрения (<!-- 1
--> и <!-- 1_insert -->), так
как мы должны будем первоначально формировать список наших галерей
для последующего их выбора. Вот с четвертым шаблоном нужно
повозится. Во-первых мы должны сформировать и выдать список
фотогалерей (<!-- 1 --> - одна строка
списка), во-вторых сформировать и выдать список фотографий выбранной
фотогалереи (<!-- 2 --> - одна строка
списка).
Переменные и параметры
которые мы бодем обрабатывать скриптом я, для удобства, выделил
темно-желтым цветом. Выделим их в список и определим, что мы с ними
предполагаем делать:
Теперь можно заняться непосредственно скриптом. Начало стандартное:
#!/usr/bin/perl
use CGI;
use
DBI;
use Image::Magick;
use strict;
Так же я рекомендовал ввести еще дополнительные параметры работы скрипта:
use CGI::Carp qw
(fatalsToBrowser); # что бы ошибки скрипта
выпадали в браузер
$CGI::POST_MAX = 262144; # что бы не было желания закачивать картинки в особо
крупных размерах :-)
Устанавливаем начальные переменные:
use vars '$path_image', '$name_base_mysql', '$host_base_mysql', '$port_base_mysql', '$user_base_mysql', '$pass_base_mysql',
'$mod', '$edit', '$id', '$doing', '$cat', '$image', '@fdb', '@temp', '$dbh', '$sth', '$sql', '$tmp', '$image_url';
$path_image = "/home/site/mysite/html/gallery/"; # путь где будут располагаться
фотографии
$script_url = "http://www.mysite.ru/cgi-bin/gallery/gallery.pl";
# url где располагается наш
скрипт
$image_url = "http://www.mysite.ru/gallery/"; # url где располагаются наши
фотографии
$name_base_mysql = "mybase"; # база данных
MySQL
$host_base_mysql = "localhost"; # host
MySQL
$port_base_mysql = "3306";
# порт MySQL
$user_base_mysql = "user"; # пользователь
MySQL*
$pass_base_mysql = "qwerty"; # пароль пользователя
MySQL
*Привилегии для пользователя MySQL можно установить только SELECT, INSERT, UPDATE, DELETE
Забираем "переменные окружения":
my ($query);
$query = new
CGI;
$mod = $query -> param('mod');
$edit = $query -> param('edit');
$id = $query -> param('id');
$doing = $query -> param('doing');
$cat = $query -> param('cat');
$image = $query -> param('image');
$fdb[0] = $query -> param('fdb0');
$fdb[1] = $query -> param('fdb1');
$fdb[2] = $query -> param('fdb2');
$fdb[3] = $query -> param('fdb3');
$fdb[4] = $query -> param('fdb4');
$fdb[5] = $query -> param('fdb5');
$fdb[6] = $query -> param('fdb6');
Перенаправляем на процедуру в соответствии с переданными переменными $mod и $edit:
if ($mod eq 'category')
{
if ($edit eq 'new')
{&mod_category_new}
if ($edit eq 'edit')
{&mod_category_edit}
if ($edit eq 'delete') {&mod_category_delete}
}
if ($mod eq 'image') {
if ($edit eq 'upload')
{&mod_image_upload}
if ($edit eq 'edit')
{&mod_image_edit}
if
($edit eq 'delete')
{&mod_image_delete}
}
&mod_list_gallery;
exit;
В итоге получается, что скрипт вызывает определенную процедуру в соответствии с двумя переданными параметрами $mod и $edit - объект и производимые действия над объектом. Если же нас не удовлетворяет хоть один из параметров, то выходим в процедуру просмотра фотогалерей.
Продолжение следует