Фотогалерея для NetCat с пакетной загрузкой файлов удобная фотогалерея с пакетной загрузкой фотографий, автоматическим генерированием превью

Компонент позволяет пакетно (т.е. много за раз) загружать фотографии в объект на основе Uploadify. Файлы загружаются по адресу \netcat_files\№_раздела\№_компонента\№_объекта\. Далее файлы обрабатываются модифицированным скриптом bolGallery. Автоматически создаются превьюшки заданного размера и html-листинг превью в слоях (div) с настройкой через css. Наконец, с помощью Fancybox листинги превью преобразуются в полноценные фотогалереи, доступные как в полном отображении объекта, так и в списке объектов.

Версия NetCat: любая старше 4.1
Статус: стабильный
Скачать: Attach:NetCat-Photogallery_2011-01-28.zip
Источники: www.uploadify.com, www.fancybox.net, http://bolgallery.free.fr/

Внимание: рецепт не безопасен! В используемом в нем стороннем uploadify.php есть дырка, через которую злоумышленник может проникнуть на ваш сайт! Если вы собираетесь установить этот скрипт, спросите в комментариях, и мы попробуем вспомнить, как решить эту проблему. Или закажите платное внедрение.

Использование:

Подключение компонента

В компоненте есть три настройки, которые будут применяться ко всем объектам по-умолчанию:

Эти же настройки могут быть заданы индивидуально для каждого объекта.

Число фотографий в строке:
По-умолчанию, фотографии помещаются в div-ах, смещающихся налево с обтеканием (float:left). Таким образом, фотографии блочно заполняют все доступное пространство для контента. Если вы хотите сделать более традиционное табличное представление (например, в три столбца), задайте соответствующее "Число фотографий в строке".

Размер превьюшек:
Размер создаваемых превью регулируется параметром "размер превьюшек". Он применяется для бОльшей стороны фотографии. Т.е. для панорамных фотографий он становится шириной, а высота рассчитывается пропорционально; а для портретных - наоборот. В любом случае, превьюшка заворачивается в div, который еще на 8 пикселей больше, чем размер самой превьюшки.

Число фотографий при выводе в списке объектов:
Внутри объекта выводятся все фотографии, а в списке объектов, вероятно, нужно будет выводить только несколько первых фотографий.

Добавление объекта

Так как адрес расположения фотографий привязан к номеру объекта, в момент добавления самого объекта нет возможности загрузить фотографии - у не добавленного объекта еще нет номера. Однако уже можно настроить отображение фотогалереи для этого объекта:

Если оставить нулевые настройки, они возьмутся из общих настроек компонента.

Добавление фотографий

Итак, объект добавлен, а возможность загрузить фотографии появится при первом изменении объекта:

фотогалерея для Netcat: настройки

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

В диалоге загрузки можно выбрать много файлов сразу. Ура!

Генерирование превью, настойка внешнего вида

Чтобы сгенерировать превью, просто зайдите в раздел с фотогалереей на сайте:

фотогалерея для Netcat: листинг объектов

Собственно, можно специально и не генерировать превьюшки - это произойдет при первом визите посетителя сайта автоматически. На скриншоте показан листинг объектов. Каждая строка с фотографиями относится к одному объекту. Внешний вид окружения фотографий настраивается в файле bolGallery\bolGalleryPhPh.css Строка со ссылками на разработчиков убирается в файле bolGallery.php :)

Фотографии открываются через Fancybox вот так:

фотогалерея для Netcat: Fancybox в действии

при этом предусмотрен сквозной листинг между фотографиями с группировкой "по объектам".

Заметки

  • баг: нельзя загружать файлы, в имени которых присутствует ', кириллицу и пробелы не пробовал;
  • временно "закомментить" какую-либо фотографию можно переименовав ее: первым символом поставить "#";
  • после каждого изменения объекта директория с "превьюшками" удаляется, и создается заново при первом открытии объекта;
  • архитектурное ограничение: если вы исправите настройки размера превьюшек во всем компоненте с уже существующими объектами, то... придется удалить все превьюшки вручную, чтобы изменения вступили в силу. Или просто зайти в режим редактирования каждого объекта и, ничего не меняя, сохраниться.
  • качество превью по-умолчанию 70%, задается в функции resizeImage в bolGallery.php

