Index: extensions/BatchDownloader/admin.php
===================================================================
--- extensions/BatchDownloader/admin.php	(revision 16379)
+++ extensions/BatchDownloader/admin.php	(revision 16379)
@@ -0,0 +1,27 @@
+<?php
+if (!defined('BATCH_DOWNLOAD_PATH')) die('Hacking attempt!');
+
+global $template, $page, $conf;
+
+// tabsheet
+include_once(PHPWG_ROOT_PATH.'admin/include/tabsheet.class.php');
+$page['tab'] = (isset($_GET['tab'])) ? $_GET['tab'] : 'sets';
+  
+$tabsheet = new tabsheet();
+$tabsheet->add('sets', l10n('Download history'), BATCH_DOWNLOAD_ADMIN . '-sets');
+$tabsheet->add('config', l10n('Configuration'), BATCH_DOWNLOAD_ADMIN . '-config');
+$tabsheet->select($page['tab']);
+$tabsheet->assign();
+
+// include page
+include(BATCH_DOWNLOAD_PATH . 'admin/' . $page['tab'] . '.php');
+
+// template
+$template->assign(array(
+  'BATCH_DOWNLOAD_PATH'=> BATCH_DOWNLOAD_PATH,
+  'BATCH_DOWNLOAD_ADMIN' => BATCH_DOWNLOAD_ADMIN,
+  ));
+  
+$template->assign_var_from_handle('ADMIN_CONTENT', 'batch_download');
+
+?>
Index: extensions/BatchDownloader/admin/config.php
===================================================================
--- extensions/BatchDownloader/admin/config.php	(revision 16379)
+++ extensions/BatchDownloader/admin/config.php	(revision 16379)
@@ -0,0 +1,53 @@
+<?php
+if (!defined('BATCH_DOWNLOAD_PATH')) die('Hacking attempt!');
+
+if (isset($_POST['save_config']))
+{
+  $conf['batch_download'] = array(
+    'groups'          => isset($_POST['groups']) ? $_POST['groups'] : array(),
+    'level'           => $_POST['level'],
+    'photo_size'      => $_POST['photo_size'],
+    'archive_prefix'  => trim($_POST['archive_prefix']),
+    'archive_comment' => trim($_POST['archive_comment']),
+    'archive_timeout' => intval($_POST['archive_timeout']),
+    'max_elements'    => intval($_POST['max_elements']),
+    'max_size'        => intval($_POST['max_size']),
+    'last_clean'      => $conf['batch_download']['last_clean'],
+    );
+  
+  conf_update_param('batch_download', serialize($conf['batch_download']));
+}
+
+// groups
+$query = '
+SELECT id, name
+  FROM '.GROUPS_TABLE.'
+  ORDER BY name ASC
+;';
+$group_options = simple_hash_from_query($query, 'id', 'name');
+
+// levels
+$level_options = get_privacy_level_options();
+
+// sizes
+$enabled = ImageStdParams::get_defined_type_map();
+$disabled = @unserialize(@$conf['disabled_derivatives']);
+if ($disabled === false) $disabled = array();
+
+$sizes_keys = array_diff(array_keys($enabled), array_keys($disabled));
+$sizes_names = array_map(create_function('$s', 'return l10n($s);'), $sizes_keys);
+
+$sizes_options = array_combine($sizes_keys, $sizes_names);
+$sizes_options['original'] = l10n('Original');
+
+$template->assign(array(
+  'group_options' => $group_options,
+  'level_options' => $level_options,
+  'sizes_options' => $sizes_options,
+  'batch_download' => $conf['batch_download'],
+  ));
+
+
+$template->set_filename('batch_download', dirname(__FILE__) . '/template/config.tpl');
+
+?>
Index: extensions/BatchDownloader/admin/index.php
===================================================================
--- extensions/BatchDownloader/admin/index.php	(revision 16379)
+++ extensions/BatchDownloader/admin/index.php	(revision 16379)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based photo gallery                                    |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2012 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: extensions/BatchDownloader/admin/sets.php
===================================================================
--- extensions/BatchDownloader/admin/sets.php	(revision 16379)
+++ extensions/BatchDownloader/admin/sets.php	(revision 16379)
@@ -0,0 +1,7 @@
+<?php
+if (!defined('BATCH_DOWNLOAD_PATH')) die('Hacking attempt!');
+
+
+$template->set_filename('batch_download', dirname(__FILE__) . '/template/sets.tpl');
+
+?>
Index: extensions/BatchDownloader/admin/template/config.tpl
===================================================================
--- extensions/BatchDownloader/admin/template/config.tpl	(revision 16379)
+++ extensions/BatchDownloader/admin/template/config.tpl	(revision 16379)
@@ -0,0 +1,87 @@
+{combine_css path=$BATCH_DOWNLOAD_PATH|@cat:"admin/template/style.css"}
+
+{combine_script id='jquery.chosen' load='footer' path='themes/default/js/plugins/chosen.jquery.min.js'}
+{combine_css path="themes/default/js/plugins/chosen.css"}
+
+{footer_script}{literal}
+jQuery(document).ready(function() {
+  jQuery(".chzn-select").chosen();
+});
+{/literal}{/footer_script}
+
+<div class="titrePage">
+	<h2>Advanced Downloader</h2>
+</div>
+
+<form method="post" action="" class="properties">
+<fieldset>
+  <legend>{'Download access'|@translate}</legend>
+  
+  <ul>
+    <li>
+      <label>
+        <span class="property">{'User groups'|@translate}</span>
+        <select name="groups[]" data-placeholder="{'Everybody'|@translate}" class="chzn-select" multiple="multiple" style="width:370px;">
+          {html_options options=$group_options selected=$batch_download.groups}
+        </select>
+      </label>
+    </li>
+    <li>
+      <label>
+        <span class="property">{'Privacy level'|@translate}</span>
+        <select name="level">
+          {html_options options=$level_options selected=$batch_download.level}
+        </select>
+      </label>
+    </li>
+  </ul>
+</fieldset>
+
+<fieldset>
+  <legend>{'Archives configuration'|@translate}</legend>
+  
+  <ul>
+    <li>
+      <label>
+        <span class="property">{'Maximum photo size'|@translate}</span>
+        <select name="photo_size">
+          {html_options options=$sizes_options selected=$batch_download.photo_size}
+        </select>
+        NOT IMPLEMENTED
+      </label>
+    </li>
+    <li>
+      <label>
+        <span class="property">{'Archive prefix'|@translate}</span>
+        <input type="text" name="archive_prefix" value="{$batch_download.archive_prefix}">
+      </label>
+    </li>
+    <li>
+      <label>
+        <span class="property">{'Archive comment'|@translate}</span>
+        <input type="text" name="archive_comment" value="{$batch_download.archive_comment}" size="80">
+      </label>
+    </li>
+    <li>
+      <label>
+        <span class="property">{'Delete unterminated downloads after'|@translate}</span>
+        <input type="text" name="archive_timeout" value="{$batch_download.archive_timeout}" size="3">{'hours'|@translate}
+      </label>
+    </li>
+    <li>
+      <label>
+        <span class="property">{'Maximum number if photos in each set'|@translate}</span>
+        <input type="text" name="max_elements" value="{$batch_download.max_elements}" size="3">
+      </label>
+    </li>
+    <li>
+      <label>
+        <span class="property">{'Maximum size of each archive'|@translate}</span>
+        <input type="text" name="max_size" value="{$batch_download.max_size}" size="4">MB
+      </label>
+    </li>
+  </ul>
+</fieldset>
+
+<p><input type="submit" name="save_config" value="{'Save Settings'|@translate}"></p>  
+</form>
Index: extensions/BatchDownloader/admin/template/index.php
===================================================================
--- extensions/BatchDownloader/admin/template/index.php	(revision 16379)
+++ extensions/BatchDownloader/admin/template/index.php	(revision 16379)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based photo gallery                                    |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2012 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: extensions/BatchDownloader/admin/template/sets.tpl
===================================================================
--- extensions/BatchDownloader/admin/template/sets.tpl	(revision 16379)
+++ extensions/BatchDownloader/admin/template/sets.tpl	(revision 16379)
@@ -0,0 +1,12 @@
+{combine_css path=$BATCH_DOWNLOAD_PATH|@cat:"admin/template/style.css"}
+
+<div class="titrePage">
+	<h2>Advanced Downloader</h2>
+</div>
+
+<form method="post" action="" class="properties">
+<fieldset>
+  <legend>{'TODO'|@translate}</legend>
+  
+</fieldset>
+</form>
Index: extensions/BatchDownloader/admin/template/style.css
===================================================================
--- extensions/BatchDownloader/admin/template/style.css	(revision 16379)
+++ extensions/BatchDownloader/admin/template/style.css	(revision 16379)
@@ -0,0 +1,3 @@
+.chzn-choices li {
+  clear:none !important;
+}
Index: extensions/BatchDownloader/download.php
===================================================================
--- extensions/BatchDownloader/download.php	(revision 16379)
+++ extensions/BatchDownloader/download.php	(revision 16379)
@@ -0,0 +1,23 @@
+<?php
+define('PHPWG_ROOT_PATH', '../../');
+include(PHPWG_ROOT_PATH.'include/common.inc.php');
+
+// check_status(ACCESS_CLASSIC);
+
+$BatchDownloader = new BatchDownloader($_GET['set_id']);
+$file = $BatchDownloader->getArchivePath();
+
+header('Content-Type: application/force-download; name="'.basename($file).'"');
+header('Content-Disposition: attachment; filename="'.basename($file).'"');
+header('Content-Description: File Transfer');
+header('Content-Transfer-Encoding: binary');
+header('Content-Length: '.filesize($file).'');
+
+header('Cache-Control: no-cache, must-revalidate');
+header('Pragma: no-cache');
+header('Expires: 0');
+
+readfile($file);
+exit(0);
+
+?>
Index: extensions/BatchDownloader/include/BatchDownloader.class.php
===================================================================
--- extensions/BatchDownloader/include/BatchDownloader.class.php	(revision 16379)
+++ extensions/BatchDownloader/include/BatchDownloader.class.php	(revision 16379)
@@ -0,0 +1,588 @@
+<?php
+defined('BATCH_DOWNLOAD_PATH') or die('Hacking attempt!');
+
+class BatchDownloader
+{
+  private $conf;
+  private $data;
+  private $images;
+  
+  /**
+   * __construct
+   * @param: mixed set id (##|'new')
+   * @param: array images
+   * @param: string set type ('album'|'tag'|'selection')
+   * @param: int set type id (for retrieving album infos for instance)
+   */
+  function __construct($set_id, $images=array(), $type=null, $type_id=null)
+  {
+    global $user, $conf;
+    
+    $this->conf = $conf['batch_download'];
+    $this->data = array(
+      'user_id' => $user['id'],
+      'set_id' => 0,
+      'type' => null,
+      'type_id' => null,
+      'nb_zip' => 0,
+      'last_zip' => 0,
+      'nb_images' => 0,
+      'status' => 'new',
+      );
+    $this->images = array();
+    
+    // load specific set
+    if (preg_match('#^[0-9]+$#', $set_id))
+    {
+      $query = '
+SELECT
+    type,
+    type_id,
+    nb_zip,
+    last_zip,
+    nb_images,
+    status
+  FROM '.BATCH_DOWNLOAD_TSETS.'
+  WHERE
+    user_id = '.$this->data['user_id'].'
+    AND id = '.$set_id.'
+;';
+      $result = pwg_query($query);
+      
+      if (pwg_db_num_rows($result))
+      {
+        $this->data['set_id'] = $set_id;
+        list(
+          $this->data['type'], 
+          $this->data['type_id'], 
+          $this->data['nb_zip'], 
+          $this->data['last_zip'], 
+          $this->data['nb_images'], 
+          $this->data['status']
+          ) = pwg_db_fetch_row($result);
+        
+        // make sur all pictures of the set exists
+        $query = '
+DELETE FROM '.BATCH_DOWNLOAD_TIMAGES.'
+  WHERE image_id NOT IN (
+    SELECT id FROM '.IMAGES_TABLE.'
+    )
+;';
+        pwg_query($query);
+      
+        $query = '
+SELECT
+    image_id,
+    zip
+  FROM '.BATCH_DOWNLOAD_TIMAGES.'
+  WHERE set_id = '.$this->data['set_id'].'
+;';
+        $this->images = simple_hash_from_query($query, 'image_id', 'zip');
+        
+        if (count($this->images) != $this->data['nb_images'])
+        {
+          $this->updateParam('nb_images', count($this->images));
+        }
+      }
+      else
+      {
+        trigger_error('BatchDownloader::__construct, invalid set id', E_USER_ERROR);
+      }
+    }
+    // create a new set
+    else if ($set_id == 'new')
+    {
+      $this->data['type'] = $type;
+      $this->data['type_id'] = $type_id;
+      
+      $query = '
+INSERT INTO '.BATCH_DOWNLOAD_TSETS.'(
+    user_id,
+    date_creation,
+    type,
+    type_id,
+    nb_zip,
+    last_zip,
+    nb_images,
+    status
+  ) 
+  VALUES(
+    '.$this->data['user_id'].',
+    NOW(),
+    "'.$this->data['type'].'",
+    "'.$this->data['type_id'].'",
+    0,
+    0,
+    0,
+    "new"
+  )
+;';
+      pwg_query($query);
+      $this->data['set_id'] = pwg_db_insert_id();
+      
+      if (!empty($images))
+      {
+        $this->addImages($images);
+      }
+    }
+    else
+    {
+      trigger_error('BatchDownloader::__construct, invalid input parameter', E_USER_ERROR);
+    }
+  }
+  
+  /**
+   * updateParam
+   * @param: string param name
+   * @param: mixed param value
+   */
+  function updateParam($name, $value)
+  {
+    $this->data[$name] = $value;
+    pwg_query('UPDATE '.BATCH_DOWNLOAD_TSETS.' SET '.$name.' = "'.$value.'" WHERE id = '.$this->data['set_id'].';');
+  }
+  
+  /**
+   * getParam
+   * @param: string param name
+   * @return: mixed param value
+   */
+  function getParam($name)
+  {
+    return $this->data[$name];
+  }
+  
+  /**
+   * getImages
+   * @return: array
+   */
+  function getImages()
+  {
+    return $this->images;
+  }
+  
+  /**
+   * isInSet
+   * @param: int image id
+   * @return: bool
+   */
+  function isInSet($image_id)
+  {
+    return array_key_exists($image_id, $this->images);
+  }
+  
+  /**
+   * removeImages
+   * @param: array image ids
+   */
+  function removeImages($image_ids)
+  {
+    if (empty($image_ids) or !is_array($image_ids)) return;
+    
+    foreach ($image_ids as $image_id)
+    {
+      unset($this->images[ $image_id ]);
+    }
+    
+    $query = '
+DELETE FROM '.BATCH_DOWNLOAD_TIMAGES.'
+  WHERE 
+    set_id = '.$this->data['set_id'].'
+    AND image_id IN('.implode(',', $image_ids).')
+;';
+    pwg_query($query);
+    
+    $this->updateParam('nb_images', count($this->images));
+  }
+  
+  /**
+   * addImages
+   * @param: array image ids
+   */
+  function addImages($image_ids)
+  {
+    if (empty($image_ids) or !is_array($image_ids)) return;
+    
+    $image_ids = array_unique($image_ids);
+    $inserts = array();
+    
+    foreach ($image_ids as $image_id)
+    {
+      if ($this->isInSet($image_id)) continue;
+      
+      $this->images[ $image_id ] = 0;
+      array_push($inserts, array('set_id'=>$this->data['set_id'], 'image_id'=>$image_id, 'zip'=>0));
+    }
+    
+    mass_inserts(
+      BATCH_DOWNLOAD_TIMAGES,
+      array('set_id', 'image_id', 'zip'),
+      $inserts
+      );
+      
+    $this->updateParam('nb_images', count($this->images));
+  }
+  
+  /**
+   * clear
+   */
+  function clear($reset=true)
+  {
+    $this->images = array();
+    
+    $query = '
+DELETE FROM '.BATCH_DOWNLOAD_TIMAGES.'
+  WHERE set_id = '.$this->data['set_id'].'
+;';
+    pwg_query($query);
+    
+    if ($reset)
+    {
+      $this->updateParam('nb_zip', 0);
+      $this->updateParam('last_zip', 0);
+      $this->updateParam('nb_images', 0);
+    }
+  }
+  
+  /**
+   * deleteLastArchive
+   */
+  function deleteLastArchive()
+  {
+    $zip_path = $this->getArchivePath();
+    if (file_exists($zip_path))
+    {
+      unlink($zip_path);
+    }
+  }
+  
+  /**
+   * createNextArchive
+   */
+  function createNextArchive()
+  {
+    // set already downloaded
+    if ( $this->data['status'] == 'done' or $this->data['nb_images'] == 0 )
+    {
+      trigger_error('BatchDownloader::createNextArchive, the set is empty', E_USER_ERROR);
+    }
+    
+    // first zip
+    if ($this->data['last_zip'] == 0)
+    {
+      $this->updateParam('status', 'download');
+      
+      // limit number of elements
+      if ($this->data['nb_images'] > $this->conf['max_elements'])
+      {
+        $images_ids = array_slice(array_keys($this->images), 0, $this->conf['max_elements']);
+        $this->clear(false);
+        $this->addImages($images_ids);
+      }
+      
+      $this->getEstimatedArchiveNumber();
+      
+      pwg_query('UPDATE '.BATCH_DOWNLOAD_TSETS.' SET date_creation = NOW() WHERE id = '.$this->data['set_id'].';');
+    }
+    
+    // get next images of the set
+    $images_to_add = array();
+    foreach ($this->images as $image_id => $zip_id)
+    {
+      if ($zip_id != 0) continue; // here are already added images
+      array_push($images_to_add, $image_id);
+    }
+    
+    if (count($images_to_add))
+    {
+      $query = '
+SELECT
+    id,
+    name,
+    file,
+    path,
+    filesize
+  FROM '.IMAGES_TABLE.'
+  WHERE id IN ('.implode(',', $images_to_add).')
+;';
+      $images_to_add = hash_from_query($query, 'id');
+      
+      // open zip
+      $this->updateParam('last_zip', $this->data['last_zip']+1);
+      $zip_path = $this->getArchivePath();
+      
+      $zip = new ZipArchive;
+      if ($zip->open($zip_path, ZipArchive::CREATE) !== true)
+      {
+        trigger_error('BatchDownloader::createNextArchive, unable to open ZIP archive', E_USER_ERROR);
+      }
+      
+      // add images until size limit is reach, or all images are added
+      $images_added = array();
+      $total_size = 0;
+      foreach ($images_to_add as $row)
+      {
+        $zip->addFile(PHPWG_ROOT_PATH . $row['path'], $row['id'].'_'.$row['name'].'.'.get_extension($row['file']));
+        
+        array_push($images_added, $row['id']);
+        $this->images[ $row['id'] ] = $this->data['last_zip'];
+        
+        $total_size+= $row['filesize'];
+        if ($total_size >= $this->conf['max_size']*1024) break;
+      }
+      
+      // archive comment
+      global $conf;
+      $comment = 'Generated on '.date('r').' with PHP ZipArchive '.PHP_VERSION.' by Piwigo Advanced Downloader.';
+      $comment.= "\n".$conf['gallery_title'].' - '.get_absolute_root_url();
+      if (!empty($this->conf['archive_comment']))
+      {
+        $comment.= "\n\n".$this->conf['archive_comment'];
+      }
+      $zip->setArchiveComment($comment);
+      
+      $zip->close();
+      
+      // update database
+      $query = '
+UPDATE '.BATCH_DOWNLOAD_TIMAGES.'
+  SET zip = '.$this->data['last_zip'].'
+  WHERE
+    set_id = '.$this->data['set_id'].'
+    AND image_id IN('.implode(',', $images_added).')
+;';
+      pwg_query($query);
+      
+      // all images added ?
+      if (count($images_to_add) == count($images_added))
+      {
+        $this->updateParam('status', 'done');
+      }
+      
+      // over estimed
+      if ( $this->data['status'] == 'done' and $this->data['last_zip'] < $this->data['nb_zip'] )
+      {
+        $this->updateParam('nb_zip', $this->data['last_zip']);
+      }
+      // under estimed
+      else if ( $this->data['last_zip'] == $this->data['nb_zip'] and $this->data['status'] != 'done' )
+      {
+        $this->updateParam('nb_zip', $this->data['last_zip']+1);
+      }
+      
+      return $zip_path;
+    }
+    else
+    {
+      return false;
+    }
+  }
+  
+  /**
+   * getEstimatedTotalSize
+   * @return: int
+   */
+  function getEstimatedTotalSize()
+  {
+    if ($this->data['nb_images'] == 0) return 0;
+    
+    $image_ids = array_slice(array_keys($this->images), 0, $this->conf['max_elements']);
+    
+    $query = '
+SELECT SUM(filesize) AS total
+  FROM '.IMAGES_TABLE.'
+  WHERE id IN ('.implode(',', $image_ids).')
+;';
+    list($total) = pwg_db_fetch_row(pwg_query($query));
+    return $total;
+  }
+  
+  /**
+   * getEstimatedArchiveNumber
+   * @return: int
+   */
+  function getEstimatedArchiveNumber()
+  {
+    $nb_zip = ceil( $this->getEstimatedTotalSize() / ($this->conf['max_size']*1024) );
+    $this->updateParam('nb_zip', $nb_zip);
+    return $nb_zip;
+  }
+  
+  /**
+   * getDownloadList
+   * @return: string html
+   */
+  function getDownloadList($url='')
+  {
+    $nb_archives = $this->getEstimatedArchiveNumber();
+    
+    $out = '<ul id="download_list">';
+    if ($this->data['status'] == 'done')
+    {
+      $out.= '<li id="zip-1">Already downloaded</li>';
+    }
+    else
+    {
+      for ($i=1; $i<=$this->data['nb_zip']; $i++)
+      {
+        $out.= '<li id="zip-'.$i.'">';
+        
+        if ($i < $this->data['last_zip']+1)
+        {
+          $out.= 'Archive #'.$i.' (already downloaded)';
+        }
+        else if ($i == $this->data['last_zip']+1)
+        {
+            $out.= '<a href="'.add_url_params($url, array('set_id'=>$this->data['set_id'],'zip'=>$i)).'" rel="nofollow"' 
+              .($i!=1 ? 'onClick="return confirm(\'Starting download Archive #'.$i.' will destroy Archive #'.($i-1).', be sure you finish the download. Continue ?\');"' : null).
+              '>Archive #'.$i.' (ready)</a>';
+        }
+        else
+        {
+          $out.= 'Archive #'.$i.' (pending)';
+        }
+        
+        $out.= '</li>';
+      }
+    }
+    $out.= '</ul>';
+    
+    return $out;
+  }
+  
+  /**
+   * getArchivePath
+   * @param: int archive number
+   * @return: string
+   */
+  function getArchivePath($i=null)
+  {
+    if (!file_exists(BATCH_DOWNLOAD_LOCAL . 'u-' .$this->data['user_id']. '/'))
+    {
+      mkdir(BATCH_DOWNLOAD_LOCAL . 'u-' .$this->data['user_id']. '/', 0755, true);
+    }
+    
+    if ($i === null) $i = $this->data['last_zip'];
+    
+    include_once(PHPWG_ROOT_PATH . 'admin/include/functions.php');
+    
+    return BATCH_DOWNLOAD_LOCAL .'u-'. $this->data['user_id'] .'/'.
+          (!empty($this->conf['archive_prefix']) ? $this->conf['archive_prefix'] .'_' : null).
+          get_username($this->data['user_id']) .'_'. 
+          $this->data['type'] .'-'. $this->data['type_id'] .'_'.
+          $this->data['user_id'] . $this->data['set_id'] .'_'.
+          'part'. $i .'.zip';
+  }
+  
+  /**
+   * getSetInfo
+   * @return: array
+   */
+  function getSetInfo()
+  {
+    $set = array(
+      'NB_IMAGES' => $this->data['nb_images'],
+      'NB_ARCHIVES' => $this->data['nb_zip'],
+      'TOTAL_SIZE' => ceil($this->getEstimatedTotalSize()/1024),
+      'LINKS' => $this->getDownloadList(BATCH_DOWNLOAD_PUBLIC . 'init_zip'),
+      );
+        
+    if ($this->data['status'] == 'new')
+    {
+      $set['U_EDIT_SET'] = BATCH_DOWNLOAD_PUBLIC . 'view&amp;set_id='.$this->data['set_id'];
+    }
+    
+    switch ($this->data['type'])
+    {
+      case 'calendar':
+      {
+        $set['NAME'] = l10n('Calendar');
+        $set['COMMENT'] = $this->data['type_id'];
+        break;
+      }
+      
+      case 'category':
+      {
+        $category = get_cat_info($this->data['type_id']);
+        $set['NAME'] = get_cat_display_name($category['upper_names']);
+        $set['sNAME'] = $category['name'];
+        $set['COMMENT'] = trigger_action('render_category_description', $category['comment']);
+        break;
+      }
+      
+      case 'flat':
+      {
+        $set['NAME'] = l10n('Whole gallery');
+        break;
+      }
+      
+      case 'tags':
+      {
+        $tags = find_tags(explode(',', $this->data['type_id']));
+        $set['NAME'] = l10n('Tags');
+        
+        $set['COMMENT'] = ''; $first = true;
+        foreach ($tags as $tag)
+        {
+          if ($first) $first = false;
+          else $set['COMMENT'].= ', ';
+          $set['COMMENT'].=
+            '<a href="' . make_index_url(array('tags'=>array($tag))) . '">'
+            .trigger_event('render_tag_name', $tag['name'])
+            .'</a>';
+        }
+        break;
+      }
+      
+      case 'search':
+      {
+        $set['NAME'] = '<a href="'.make_index_url(array('section'=>'search', 'search'=>$this->data['type_id'])).'">'.l10n('Search').'</a>';
+        break;
+      }
+      
+      case 'favorites':
+      {
+        $set['NAME'] = '<a href="'.make_index_url(array('section'=>'favorites')).'">'.l10n('Your favorites').'</a>';
+        break;
+      }
+      
+      case 'most_visited':
+      {
+        $set['NAME'] = '<a href="'.make_index_url(array('section'=>'most_visited')).'">'.l10n('Most visited').'</a>';
+        break;
+      }
+      
+      case 'best_rated':
+      {
+        $set['NAME'] = '<a href="'.make_index_url(array('section'=>'best_rated')).'">'.l10n('Best rated').'</a>';
+        break;
+      }
+      
+      case 'list':
+      {
+        $set['NAME'] = l10n('Random');
+        break;
+      }
+      
+      case 'recent_pics':
+      {
+        $set['NAME'] = '<a href="'.make_index_url(array('section'=>'recent_pics')).'">'.l10n('Recent photos').'</a>';
+        break;
+      }
+      
+      // case 'selection':
+      // {
+        // $set['NAME'] = '';
+        // $set['COMMENT'] = '';
+        // break;
+      // }
+    }
+    
+    if (!isset($set['sNAME'])) $set['sNAME'] = $set['NAME'];
+    if (!isset($set['COMMENT'])) $set['COMMENT'] = null;
+    
+    return $set;
+  }
+}
+
+?>
Index: extensions/BatchDownloader/include/download.inc.php
===================================================================
--- extensions/BatchDownloader/include/download.inc.php	(revision 16379)
+++ extensions/BatchDownloader/include/download.inc.php	(revision 16379)
@@ -0,0 +1,116 @@
+<?php
+defined('BATCH_DOWNLOAD_PATH') or die('Hacking attempt!');
+
+# this file is called on public page #
+
+global $page, $template, $conf, $user;
+
+switch ($page['sub_section'])
+{
+  /* download page */
+  case 'init_zip':
+  {
+    $template->set_filename('index', dirname(__FILE__) . '/../template/init_zip.tpl');
+    
+    $BatchDownloader = new BatchDownloader($_GET['set_id']);
+    
+    if ($BatchDownloader->getParam('status') != 'done')
+    {
+      if (isset($_GET['zip']))
+      {
+        $BatchDownloader->deleteLastArchive();
+        $next_file = $BatchDownloader->createNextArchive();
+      }
+      else
+      {
+        $BatchDownloader->getEstimatedArchiveNumber();
+      }
+    }
+
+    $set = $BatchDownloader->getSetInfo();
+    
+    if (isset($next_file))
+    {
+      $set['U_DOWNLOAD'] = BATCH_DOWNLOAD_PATH . 'download.php?set_id='.$_GET['set_id'].'&amp;zip='.$_GET['zip'];
+      array_push($page['infos'], sprintf(l10n('Archive #%d is downloading, if the download doesn\'t start automatically please <a href="%s">click here</a>'), $_GET['zip'], $set['U_DOWNLOAD']));
+    }
+    
+    if ($BatchDownloader->getParam('nb_images') > $conf['batch_download']['max_elements'])
+    {
+      array_push($page['errors'], sprintf(
+        l10n('You choose to download %d pictures, but the system is limited to %d. You can edit the set, or the last %d pictures will not be downloaded.'),
+        $BatchDownloader->getParam('nb_images'),
+        $conf['batch_download']['max_elements'],
+        $BatchDownloader->getParam('nb_images') - $conf['batch_download']['max_elements']
+        ));
+    }
+    
+    $template->assign(array(
+      'set' => $set,
+      'archive_timeout' => $conf['batch_download']['archive_timeout'],
+      ));
+    
+    break;
+  }
+  
+  /* edition page */
+  case 'view':
+    $self_url = BATCH_DOWNLOAD_PUBLIC . 'view&amp;set_id='.$_GET['set_id'];
+    
+    $template->set_filename('index', dirname(__FILE__).'/../template/view.tpl');
+    $template->assign(array(
+      'BATCH_DOWNLOAD_PATH' => BATCH_DOWNLOAD_PATH,
+      'U_VIEW' => $self_url,
+      'U_INIT_ZIP' => BATCH_DOWNLOAD_PUBLIC . 'init_zip&amp;set_id='.$_GET['set_id'],
+      ));
+    
+    $BatchDownloader = new BatchDownloader($_GET['set_id']);
+    
+    if ($BatchDownloader->getParam('status') != 'new')
+    {
+      array_push($page['errors'], l10n('You can not edit this set'));
+      break;
+    }
+    
+    if ( isset($_GET['remove']) and preg_match('#^[0-9]+$#', $_GET['remove']) )
+    {
+      $BatchDownloader->removeImages(array($_GET['remove']));
+    }
+    
+    $template->assign('set', $BatchDownloader->getSetInfo());
+    
+    $template->set_prefilter('index_thumbnails', 'batch_download_thumbnails_list_prefilter');
+    
+    $page['start'] = isset($_GET['start']) ? $_GET['start'] : 0;
+    $page['items'] = array_keys($BatchDownloader->getImages());
+    
+    if (count($page['items']) > $page['nb_image_page'])
+    {
+      $page['navigation_bar'] = create_navigation_bar(
+        $self_url,
+        count($page['items']),
+        $page['start'],
+        $page['nb_image_page'],
+        false
+        );
+      $template->assign('navbar', $page['navigation_bar']);
+    }
+    
+    include(PHPWG_ROOT_PATH . 'include/category_default.inc.php');
+    
+    break;    
+}
+
+
+function batch_download_thumbnails_list_prefilter($content, &$smarty)
+{
+  $search = '<span class="thumbName">';
+  
+  $add = '<a href="{$U_VIEW}&amp;remove={$thumbnail.id}">
+<img src="{$BATCH_DOWNLOAD_PATH}template/image_delete.png" title="{\'Remove from download set\'|@translate}">
+</a>&nbsp;';
+
+  return str_replace($search, $search.$add, $content);
+}
+
+?>
Index: extensions/BatchDownloader/include/events.inc.php
===================================================================
--- extensions/BatchDownloader/include/events.inc.php	(revision 16379)
+++ extensions/BatchDownloader/include/events.inc.php	(revision 16379)
@@ -0,0 +1,188 @@
+<?php
+defined('BATCH_DOWNLOAD_PATH') or die('Hacking attempt!');
+
+# this file contains all functions directly called by the triggers #
+
+/* unserialize conf and load language */
+function batch_download_init()
+{
+  global $conf;
+  
+  $conf['batch_download'] = unserialize($conf['batch_download']);
+  load_language('plugin.lang', BATCH_DOWNLOAD_PATH);
+}
+
+
+/* define page section from url */
+function batch_download_section_init()
+{
+  global $tokens, $page, $conf;
+  
+  if ($tokens[0] == 'download')
+  {
+    if (check_download_access() === false) access_denied();
+    
+    $page['section'] = 'download';
+    $page['title'] = l10n('Advanced Downloader').$conf['level_separator'].' ';
+    
+    switch (@$tokens[1])
+    {
+      case 'init_zip':
+        $page['sub_section'] = 'init_zip';
+        $page['title'].= l10n('Generate ZIP');
+        break;
+      case 'view':
+        $page['sub_section'] = 'view';
+        $page['title'].= l10n('Edit set');
+        break;
+      default:
+        redirect('index.php');
+    }
+  }
+}
+
+/* download section */
+function batch_download_page() 
+{
+  global $page;
+
+  if (isset($page['section']) and $page['section'] == 'download')
+  {
+    include(BATCH_DOWNLOAD_PATH . '/include/download.inc.php');
+  }
+}
+
+
+/* add buttons on thumbnails list */
+function batch_download_index_button()
+{
+  global $page, $template, $user;
+  
+  if ( !count($page['items']) or !isset($page['section']) ) return;
+  
+  if (check_download_access() === false) return;
+  
+  // download the set
+  if ( isset($_GET['action']) and $_GET['action']=='advdown_set' )
+  {
+    $set = get_set_info_from_page();
+    
+    if ($set !== false)
+    {
+      $BatchDownloader = new BatchDownloader('new', $page['items'], $set['type'], $set['id']);
+      redirect(BATCH_DOWNLOAD_PUBLIC . 'init_zip&amp;set_id='.$BatchDownloader->getParam('set_id'));
+    }
+  }
+  
+  // toolbar button
+  $button = '<li><a href="'. duplicate_index_url(array(), array('action')) .'&amp;action=advdown_set" title="'.l10n('Download all pictures of this selection').'" class="pwg-state-default pwg-button" rel="nofollow">
+			<span class="pwg-icon" style="background:url(\'' . BATCH_DOWNLOAD_PATH . 'template/zip.png\') center center no-repeat;">&nbsp;</span><span class="pwg-button-text">'.l10n('Advanced Downloader').'</span>
+		</a></li>';
+  $template->concat('PLUGIN_INDEX_ACTIONS', $button);
+}
+
+
+/* menu block */
+function batch_download_add_menublock($menu_ref_arr)
+{
+  global $user;
+  
+  $menu = &$menu_ref_arr[0];
+  if ($menu->get_id() != 'menubar') return;
+  
+  if (check_download_access() === false) return;
+  
+  $query = '
+SELECT id
+  FROM '.BATCH_DOWNLOAD_TSETS.'
+  WHERE
+    user_id = '.$user['id'].'
+    AND status != "done"
+;';
+  $result = pwg_query($query);
+  if (!pwg_db_num_rows($result)) return;
+  
+  $menu->register_block(new RegisteredBlock('mbAdvancedDownloader', l10n('Downloads'), 'AdvancedDownloader'));
+}
+
+function batch_download_applymenu($menu_ref_arr)
+{
+  global $template, $conf, $user;
+  
+  $menu = &$menu_ref_arr[0];
+  $block = $menu->get_block('mbAdvancedDownloader');
+  
+  if ($block != null)
+  {
+    $query = '
+SELECT id 
+  FROM '.BATCH_DOWNLOAD_TSETS.'
+  WHERE
+    user_id = '.$user['id'].'
+    AND status != "done"
+;';
+    $sets = array_from_query($query, 'id');
+    
+    $data = array();
+    foreach ($sets as $set_id)
+    {
+      $BatchDownloader = new BatchDownloader($set_id);
+      $set = $BatchDownloader->getSetInfo();
+      
+      array_push($data, array(
+        'URL' => BATCH_DOWNLOAD_PUBLIC . 'init_zip&amp;set_id='.$BatchDownloader->getParam('set_id'),
+        'TITLE' => strip_tags($set['COMMENT']),
+        'NAME' => $set['sNAME'],
+        'COUNT' => $set['NB_IMAGES'],
+        ));
+    }
+    
+    $template->set_template_dir(BATCH_DOWNLOAD_PATH . 'template/');
+    $block->set_title(l10n('Downloads'));
+    $block->template = 'menublock.tpl';
+    $block->data = $data;
+  }
+}
+
+
+/* archives and databse cleanup */
+function batch_download_clean()
+{
+  global $conf;
+  
+  // we only search for old downloads every hour, nevermind which user is connected
+  if ($conf['batch_download']['last_clean'] > time() - 3600) return;
+  
+  $conf['batch_download']['last_clean'] = time();
+  conf_update_param('batch_download', serialize($conf['batch_download']));
+  
+  // set old sets as done
+  $query = '
+SELECT id 
+  FROM '.BATCH_DOWNLOAD_TSETS.'
+  WHERE 
+    date_creation < DATE_SUB(NOW(), INTERVAL '.$conf['batch_download']['archive_timeout'].' HOUR)
+    AND status != "done"
+;';
+  $sets = array_from_query($query, 'id');
+  
+  foreach ($sets as $set_id)
+  {
+    $BatchDownloader = new BatchDownloader($set_id);
+    $BatchDownloader->deleteLastArchive();
+    $BatchDownloader->clear(false);
+    $BatchDownloader->updateParam('status', 'done');
+  }
+  
+  // remove old archives
+  $zips = glob(BATCH_DOWNLOAD_LOCAL . 'u-*/*.zip');
+  foreach ($zips as $zip)
+  {
+    if (filemtime($zip) < time()-$conf['batch_download']['archive_timeout']*3600)
+    {
+      unlink($zip);
+    }
+  }
+}
+
+?>
Index: extensions/BatchDownloader/include/functions.inc.php
===================================================================
--- extensions/BatchDownloader/include/functions.inc.php	(revision 16379)
+++ extensions/BatchDownloader/include/functions.inc.php	(revision 16379)
@@ -0,0 +1,95 @@
+<?php
+defined('BATCH_DOWNLOAD_PATH') or die('Hacking attempt!');
+
+/**
+ * get BatchDownloader type and type_id from page info
+ * @return: array or false
+ */
+function get_set_info_from_page()
+{
+  global $page;
+  
+  switch ($page['section'])
+  {
+    case 'categories':
+      if (isset($page['chronology_field']))
+      {
+        $batch_type = 'calendar';
+        $batch_id = add_well_known_params_in_url('', 
+          array_intersect_key($page, 
+            array(
+              'chronology_field'=>0,
+              'chronology_style'=>0,
+              'chronology_view'=>0,
+              'chronology_date'=>0,
+          )));
+        $batch_id = ltrim($batch_id, '/');
+      }
+      else if (isset($page['category']))
+      {
+        $batch_type = 'category';
+        $batch_id = $page['category']['id'];
+      }
+      else if (isset($page['flat'])) // this is for the whole gallery only, flat mode for category is above
+      {
+        $batch_type = 'flat';
+        $batch_id = 0;
+      }
+      break;
+    case 'tags':
+      $batch_type = 'tags';
+      $batch_id = implode(',', array_map(create_function('$t', 'return $t["id"];'), $page['tags']));
+      break;
+    case 'search':
+      $batch_type = 'search';
+      $batch_id = $page['search'];
+      break;
+    case 'favorites':
+    case 'most_visited':
+    case 'best_rated':
+    case 'list':
+    case 'recent_pics':
+      $batch_type = $page['section'];
+      $batch_id = 0;
+      break;
+  }
+  
+  if ( isset($batch_type) and isset($batch_id) )
+  {
+    return array('type'=>$batch_type, 'id'=>$batch_id);
+  }
+  else
+  {
+    return false;
+  }
+}
+
+/**
+ * check is current user can use BatchDownloader
+ * @return: boolean
+ */
+function check_download_access()
+{
+  global $user, $conf;
+  
+  if (is_admin()) return true;
+  
+  if ($user['level'] < $conf['batch_download']['level']) return false;
+  
+  if (!empty($conf['batch_download']['groups']))
+  {
+    $query = '
+SELECT 1 FROM '.USER_GROUP_TABLE.'
+  WHERE
+    user_id = '.$user['id'].'
+    AND group_id IN('.implode(',', $conf['batch_download']['groups']).')
+;';
+    $result = pwg_query($query);
+    
+    if (!pwg_db_num_rows($result)) return false;
+  }
+  
+  return true;
+}
+
+?>
Index: extensions/BatchDownloader/include/index.php
===================================================================
--- extensions/BatchDownloader/include/index.php	(revision 16379)
+++ extensions/BatchDownloader/include/index.php	(revision 16379)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based photo gallery                                    |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2012 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: extensions/BatchDownloader/index.php
===================================================================
--- extensions/BatchDownloader/index.php	(revision 16379)
+++ extensions/BatchDownloader/index.php	(revision 16379)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based photo gallery                                    |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2012 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: extensions/BatchDownloader/language/en_UK/index.php
===================================================================
--- extensions/BatchDownloader/language/en_UK/index.php	(revision 16379)
+++ extensions/BatchDownloader/language/en_UK/index.php	(revision 16379)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based photo gallery                                    |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2012 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: extensions/BatchDownloader/language/en_UK/plugin.lang.php
===================================================================
--- extensions/BatchDownloader/language/en_UK/plugin.lang.php	(revision 16379)
+++ extensions/BatchDownloader/language/en_UK/plugin.lang.php	(revision 16379)
@@ -0,0 +1,5 @@
+<?php
+
+
+
+?>
Index: extensions/BatchDownloader/language/fr_FR/index.php
===================================================================
--- extensions/BatchDownloader/language/fr_FR/index.php	(revision 16379)
+++ extensions/BatchDownloader/language/fr_FR/index.php	(revision 16379)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based photo gallery                                    |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2012 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: extensions/BatchDownloader/language/fr_FR/plugin.lang.php
===================================================================
--- extensions/BatchDownloader/language/fr_FR/plugin.lang.php	(revision 16379)
+++ extensions/BatchDownloader/language/fr_FR/plugin.lang.php	(revision 16379)
@@ -0,0 +1,5 @@
+<?php
+
+
+
+?>
Index: extensions/BatchDownloader/language/index.php
===================================================================
--- extensions/BatchDownloader/language/index.php	(revision 16379)
+++ extensions/BatchDownloader/language/index.php	(revision 16379)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based photo gallery                                    |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2012 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: extensions/BatchDownloader/main.inc.php
===================================================================
--- extensions/BatchDownloader/main.inc.php	(revision 16379)
+++ extensions/BatchDownloader/main.inc.php	(revision 16379)
@@ -0,0 +1,53 @@
+<?php 
+/*
+Plugin Name: Batch Downloader
+Version: auto
+Description: Allows users to download pictures sets in ZIP. Compatible with User Selection.
+Plugin URI: http://piwigo.org/ext/extension_view.php?eid=
+Author: Mistic
+Author URI: http://www.strangeplanet.fr
+*/
+
+defined('PHPWG_ROOT_PATH') or die('Hacking attempt!');
+
+global $conf, $prefixeTable;
+
+define('BATCH_DOWNLOAD_PATH',    PHPWG_PLUGINS_PATH . basename(dirname(__FILE__)) . '/');
+define('BATCH_DOWNLOAD_TSETS',   $prefixeTable . 'download_sets');
+define('BATCH_DOWNLOAD_TIMAGES', $prefixeTable . 'download_sets_images');
+define('BATCH_DOWNLOAD_LOCAL',   PHPWG_ROOT_PATH . $conf['data_location'] . 'download_archives/');
+define('BATCH_DOWNLOAD_ADMIN',   get_root_url() . 'admin.php?page=plugin-' . basename(dirname(__FILE__)));
+define('BATCH_DOWNLOAD_PUBLIC',  make_index_url(array('section' => 'download')) . '/');
+
+if (class_exists('ZipArchive'))
+{
+  add_event_handler('init', 'batch_download_init');
+
+  add_event_handler('loc_end_section_init', 'batch_download_section_init');
+  add_event_handler('loc_end_index', 'batch_download_page');
+  
+  add_event_handler('loc_end_index', 'batch_download_clean');
+
+  add_event_handler('loc_begin_index', 'batch_download_index_button');
+
+  add_event_handler('blockmanager_register_blocks', 'batch_download_add_menublock');
+  add_event_handler('blockmanager_apply', 'batch_download_applymenu');
+  
+  require(BATCH_DOWNLOAD_PATH . 'include/functions.inc.php');
+  require(BATCH_DOWNLOAD_PATH . 'include/BatchDownloader.class.php');
+  require(BATCH_DOWNLOAD_PATH . 'include/events.inc.php');
+}
+
+add_event_handler('get_admin_plugin_menu_links', 'batch_download_admin_menu');
+
+/* admin plugins menu */
+function batch_download_admin_menu($menu) 
+{
+  array_push($menu, array(
+    'NAME' => 'Batch Downloader',
+    'URL' => BATCH_DOWNLOAD_ADMIN,
+  ));
+  return $menu;
+}
+
+?>
Index: extensions/BatchDownloader/maintain.inc.php
===================================================================
--- extensions/BatchDownloader/maintain.inc.php	(revision 16379)
+++ extensions/BatchDownloader/maintain.inc.php	(revision 16379)
@@ -0,0 +1,109 @@
+<?php
+if (!defined('PHPWG_ROOT_PATH')) die('Hacking attempt!');
+
+define(
+  'batch_download_default_config', 
+  serialize(array(
+    'groups'          => array(),
+    'level'           => 0,
+    'photo_size'      => 'original',
+    'archive_prefix'  => 'piwigo',
+    'archive_comment' => null,
+    'archive_timeout' => 48, /* hours */
+    'max_elements'    => 500,
+    'max_size'        => 100, /* MB */
+    'last_clean'      => time(),
+    ))
+  );
+
+function plugin_install() 
+{
+  global $conf, $prefixeTable;
+  
+  $query = '
+CREATE TABLE IF NOT EXISTS `' . $prefixeTable . 'download_sets` (
+  `id` mediumint(8) NOT NULL AUTO_INCREMENT,
+  `user_id` smallint(5) NOT NULL,
+  `date_creation` datetime NOT NULL,
+  `type` varchar(16) CHARACTER SET utf8 NOT NULL,
+  `type_id` varchar(64) CHARACTER SET utf8 NOT NULL,
+  `nb_zip` smallint(2) NOT NULL DEFAULT 0,
+  `last_zip` smallint(2) NOT NULL DEFAULT 0,
+  `nb_images` mediumint(8) NOT NULL DEFAULT 0,
+  `status` enum("new","download","done") CHARACTER SET utf8 NOT NULL DEFAULT "new",
+  PRIMARY KEY (`id`)
+) DEFAULT CHARSET=utf8 AUTO_INCREMENT=1
+;';
+  pwg_query($query);
+  
+  $query = '
+CREATE TABLE IF NOT EXISTS `' . $prefixeTable . 'download_sets_images` (
+  `set_id` mediumint(8) NOT NULL,
+  `image_id` mediumint(8) NOT NULL,
+  `zip` smallint(5) NOT NULL DEFAULT 0,
+  UNIQUE KEY `UNIQUE` (`set_id`,`image_id`)
+) DEFAULT CHARSET=utf8
+;';
+  pwg_query($query);
+
+  conf_update_param('batch_download', batch_download_default_config);
+  
+  mkdir($conf['data_location'] . 'download_archives/', 0755);
+}
+
+function plugin_activate()
+{
+  global $conf;
+
+  if (empty($conf['batch_download']))
+  {
+    conf_update_param('batch_download', batch_download_default_config);
+  }
+  
+  if (!file_exists($conf['data_location'] . 'download_archives/'))
+  {
+    mkdir($conf['data_location'] . 'download_archives/', 0755);
+  }
+}
+
+function plugin_uninstall() 
+{
+  global $prefixeTable, $conf;
+  
+  pwg_query('DELETE FROM `' . CONFIG_TABLE . '` WHERE param = "batch_download" LIMIT 1;');
+  pwg_query('DROP TABLE IF EXISTS `' . $prefixeTable . 'download_sets`;');
+  pwg_query('DROP TABLE IF EXISTS `' . $prefixeTable . 'download_sets_images`;');
+  
+  rrmdir($conf['data_location'].'download_archives/');
+}
+
+function rrmdir($dir)
+{
+  if (!is_dir($dir))
+  {
+    return false;
+  }
+  $dir = rtrim($dir, '/');
+  $objects = scandir($dir);
+  $return = true;
+  
+  foreach ($objects as $object)
+  {
+    if ($object !== '.' && $object !== '..')
+    {
+      $path = $dir.'/'.$object;
+      if (filetype($path) == 'dir') 
+      {
+        $return = $return && rrmdir($path); 
+      }
+      else 
+      {
+        $return = $return && @unlink($path);
+      }
+    }
+  }
+  
+  return $return && @rmdir($dir);
+} 
+
+?>
Index: extensions/BatchDownloader/template/init_zip.tpl
===================================================================
--- extensions/BatchDownloader/template/init_zip.tpl	(revision 16379)
+++ extensions/BatchDownloader/template/init_zip.tpl	(revision 16379)
@@ -0,0 +1,41 @@
+{$MENUBAR}
+
+{if $set.U_DOWNLOAD}
+{footer_script}
+setTimeout("document.location.href = '{$set.U_DOWNLOAD}';", 1000);
+{/footer_script}
+{/if}
+
+<div id="content" class="content{if isset($MENUBAR)} contentWithMenu{/if}">
+<div class="titrePage">
+  <ul class="categoryActions"></ul>
+  <h2>{$TITLE}</h2>
+</div>{* <!-- titrePage --> *}
+
+{if isset($errors) or not empty($infos)}
+{include file='infos_errors.tpl'}
+{/if}
+
+
+<p>
+  <h3>{$set.NAME}</h3>
+  {if $set.COMMENT}<blockquote>{$set.COMMENT}</blockquote>{/if}
+  <span>{'%d images'|@translate|@sprintf:$set.NB_IMAGES}{if $set.U_EDIT_SET}, <a href="{$set.U_EDIT_SET}" rel="nofollow">{'Edit the set'|@translate}</a>{/if}</span>
+</p>
+
+<p>
+  <b>{'Estimated size'|@translate}:</b> {$set.TOTAL_SIZE} MB<br>
+  <b>{'Estimated number of archives'|@translate}:</b> {$set.NB_ARCHIVES}<br>
+  <i>{'These datas are an estimation, real specs can differ'|@translate}</i>
+</p>
+
+<p>
+<b>Download links:</b>
+{$set.LINKS}
+</p>
+
+<p class="infos">
+{'<b>Warning:</b> all files will be deleted within %d hours'|@translate|@sprintf:$archive_timeout}
+</p>
+
+</div>{* <!-- content --> *}
Index: extensions/BatchDownloader/template/menublock.tpl
===================================================================
--- extensions/BatchDownloader/template/menublock.tpl	(revision 16379)
+++ extensions/BatchDownloader/template/menublock.tpl	(revision 16379)
@@ -0,0 +1,11 @@
+<dt>{$block->get_title()}</dt>
+<dd>
+	<ul>
+		{foreach from=$block->data item=link}
+		<li>
+      <a href="{$link.URL}" title="{$link.TITLE}" rel="nofollow">{$link.NAME}</a>
+      <span class="menuInfoCat">[{$link.COUNT}]</span>
+    </li>
+		{/foreach}
+	</ul>
+</dd>
Index: extensions/BatchDownloader/template/view.tpl
===================================================================
--- extensions/BatchDownloader/template/view.tpl	(revision 16379)
+++ extensions/BatchDownloader/template/view.tpl	(revision 16379)
@@ -0,0 +1,30 @@
+{$MENUBAR}
+
+<div id="content" class="content{if isset($MENUBAR)} contentWithMenu{/if}">
+<div class="titrePage{if isset($chronology.TITLE)} calendarTitleBar{/if}">
+  <ul class="categoryActions"></ul>
+  <h2>{$TITLE}</h2>
+</div>{* <!-- titrePage --> *}
+
+{if isset($errors) or not empty($infos)}
+{include file='infos_errors.tpl'}
+{/if}
+
+<p>
+  <h3>{$set.NAME}</h3>
+  {if $set.COMMENT}<blockquote>{$set.COMMENT}</blockquote>{/if}
+  <span>{'%d images'|@translate|@sprintf:$set.NB_IMAGES}</span>
+</p>
+
+
+{if !empty($THUMBNAILS)}
+<ul class="thumbnails" id="thumbnails">
+{$THUMBNAILS}
+</ul>
+{/if}
+
+{if !empty($navbar)}{include file='navigation_bar.tpl'|@get_extent:'navbar'}{/if}
+
+<p style="text-align:center;font-weight:bold;margin:20px;"><a href="{$U_INIT_ZIP}" rel="nofollow">{'Return to download page'|@translate}</a></p>
+
+</div>{* <!-- content --> *}