Установка:

  1. скачайте архив;
  2. залейте на сервер в корень установки NetCat директорию /uploadify из архива. Альтернативно вы можете скачать текущую версию Uploadify с официального сайта www.uploadify.com и залить ее;
  3. залейте на сервер в корень установки NetCat директорию /bolGallery из архива. bolGallery.php с официального сайта не подойдет;
  4. в макет дизайна пропишите путь к CSS: <link type='text/css' rel='stylesheet' href='/bolGallery/bolGalleryPhPh.css' />
  5. подключите Fancybox
  6. импортируйте компонент (или, рекомендуется, соберите его из этой статьи);
  7. в компоненте не будет ничего, кроме, собственно фотогалереи. Навигация по объектам будет производиться по их порядковому номеру в Базе Данных. Допиливайте далее на свой вкус :)

Полезные куски кода (раскладка компонента):

Поля компонента: ColumsNumber ThumbWidth PicsLimitCount, целые числа.

Объект в списке

";
    global $NETCAT_FOLDER;
    global $f_RowNum;
    $pageString = 0;
    $path2dir = $NETCAT_FOLDER."
netcat_files/$f_Subdivision_ID/$f_Sub_Class_ID/$f_RowID/";
    if ($admin_mode != true && ((glob("
$path2dir*.jpg") || glob("$path2dir*.JPG") || glob("$path2dir*.jpeg") || glob("$path2dir*.JPEG") || glob("$path2dir*.png")) || glob("$path2dir*.PNG") || glob("$path2dir*.gif") || glob("$path2dir*.GIF") != false) && ($f_PicsLimitCount||$cc_settings[PicsLimitCount]) && ($f_PicsLimitCount!="-1")) {
        global $pageString;

        include_once($NETCAT_FOLDER."
/bolGallery/bolGallery.php");
        bolGallery("
$NETCAT_FOLDER/netcat_files/$f_Subdivision_ID/$f_Sub_Class_ID/$f_RowID/", opt_case($f_ColumsNumber,$f_ColumsNumber,$cc_settings[ColumsNumber]), opt_case($f_ThumbWidth,$f_ThumbWidth,$cc_settings[ThumbWidth]), opt_case($f_ThumbWidth,$f_ThumbWidth,$cc_settings[ThumbWidth]), opt_case($f_PicsLimitCount,$f_PicsLimitCount,$cc_settings[PicsLimitCount]));
        }

$result.= "

$f_AdminButtons
<a href='$fullLink'><h3>$f_RowID</h3></a>
<!-- phph-photogallery -->
".opt($pageString,$pageString)."
<!-- /phph-photogallery -->

Отображение объекта

<h3>$f_RowID</h3>
";
    $path2dir = $NETCAT_FOLDER."
netcat_files/$f_Subdivision_ID/$f_Sub_Class_ID/$message/";
    if ($admin_mode != true && ((glob("
$path2dir*.jpg") || glob("$path2dir*.JPG") || glob("$path2dir*.jpeg") || glob("$path2dir*.JPEG") || glob("$path2dir*.png")) || glob("$path2dir*.PNG") || glob("$path2dir*.gif") || glob("$path2dir*.GIF") != false) ) {
        global $pageString;

        include_once($NETCAT_FOLDER."
/bolGallery/bolGallery.php");
        bolGallery("
$NETCAT_FOLDER/netcat_files/$f_Subdivision_ID/$f_Sub_Class_ID/$message/", opt_case($f_ColumsNumber,$f_ColumsNumber,$cc_settings[ColumsNumber]), opt_case($f_ThumbWidth,$f_ThumbWidth,$cc_settings[ThumbWidth]), opt_case($f_ThumbWidth,$f_ThumbWidth,$cc_settings[ThumbWidth]), 0);
        }

echo "

<!-- phph-photogallery -->
$pageString
<!-- /phph-photogallery -->

Настройки отображения компонента раздела

$settings_array = array(
    'title4' => array('type' => 'divider', 'caption' => 'Настройки фотогалереи (общие, подставляются по-умолчанию в объекты)'),
    'ColumsNumber' => array('type' => 'string',
        'default_value' => 999,
        'caption' => 'Число фотографий в строке',
        'size' => 5,
        'validate_regexp' => '/^\d+$/',
        'validate_error' => 'Введите целое число'
    ),
    'ThumbWidth' => array('type' => 'string',
        'default_value' => 150,
        'caption' => 'Размер превьюшек',
        'size' => 5,
        'validate_regexp' => '/^\d+$/',
        'validate_error' => 'Введите целое число'
    ),
    'PicsLimitCount' => array('type' => 'string',
        'default_value' => 999,
        'caption' => 'Число фотографий при выводе в списке объектов',
        'size' => 5,
        'validate_regexp' => '/^\d+$/',
        'validate_error' => 'Введите целое число'
    )
);

Альтернативная форма добавления объекта

Необязательная форма, в момент добавления объекта записывает в его поля значения из настроек компонента.

<!-- скрытые поля настройки фотогалереи, берутся из настроек компонента-->
<input name='f_ThumbWidth' maxlength='12' size='12' value='$cc_settings[ThumbWidth]' type='hidden'><br>
<input name='f_ColumsNumber' maxlength='12' size='12' value='$cc_settings[ColumsNumber]' type='hidden'><br>
<!-- /скрытые поля настройки фотогалереи, берутся из настроек компонента-->

Альтернативная форма изменения объекта

<!-- все это вставляем сразу ПОСЛЕ дива nc_moderate_form -->
<!-- определяем, существует ли целевая директория, и если нет, создаем ее-->
";
$path = $NETCAT_FOLDER."netcat_files/$current_sub[Subdivision_ID]/$current_cc[Sub_Class_ID]/$message";

if(!is_dir("$NETCAT_FOLDER/netcat_files/$current_sub[Subdivision_ID]")) {
        echo "<span style='color:blue;'>СИСТЕМА: не существует директории для файлов раздела. Бывает, сейчас сделаем...</span><br>";
            if (!mkdir("$NETCAT_FOLDER/netcat_files/$current_sub[Subdivision_ID]", 0755, true)) {
                echo "<span style='color:red;'>СИСТЕМА: не удалось создать директорию для файлов раздела. Обратитесь в <a href='http://web.finar.ru/' target='_blank'>Ph and Ph</a> для решения проблемы</span><br>";
                }
            else {
                echo "<span style='color:green;'>СИСТЕМА: ...директория для разделов создана. </span><br>";
                }
    }
if(is_dir("$NETCAT_FOLDER/netcat_files/$current_sub[Subdivision_ID]")) {
        echo "<span style='color:green;'>";
        echo "СИСТЕМА: директория <b>netcat_files/$current_sub[Subdivision_ID]</b> существует. Хорошо!<br> ";
        echo "</span>";
        if(is_dir($path)) {
                echo "<span style='color:green;'>СИСТЕМА: директория <b>netcat_files/$current_sub[Subdivision_ID]/$current_cc[Sub_Class_ID]/$message</b> существует. Все хорошо :)</span>";
            }
            else {
                echo "<span style='color:blue;'>СИСТЕМА: директория <b>netcat_files/$current_sub[Subdivision_ID]/$current_cc[Sub_Class_ID]/$message</b> не существует. Сейчас создадим ее...<br></span> ";
                if (!mkdir($path, 0755, true)) {
                        echo "<span style='color:red;'>СИСТЕМА: не удалось создать директорию для объекта</span>";
                        }
                    else {
                        echo "<span style='color:green;'>СИСТЕМА: ...директория создана. Все хорошо :)</span>";
                        }
                }
    }



echo "
<!-- /определяем, существует ли целевая директория, и если нет, создаем ее-->

<!-- скрипт для кнопки-->
    <script type='text/javascript'><!--
        function toggleObj(obj, tog, show, hide, swap, set, cname, button) {
            var e = document.getElementById(obj);
            if (hide && swap!='') var e2 = document.getElementById(swap);
            var text    = document.getElementById(obj + \"-tog\");
            if (set=='1') document.cookie=cname+'='+tog+'; path=/';
            if (tog=='show') {
                e.style.display = 'block';
                if(swap!='') e2.style.display = 'none';
                var label = hide;
                tog='hide';            
            }
            else {
                e.style.display = 'none';
                if(swap!='') e2.style.display = 'block';
                var label = show;
                tog='show';
            }
        var act = '\"javascript:toggleObj(\''+obj+'\',\''+tog+'\',\''+show+'\',\''+hide+'\',\''+swap+'\',\''+set+'\',\''+cname+'\',\''+button+'\');\"';
        if (button==1)
            copy = '<input type=\"button\" class=\"inputbutton togglebutton\" value=\"'+label+'\" onclick='+act+' />';
        else
            var copy = '<a class=\"togglelink\" href='+act+'>'+label+'</a>';
        text.innerHTML = copy;  
     }
  --></script>
<!-- /скрипт для кнопки-->

<!-- кнопка, показывающая настройки-->
<br><h3>
<span id='box1-tog'>
    <a class='togglelink' href=\"javascript:toggleObj('box1','show','Настройки фотогалереи','скрыть настройки','','','','')\">Настройки фотогалереи</a>
</span></h3>
<!-- /кнопка, показывающая настройки-->

<div style='display:none; border: 2px grey solid; background: #EEEEEE; width:400px; text-align:center; padding:5px; margin-top:10px;' id='box1'>
    <!-- uploadify -->
    <b>Пакетная загрузка фотографий.</b> <br>Выберите фотки и затем нажмите кнопку ''ЗАГРУЗИТЬ''<br><br>
    <link href='/uploadify/uploadify.css' type='text/css' rel='stylesheet' />
    <script type='text/javascript' src='/uploadify/jquery-1.4.2.min.js'></script>
    <script type='text/javascript' src='/uploadify/swfobject.js'></script>
    <script type='text/javascript' src='/uploadify/jquery.uploadify.v2.1.4.min.js'></script>
    <script type='text/javascript'>
        $(document).ready(function() {
            $('#file_upload').uploadify({
                'uploader'  : '/uploadify/uploadify.swf',
                'script'    : '/uploadify/uploadify.php',
                'cancelImg' : '/uploadify/cancel.png',
                'folder'    : '/netcat_files/$current_sub[Subdivision_ID]/$current_cc[Sub_Class_ID]/$message',
                'auto'      : false,
                'multi'     : true
            });
        });
    </script>


    <input id='file_upload' name='file_upload' type='file' /><br>
    <p><a href=\"javascript:$('#file_upload').uploadifyUpload()\">ЗАГРУЗИТЬ</a></p><hr>
    <!-- /uploadify -->

    <!-- поля с настройками вывода для данного объекта-->
    <p style='font-size:8 pt;text-align:left;'>
    Поддерживаемые расширения файлов: <b>jpg</b>, <b>jpeg</b>, <b>gif</b>, <b>png</b> <br>
    <b>Настройки фотогалереи для данного объекта (при нулевых значениях, берутся из общих настроек компонента):</b><br><br>
        ".nc_int_field("ColumsNumber", "maxlength='12' size='12'", $classID, 1)."<br>
        ".nc_int_field("ThumbWidth", "maxlength='12' size='12'", $classID, 1)."<br>
        ".nc_int_field("PicsLimitCount", "maxlength='12' size='12'", $classID, 1)."<br>    
    </p>
    <!-- поля с настройками вывода для данного объекта-->

    <!-- ссылка на директорию в файловом менеджере -->
        <p style='font-size:8 pt; text-align:center;'><a href='/netcat/modules/filemanager/admin.php?page=manager&dir=netcat_files/$current_sub[Subdivision_ID]/$current_cc[Sub_Class_ID]/$message'>управление фотографиями</a> (переход в файл-менеджер)</p>
    <!-- /ссылка на директорию в файловом менеджере -->
</div>
<br>
<!-- далее пустить конец дефолтной формы изменения -->
 

Действие после изменения объекта

";
$dir = $NETCAT_FOLDER."
netcat_files/$current_sub[Subdivision_ID]/$current_cc[Sub_Class_ID]/$message/bolGallery/";

function rrmdir($dir) {
   if (is_dir($dir)) {
     $objects = scandir($dir);
     foreach ($objects as $object) {
       if ($object != "
." && $object != "..") {
         if (filetype($dir."
/".$object) == "dir") rrmdir($dir."/".$object); else unlink($dir."/".$object);
       }
     }
     reset($objects);
     rmdir($dir);
   }
 }
rrmdir($dir);

if($inside_admin) {
    ob_end_clean();
    header("
Location: ".$goBackLink."&inside_admin=1");
    exit;
}
else {
    echo NETCAT_MODERATION_MSG_OBJCHANGED;
    echo "
<br><br>".$goBack;
}
echo "

Действие после удаления объекта

";
$dir = $NETCAT_FOLDER."
netcat_files/$current_sub[Subdivision_ID]/$current_cc[Sub_Class_ID]/$message/";

function rrmdir($dir) {
   if (is_dir($dir)) {
     $objects = scandir($dir);
     foreach ($objects as $object) {
       if ($object != "
." && $object != "..") {
         if (filetype($dir."
/".$object) == "dir") rrmdir($dir."/".$object); else unlink($dir."/".$object);
       }
     }
     reset($objects);
     rmdir($dir);
   }
 }
rrmdir($dir);


if($inside_admin) {
    ob_end_clean();
    header("
Location: ".$goBackLink."&inside_admin=1");
    exit;
}
else {
    if ( is_array($message) ){
        echo NETCAT_MODERATION_MSG_OBJDELETED;
    } else {
        echo NETCAT_MODERATION_MSG_OBJSDELETED;
    }
    echo "
<br><br>".$goBack;
}
echo "

Change-log

Июль 2011:

  • исправлены пару багов с путями в bolGallery.php
  • ... и в инструкции
  • реакция на отсутствие директории для файлов раздела: теперь она создается автоматически
  • разработан функционал добавления текстовых описаний для title, alt и подписи в окне Fancybox. Теперь все это можно добавлять к фотогалерее на уровне файлов, т.е. просто подгрузив текстовый файл с описанием рядом с картинкой (с тем же именем, но расширением .diz)

Обновленный bolGallery.php пока еще не выложен. Если нужно - запросите в комментария, попробуем помочь.

Алексей — 2011-09-30, 17:33

Отлично! Всё получилось. Благодарю.
Единственое что хотелось бы выводить какой-либо заголовок у альбома вместо номера идентификатора. Добавление текстовых описаний для title, alt и подписи - было бы шикарно.

Рады, что помогли! В качестве заголовка проще всего выводить название галереи. Версию с выводом title и alt'ов обязательно выложим, немного позже.

Finar.

Александр — 2011-10-28, 08:45

Для версии 4.6 не могу установить.
Пишет что компонент разработан для версии 3.5
Я в самом файле изменил цифири на 4.6 и в результате: Warning: Cannot use a scalar value as an array in /usr/home/novour.com/data/www/city.novour.com/netcat/system/nc_ezsqlcore.class.php on line 102
ну и: Ошибка создания компонента, данные компонента не добавлены.
Компонент не может быть установлен.

Надо собрать компонент вручную в 4.6 по инструкциям, затем экспортировать его и прислать нам :)

Finar.

Александр — 2012-01-30, 20:22

Здравствуйте. Спасибо большое за фотогалерею.
Единственный вопрос, как проверить есть ли загруженные фото у объекта (чтоб не выводить слайдер к примеру)?

Например также, как это сделано в объекте в списке: (glob("$path2dir*.jpg") || glob("$path2dir*.JPG") ...

Finar

Сергей — 2012-05-15, 09:47

Как сделать сортировку по имени файла ?

Возможно, поможет такой код:

//сортировка по возрастанию
sort($imagesList);
//$imagesList = array($imagesList[0], $imagesList[1], $imagesList[2]);
$imagesList = array_slice($imagesList, 0, 3); // daria 8.02.2012, solving problem with empty elements
                }
                else if ($switchClassic == 0){
                    while ($file=readdir($handle)) {

                        if (is_file($referenceImagesDirectory.$file)) {

                            // Check if the file is an image
                            $extension = strtolower(substr(strrchr($file,  "." ), 1));
                            $supportedExtensions = array("jpg", "jpeg", "gif", "png");

                            if (in_array($extension, $supportedExtensions) and ($file[0] != "#")) { // Also checks whether file is marked by a "#"

                                // Add this file to the image files array
                                $imagesList[] = $referenceImagesDirectory.$file; // Should not add $referenceImagesDirectory in the array, could be added later

                            }
                        }
                    }
//сортировка по возрастанию
natcasesort($imagesList);
                }
                else {
                exit("ERROR: pics limit counter must be natural");
                }
                closedir($handle);

Finar

Сергей — 2012-05-17, 13:50

Большое спасибо! Все работает!

Игорь — 2013-03-16, 12:44

Для версии 5.0 нет компанента?

Нет, пока нету.

Finar.

Блог

Tilda Module: интеграция NetCat с Tilda.cc

Представляем нашу новую разработку, модуль интеграции CMS NetCat с платформой Tilda.cc. Модуль дает возможностью полуавтоматически размещать классные лендинги прямо в структуре вашего сайта!

далее

Как оптимально заархивировать файлы, чтобы распаковать их средствами ISPmanager?

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

далее

Как расшифровать бэкапы, зашифрованные ISPmanager?

В ISPmanager версии 5.52.0 и старше, реализована новая система резервного копирования, построенная на основе некоей ISPtar. И работает она... своеобразно. Попробуем разобраться, как именно.

далее

Типовой сайт по раскрытию информации по Приказу ФСФР 22.06.2005 № 05-23/пз-н

Представляемый программный комплекс предназначен для российских УК ПИФ (управляющих компаний паевого инвестиционного фонда). В соответствии с требованиями законодательства, такие УК обязаны иметь сайт по раскрытию информации, на котором будет регулярно публиковаться определенный набор документов, касающихся их деятельности. И не только публиковаться, но и своевременно отправляться в Архив, а кроме всего прочего должно вестись журналирование всех этих действий. Иначе -- плохо, иначе -- нарушение действующего законодательства, наказания, штрафы, отзыв лицензии и так далее.

далее

Весь блог тут