Index: /extensions/UserCollections/admin.php
===================================================================
--- /extensions/UserCollections/admin.php	(revision 16591)
+++ /extensions/UserCollections/admin.php	(revision 16591)
@@ -0,0 +1,34 @@
+<?php
+if (!defined('FLICKR_PATH')) die('Hacking attempt!');
+
+global $template, $page, $conf;
+
+
+
+if (!file_exists(FLICKR_FS_CACHE))
+{
+  mkdir(FLICKR_FS_CACHE, 0755);
+}
+
+// tabsheet
+include_once(PHPWG_ROOT_PATH.'admin/include/tabsheet.class.php');
+$page['tab'] = (isset($_GET['tab'])) ? $_GET['tab'] : $page['tab'] = 'import';
+  
+$tabsheet = new tabsheet();
+$tabsheet->add('import', l10n('Import'), FLICKR_ADMIN . '-import');
+$tabsheet->add('config', l10n('Configuration'), FLICKR_ADMIN . '-config');
+$tabsheet->select($page['tab']);
+$tabsheet->assign();
+
+// include page
+include(FLICKR_PATH . 'admin/' . $page['tab'] . '.php');
+
+// template
+$template->assign(array(
+  'FLICKR_PATH'=> FLICKR_PATH,
+  'FLICKR_ABS_PATH'=> dirname(__FILE__).'/',
+  'FLICKR_ADMIN' => FLICKR_ADMIN,
+  ));
+$template->assign_var_from_handle('ADMIN_CONTENT', 'flickr2piwigo');
+
+?>
Index: /extensions/UserCollections/include/UserCollection.class.php
===================================================================
--- /extensions/UserCollections/include/UserCollection.class.php	(revision 16591)
+++ /extensions/UserCollections/include/UserCollection.class.php	(revision 16591)
@@ -0,0 +1,283 @@
+<?php
+defined('USER_COLLEC_PATH') or die('Hacking attempt!');
+
+class UserCollection
+{
+  // private $conf;
+  private $data;
+  private $images;
+  
+  /**
+   * __construct
+   * @param: mixed col id (##|'new'|'active')
+   * @param: array images
+   */
+  function __construct($col_id, $images=array(), $name=null, $active=false, $public=false)
+  {
+    global $user, $conf;
+    
+    // $this->conf = $conf['user_collections'];
+    $this->data = array(
+      'col_id' => 0,
+      'user_id' => $user['id'],
+      'name' => null,
+      'date_creation' => '0000-00-00 00:00:00',
+      'nb_images' => 0,
+      'active' => false,
+      'public' => false,
+      );
+    $this->images = array();
+    
+    // load specific collection
+    if (preg_match('#^[0-9]+$#', $col_id))
+    {
+      $query = '
+SELECT
+    user_id,
+    name,
+    date_creation,
+    nb_images,
+    active,
+    public
+  FROM '.COLLECTIONS_TABLE.'
+  WHERE
+    id = '.$col_id.'
+    '.(!is_admin() ? 'AND (user_id = '.$this->data['user_id'].' OR public = 1)' : null).'
+;';
+      $result = pwg_query($query);
+      
+      if (pwg_db_num_rows($result))
+      {
+        $this->data['col_id'] = $col_id;
+        list(
+          $this->data['user_id'],
+          $this->data['name'],
+          $this->data['date_creation'],
+          $this->data['nb_images'],
+          $this->data['active'],
+          $this->data['public']
+          ) = pwg_db_fetch_row($result);
+        
+        // make sur all pictures of the collection exist
+        $query = '
+DELETE FROM '.COLLECTION_IMAGES_TABLE.'
+  WHERE image_id NOT IN (
+    SELECT id FROM '.IMAGES_TABLE.'
+    )
+;';
+        pwg_query($query);
+      
+        $query = '
+SELECT image_id
+  FROM '.COLLECTION_IMAGES_TABLE.'
+  WHERE col_id = '.$this->data['col_id'].'
+;';
+        $this->images = array_from_query($query, 'image_id');
+        
+        if ($this->data['nb_images'] != count($this->images))
+        {
+          $this->updateParam('nb_images', count($this->images));
+        }
+      }
+      else
+      {
+        throw new Exception(l10n('Invalid collection'));
+      }
+    }
+    // create a new collection
+    else if ($col_id == 'new')
+    {
+      $this->data['name'] = $name;
+      $this->data['active'] = $active;
+      $this->data['public'] = $public;
+      
+      $query = '
+INSERT INTO '.COLLECTIONS_TABLE.'(
+    user_id,
+    name,
+    date_creation,
+    active,
+    public
+  ) 
+  VALUES(
+    '.$this->data['user_id'].',
+    "'.$this->data['name'].'",
+    NOW(),
+    '.(int)$this->data['active'].',
+    '.(int)$this->data['public'].'
+  )
+;';
+      pwg_query($query);
+      $this->data['col_id'] = pwg_db_insert_id();
+      
+      $date = pwg_query('SELECT FROM_UNIXTIME(NOW());');
+      list($this->data['date_creation']) = pwg_db_fetch_row($date);
+      
+      if (!empty($images))
+      {
+        $this->addImages($images);
+      }
+      
+      // only one active collection allowed
+      if ($this->data['active'])
+      {
+        $query = '
+UPDATE '.COLLECTIONS_TABLE.'
+  SET active = 0
+  WHERE
+    user_id = '.$this->data['user_id'].'
+    AND id != '.$this->data['col_id'].'
+;';
+        pwg_query($query);
+      }
+    }
+    else
+    {
+      trigger_error('UserCollection::__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 '.COLLECTIONS_TABLE.' SET '.$name.' = "'.$value.'" WHERE id = '.$this->data['col_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 in_array($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[ array_search($image_id, $this->images) ]);
+    }
+    
+    $query = '
+DELETE FROM '.COLLECTION_IMAGES_TABLE.'
+  WHERE 
+    col_id = '.$this->data['col_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;
+      
+      array_push($this->images, $image_id);
+      array_push($inserts, array('col_id'=>$this->data['col_id'], 'image_id'=>$image_id));
+    }
+    
+    mass_inserts(
+      COLLECTION_IMAGES_TABLE,
+      array('col_id', 'image_id'),
+      $inserts
+      );
+      
+    $this->updateParam('nb_images', count($this->images));
+  }
+  
+  /**
+   * toggleImage
+   * @param: int image id
+   */
+  function toggleImage($image_id)
+  {
+    if ($this->isInSet($image_id))
+    {
+      $this->removeImages(array($image_id));
+    }
+    else
+    {
+      $this->addImages(array($image_id));
+    }
+  }
+  
+  /**
+   * clearImages
+   */
+  function clearImages()
+  {
+    $this->images = array();
+    $this->updateParam('nb_images', 0);
+    
+    $query = '
+DELETE FROM '.COLLECTION_IMAGES_TABLE.'
+  WHERE col_id = '.$this->data['col_id'].'
+;';
+    pwg_query($query);
+  }
+  
+  /**
+   * getCollectionInfo
+   * @return: array
+   */
+  function getCollectionInfo()
+  {
+    $set = array(
+      'NAME' => $this->data['name'],
+      'NB_IMAGES' => $this->data['nb_images'],
+      'ACTIVE' => (bool)$this->data['active'],
+      'PUBLIC' => (bool)$this->data['public'],
+      'DATE_CREATION' => format_date($this->data['date_creation'], true),
+      'U_PUBLIC' => get_absolute_root_url().USER_COLLEC_PUBLIC . 'view/'.$this->data['col_id'],
+      'IS_TEMP' =>  $this->data['name'] == 'temp',
+      );
+    
+    return $set;
+  }
+}
+
+?>
Index: /extensions/UserCollections/include/collections.inc.php
===================================================================
--- /extensions/UserCollections/include/collections.inc.php	(revision 16591)
+++ /extensions/UserCollections/include/collections.inc.php	(revision 16591)
@@ -0,0 +1,285 @@
+<?php
+defined('USER_COLLEC_PATH') or die('Hacking attempt!');
+
+# this file is called on basket public page #
+
+global $page, $template, $conf, $user, $tokens;
+
+switch ($page['sub_section'])
+{
+  case 'list':
+  {
+    $template->set_filename('index', dirname(__FILE__) . '/../template/list.tpl');
+    
+    if ( isset($_GET['action']) and filter_var($_GET['col_id'], FILTER_VALIDATE_INT) !== false )
+    {
+      switch ($_GET['action'])
+      {
+        // new
+        case 'new':
+        {
+          new UserCollection('new', array(), empty($_GET['name']) ? 'temp' : $_GET['name'], 1);
+          redirect(USER_COLLEC_PUBLIC);
+          break;
+        }
+        
+        // clear
+        case 'clear':
+        {
+          $query = '
+DELETE ci
+  FROM '.COLLECTION_IMAGES_TABLE.' AS ci
+    INNER JOIN '.COLLECTIONS_TABLE.' AS c 
+    ON ci.col_id = c.id
+  WHERE
+    c.user_id = '.$user['id'].'
+    AND c.id = '.$_GET['col_id'].'
+;';
+          pwg_query($query);
+          
+          if (!empty($_SERVER['HTTP_REFERER']))
+          {
+            redirect($_SERVER['HTTP_REFERER']);
+          }
+          break;
+        }
+          
+        // delete
+        case 'delete':
+        {
+          $query = '
+DELETE ci, c
+  FROM '.COLLECTION_IMAGES_TABLE.' AS ci
+    RIGHT JOIN '.COLLECTIONS_TABLE.' AS c 
+    ON ci.col_id = c.id
+  WHERE
+    c.user_id = '.$user['id'].'
+    AND c.id = '.$_GET['col_id'].'
+;';
+          pwg_query($query);
+      
+          redirect(USER_COLLEC_PUBLIC);
+          break;
+        }
+        
+        // save
+        case 'save':
+        {
+          if (empty($_GET['name']))
+          {
+            array_push($page['errors'], l10n('Please give a name'));
+          }
+          else
+          {
+            $query = '
+UPDATE '.COLLECTIONS_TABLE.'
+  SET
+    name = "'.pwg_db_real_escape_string($_GET['name']).'",
+    active = 0
+  WHERE
+    user_id = '.$user['id'].'
+    AND id = '.$_GET['col_id'].'
+;';
+            pwg_query($query);
+            
+            redirect(USER_COLLEC_PUBLIC);
+          }
+          break;
+        }
+        
+        // set active
+        case 'set_active':
+        {
+          $query = '
+UPDATE '.COLLECTIONS_TABLE.'
+  SET active = 0
+  WHERE user_id = '.$user['id'].'
+;';
+          pwg_query($query);
+          
+          $query = '
+UPDATE '.COLLECTIONS_TABLE.'
+  SET active = 1
+  WHERE
+    user_id = '.$user['id'].'
+    AND id = '.$_GET['col_id'].'
+;';
+          pwg_query($query);
+          
+          redirect(USER_COLLEC_PUBLIC);
+          break;
+        }
+      }
+    }
+      
+    // get collections
+    $query = '
+SELECT * 
+  FROM '.COLLECTIONS_TABLE.'
+  WHERE user_id = '.$user['id'].'
+  ORDER BY date_creation DESC
+';
+    $collections = hash_from_query($query, 'id');
+    
+    foreach ($collections as $col)
+    {
+      $col['date_creation'] = format_date($col['date_creation'], true);
+      $col['U_VIEW'] = USER_COLLEC_PUBLIC.'view/'.$col['id'];
+      $col['U_EDIT'] = USER_COLLEC_PUBLIC.'edit/'.$col['id'];
+      $col['U_ACTIVE'] = USER_COLLEC_PUBLIC.'&amp;action=set_active&amp;col_id='.$col['id'];
+      $col['U_DELETE'] = USER_COLLEC_PUBLIC.'&amp;action=delete&amp;col_id='.$col['id'];
+      
+      if ($col['name'] == 'temp')
+      {
+        $col['name'] = 'temp #'.$col['id'];
+        $col['U_SAVE'] = USER_COLLEC_PUBLIC.'&amp;action=save&amp;col_id='.$col['id'];
+        $template->append('temp_col', $col);
+      }
+      else
+      {
+        $template->append('collections', $col);
+      }
+    }
+    
+    $template->assign('U_CREATE', USER_COLLEC_PUBLIC.'&amp;action=new&amp;col_id=0');
+    break;
+  }
+    
+  case 'edit':
+  {
+    if (empty($page['col_id']))
+    {
+      $_SESSION['page_errors'][] = l10n('Invalid collection');
+      redirect(USER_COLLEC_PUBLIC);
+    }
+    
+    $self_url = USER_COLLEC_PUBLIC . 'edit/'.$page['col_id'];
+    
+    $template->set_filename('index', dirname(__FILE__).'/../template/edit.tpl');
+    $template->assign(array(
+      'USER_COLLEC_PATH' => USER_COLLEC_PATH,
+      'U_VIEW' => $self_url,
+      'U_LIST' => USER_COLLEC_PUBLIC,
+      ));
+    
+    try {
+      $UserCollection = new UserCollection($page['col_id']);
+      
+      // save properties
+      if (isset($_POST['save_col']))
+      {
+        $UserCollection->updateParam('name', $_POST['name']);
+        $UserCollection->updateParam('public', $_POST['public']);
+      }
+      
+      // remove an element
+      if ( isset($_GET['remove']) and preg_match('#^[0-9]+$#', $_GET['remove']) )
+      {
+        $UserCollection->removeImages(array($_GET['remove']));
+      }
+      
+      $template->assign('collection', $UserCollection->getCollectionInfo());
+      
+      $template->set_prefilter('index_thumbnails', 'user_collection_thumbnails_list_prefilter');
+      
+      $page['start'] = isset($_GET['start']) ? $_GET['start'] : 0;
+      $page['items'] = $UserCollection->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');
+    }
+    catch (Exception $e)
+    {
+      array_push($page['errors'], $e->getMessage());
+    }
+    
+    break;
+  }
+  
+  case 'view':
+  {
+    if (empty($page['col_id']))
+    {
+      $_SESSION['page_errors'][] = l10n('Invalid collection');
+      redirect(get_home_url());
+    }
+    
+    $self_url = USER_COLLEC_PUBLIC . 'view/'.$page['col_id'];
+    
+    $template->set_filename('index', dirname(__FILE__).'/../template/view.tpl');
+    $template->assign(array(
+      'USER_COLLEC_PATH' => USER_COLLEC_PATH,
+      'U_VIEW' => $self_url,
+      ));
+    
+    try
+    {
+      $UserCollection = new UserCollection($page['col_id']);
+      
+      if ($UserCollection->getParam('user_id') == $user['id'])
+      {
+        $template->assign('U_LIST', USER_COLLEC_PUBLIC);
+      }
+      
+      $template->assign('collection', $UserCollection->getCollectionInfo());
+      
+      include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
+      $template->assign('OWNER', get_username($UserCollection->getParam('user_id')));
+      
+      $page['start'] = isset($_GET['start']) ? $_GET['start'] : 0;
+      $page['items'] = $UserCollection->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');
+    }
+    catch (Exception $e)
+    {
+      array_push($page['errors'], $e->getMessage());
+    }
+    
+    break;
+  }
+    
+  // case 'send':
+  // {
+    
+    // break;
+  // }
+}
+
+$template->assign('USER_COLLEC_PATH', USER_COLLEC_PATH);
+
+function user_collection_thumbnails_list_prefilter($content, &$smarty)
+{
+  $search = '<span class="thumbName">';
+  
+  $add = '<a href="{$U_VIEW}&amp;remove={$thumbnail.id}" rel="nofollow">
+<img src="{$USER_COLLEC_PATH}template/image_delete.png" title="{\'Remove from collection\'|@translate}">
+</a>&nbsp;';
+
+  return str_replace($search, $search.$add, $content);
+}
+
+?>
Index: /extensions/UserCollections/include/events.inc.php
===================================================================
--- /extensions/UserCollections/include/events.inc.php	(revision 16591)
+++ /extensions/UserCollections/include/events.inc.php	(revision 16591)
@@ -0,0 +1,238 @@
+<?php
+defined('USER_COLLEC_PATH') or die('Hacking attempt!');
+
+# this file contains all functions directly called by the triggers #
+
+/* unserialize conf and load language */
+function user_collections_init()
+{
+  global $conf;
+  
+  // $conf['user_collections'] = unserialize($conf['user_collections']);
+  load_language('plugin.lang', USER_COLLEC_PATH);
+}
+
+
+/* define page section from url */
+function user_collections_section_init()
+{
+  global $tokens, $page, $conf;
+  
+  if ($tokens[0] == 'collections')
+  {
+    $page['section'] = 'collections';
+    $page['title'] = '<a href="'.USER_COLLEC_PUBLIC.'">'.l10n('Collections').'</a>';
+    
+    switch (@$tokens[1])
+    {
+      case 'edit':
+        $page['sub_section'] = 'edit';
+        $page['title'].= $conf['level_separator'].' '.l10n('Edit');
+        break;
+      case 'view':
+        $page['sub_section'] = 'view';
+        $page['title'].= $conf['level_separator'].' '.l10n('View');
+        break;
+      // case 'send':
+        // $page['sub_section'] = 'send';
+        // $page['title'].= $conf['level_separator'].' '.l10n('Send');
+        // break;
+      default:
+        $page['sub_section'] = 'list';
+    }
+    
+    if (!empty($tokens[2]))
+    {
+      $page['col_id'] = $tokens[2];
+    }
+  }
+}
+
+/* collection section */
+function user_collections_page()
+{
+  global $page;
+
+  if (isset($page['section']) and $page['section'] == 'collections')
+  {
+    include(USER_COLLEC_PATH . '/include/collections.inc.php');
+  }
+}
+
+
+/* add buttons on thumbnails list */
+function user_collections_index_actions()
+{
+  global $page, $UserCollection;
+     
+  // add image to collection list
+  if ( isset($_GET['collection_toggle']) and  preg_match('#^[0-9]+$#', $_GET['collection_toggle']) )
+  {
+    if (empty($UserCollection))
+    {
+      $UserCollection = new UserCollection(get_current_collection_id(true));
+    }
+    $UserCollection->toggleImage($_GET['collection_toggle']);
+    redirect(duplicate_index_url(array(), array('collection_toggle')));
+  }
+}
+
+function user_collections_thumbnails_list($tpl_thumbnails_var, $pictures)
+{
+  global $page, $template, $UserCollection;
+  
+  // the prefilter is different on collection page
+  if (isset($page['section']) and $page['section'] == 'collections') return $tpl_thumbnails_var;
+  
+  // get existing collections
+  if (empty($UserCollection) and ($col_id = get_current_collection_id(false)) !== false)
+  {
+    $UserCollection = new UserCollection($col_id);
+    $collection = $UserCollection->getImages();
+  }
+  else if (!empty($UserCollection))
+  {
+    $collection = $UserCollection->getImages();
+  }
+  else
+  {
+    $collection = array();
+  }
+  
+  
+  
+  $self_url = duplicate_index_url(array(), array('collection_toggle'));  
+  
+  foreach ($tpl_thumbnails_var as &$thumbnail)
+  {
+    if (in_array($thumbnail['id'], $collection))
+    {
+      $thumbnail['COLLECTION_SELECTED'] = true;
+    }
+  }
+  unset($thumbnail);
+  
+  // thumbnails buttons
+  $template->assign(array(
+    'USER_COLLEC_PATH' => USER_COLLEC_PATH,
+    'collection_toggle_url' =>  $self_url,
+    ));
+  $template->set_prefilter('index_thumbnails', 'user_collections_thumbnails_list_prefilter');
+  
+  return $tpl_thumbnails_var;
+}
+
+function user_collections_thumbnails_list_prefilter($content, &$smarty)
+{
+  $search = '<span class="thumbName">';
+  
+  $add = '<a href="{$collection_toggle_url}&amp;collection_toggle={$thumbnail.id}" rel="nofollow">
+{if $thumbnail.COLLECTION_SELECTED}
+<img src="{$USER_COLLEC_PATH}template/image_delete.png" title="{\'Remove from collection\'|@translate}">
+{else}
+<img src="{$USER_COLLEC_PATH}template/image_add.png" title="{\'Add to collection\'|@translate}">
+{/if}
+</a>&nbsp;';
+
+  return str_replace($search, $search.$add, $content);
+}
+
+
+/* add button on picture page */
+function user_collections_picture_page()
+{
+  global $template, $picture, $UserCollection;
+  
+  // add image to collection list
+  if ( isset($_GET['action']) and $_GET['action'] == 'collection_toggle' )
+  {
+    if (empty($UserCollection))
+    {
+      $UserCollection = new UserCollection(get_current_collection_id(true));
+    }
+    
+    $UserCollection->toggleImage($picture['current']['id']);
+    redirect(duplicate_picture_url());
+  }
+  
+  // get existing collection
+  if (empty($UserCollection) and ($col_id = get_current_collection_id(false)) !== false)
+  {
+    $UserCollection = new UserCollection($col_id);
+    $collection = $UserCollection->isInSet($picture['current']['id']);
+  }
+  else if (!empty($UserCollection))
+  {
+    $collection = $UserCollection->isInSet($picture['current']['id']);
+  }
+  else
+  {
+    $collection = false;
+  }  
+  
+  $url = duplicate_picture_url().'&amp;action=collection_toggle';    
+  
+  $button = '
+<a href="'.$url.'" title="'.($collection?l10n('Remove from collection'):l10n('Add to collection')).'" class="pwg-state-default pwg-button" rel="nofollow">
+  <span class="pwg-icon" style="background:url(\''.USER_COLLEC_PATH.'template/image_'.($collection?'delete':'add').'.png\') center center no-repeat;"> </span>
+  <span class="pwg-button-text">'.($collection?l10n('Remove from collection'):l10n('Add to collection')).'</span>
+</a>';
+    
+  $template->concat('PLUGIN_PICTURE_ACTIONS', $button);
+}
+
+
+/* menu block */
+function user_collections_add_menublock($menu_ref_arr)
+{
+  $menu = &$menu_ref_arr[0];
+  if ($menu->get_id() != 'menubar') return;
+  
+  if (get_current_collection_id(false) === false) return;
+  
+  $menu->register_block(new RegisteredBlock('mbUserCollection', l10n('Download Basket'), 'UserCollection'));
+}
+
+function user_collections_applymenu($menu_ref_arr)
+{
+  global $template, $conf, $UserCollection;
+  $menu = &$menu_ref_arr[0];
+  
+  if (($block = $menu->get_block('mbUserCollection')) != null)
+  {
+    if (empty($UserCollection))
+    {
+      $UserCollection = new UserCollection(get_current_collection_id());
+    }
+    
+    $data = array(
+      'U_LIST' => USER_COLLEC_PUBLIC,
+      'current' => array(
+        'NAME' => $UserCollection->getParam('name'),
+        'NB_IMAGES' => $UserCollection->getParam('nb_images'),
+        ),
+      'links' => array(),
+      );
+      
+    if ($data['current']['NB_IMAGES'] > 0)
+    {
+      $data['links'] = array(
+        array(
+          'URL' => USER_COLLEC_PUBLIC.'view/'.$UserCollection->getParam('col_id'),
+          'NAME' => l10n('View'),
+          ),
+        array(
+          'URL' => USER_COLLEC_PUBLIC.'&amp;action=clear&amp;col_id='.$UserCollection->getParam('col_id'),
+          'NAME' => l10n('Clear'),
+          ),
+        );
+    }
+      
+    $template->set_template_dir(USER_COLLEC_PATH . 'template/');
+    $block->set_title(l10n('Collections'));
+    $block->template = 'menublock.tpl';
+    $block->data = $data;
+  }
+}
+
+?>
Index: /extensions/UserCollections/include/functions.inc.php
===================================================================
--- /extensions/UserCollections/include/functions.inc.php	(revision 16591)
+++ /extensions/UserCollections/include/functions.inc.php	(revision 16591)
@@ -0,0 +1,34 @@
+<?php
+defined('USER_COLLEC_PATH') or die('Hacking attempt!');
+
+function get_current_collection_id($create=true)
+{
+  global $user;
+  
+  // active in db
+  $query = '
+SELECT id
+  FROM '.COLLECTIONS_TABLE.'
+  WHERE
+    active = 1
+    AND user_id = '.$user['id'].'
+;';
+  $result = pwg_query($query);
+  
+  if (pwg_db_num_rows($result))
+  {
+    list($col_id) = pwg_db_fetch_row($result);
+    return $col_id;
+  }
+  
+  // new one
+  if ($create)
+  {
+    $UserCollection = new UserCollection('new', array(), 'temp', 1);
+    return $UserCollection->getParam('col_id');
+  }
+  
+  return false;
+}
+
+?>
Index: /extensions/UserCollections/include/index.php
===================================================================
--- /extensions/UserCollections/include/index.php	(revision 16591)
+++ /extensions/UserCollections/include/index.php	(revision 16591)
@@ -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/UserCollections/index.php
===================================================================
--- /extensions/UserCollections/index.php	(revision 16591)
+++ /extensions/UserCollections/index.php	(revision 16591)
@@ -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/UserCollections/language/en_UK/index.php
===================================================================
--- /extensions/UserCollections/language/en_UK/index.php	(revision 16591)
+++ /extensions/UserCollections/language/en_UK/index.php	(revision 16591)
@@ -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/UserCollections/language/en_UK/plugin.lang.php
===================================================================
--- /extensions/UserCollections/language/en_UK/plugin.lang.php	(revision 16591)
+++ /extensions/UserCollections/language/en_UK/plugin.lang.php	(revision 16591)
@@ -0,0 +1,5 @@
+<?php
+
+
+
+?>
Index: /extensions/UserCollections/language/fr_FR/index.php
===================================================================
--- /extensions/UserCollections/language/fr_FR/index.php	(revision 16591)
+++ /extensions/UserCollections/language/fr_FR/index.php	(revision 16591)
@@ -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/UserCollections/language/fr_FR/plugin.lang.php
===================================================================
--- /extensions/UserCollections/language/fr_FR/plugin.lang.php	(revision 16591)
+++ /extensions/UserCollections/language/fr_FR/plugin.lang.php	(revision 16591)
@@ -0,0 +1,5 @@
+<?php
+
+
+
+?>
Index: /extensions/UserCollections/language/index.php
===================================================================
--- /extensions/UserCollections/language/index.php	(revision 16591)
+++ /extensions/UserCollections/language/index.php	(revision 16591)
@@ -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/UserCollections/main.inc.php
===================================================================
--- /extensions/UserCollections/main.inc.php	(revision 16591)
+++ /extensions/UserCollections/main.inc.php	(revision 16591)
@@ -0,0 +1,39 @@
+<?php 
+/*
+Plugin Name: User Collections
+Version: auto
+Description: Registered users can select pictures from the gallery and save them into collections, kind of advanced favorites.
+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('USER_COLLEC_PATH',      PHPWG_PLUGINS_PATH . basename(dirname(__FILE__)) . '/');
+define('COLLECTIONS_TABLE',     $prefixeTable.'collections');
+define('COLLECTION_IMAGES_TABLE',$prefixeTable.'collection_images');
+define('USER_COLLEC_ADMIN',     get_root_url() . 'admin.php?page=plugin-' . basename(dirname(__FILE__)));
+define('USER_COLLEC_PUBLIC',    make_index_url(array('section' => 'collections')) . '/');
+
+
+add_event_handler('init', 'user_collections_init');
+
+add_event_handler('loc_end_section_init', 'user_collections_section_init');
+add_event_handler('loc_end_index', 'user_collections_page');
+
+add_event_handler('loc_end_index', 'user_collections_index_actions');
+add_event_handler('loc_end_index_thumbnails', 'user_collections_thumbnails_list', EVENT_HANDLER_PRIORITY_NEUTRAL, 2);
+
+add_event_handler('loc_end_picture', 'user_collections_picture_page');
+
+add_event_handler('blockmanager_register_blocks', 'user_collections_add_menublock');
+add_event_handler('blockmanager_apply', 'user_collections_applymenu');
+
+require(USER_COLLEC_PATH . 'include/functions.inc.php');
+require(USER_COLLEC_PATH . 'include/UserCollection.class.php');
+require(USER_COLLEC_PATH . 'include/events.inc.php');
+
+?>
Index: /extensions/UserCollections/maintain.inc.php
===================================================================
--- /extensions/UserCollections/maintain.inc.php	(revision 16591)
+++ /extensions/UserCollections/maintain.inc.php	(revision 16591)
@@ -0,0 +1,44 @@
+<?php
+if (!defined('PHPWG_ROOT_PATH')) die('Hacking attempt!');
+
+function plugin_install() 
+{
+  global $conf, $prefixeTable;
+  
+  $query = '
+CREATE TABLE IF NOT EXISTS `'.$prefixeTable.'collections` (
+  `id` mediumint(8) NOT NULL AUTO_INCREMENT,
+  `user_id` smallint(5) DEFAULT NULL,
+  `name` varchar(255) NOT NULL,
+  `date_creation` datetime NOT NULL,
+  `nb_images` mediumint(8) NOT NULL DEFAULT 0,
+  `active` tinyint(1) DEFAULT 0,
+  `public` tinyint(1) DEFAULT 0,
+  PRIMARY KEY (`id`)
+) DEFAULT CHARSET=utf8 AUTO_INCREMENT=1
+;';
+  pwg_query($query);
+  
+  $query = '
+CREATE TABLE IF NOT EXISTS `'.$prefixeTable.'collection_images` (
+  `col_id` mediumint(8) NOT NULL,
+  `image_id` mediumint(8) NOT NULL,
+  UNIQUE KEY `UNIQUE` (`col_id`,`image_id`)
+) DEFAULT CHARSET=utf8
+;';
+  pwg_query($query);
+}
+
+function plugin_activate()
+{}
+
+function plugin_uninstall() 
+{
+  global $prefixeTable;
+  
+  pwg_query('DELETE FROM `'. CONFIG_TABLE .'` WHERE param = "user_collections" LIMIT 1;');
+  pwg_query('DROP TABLE IF EXISTS `'.$prefixeTable.'collections`;');
+  pwg_query('DROP TABLE IF EXISTS `'.$prefixeTable.'collection_images`;');
+}
+
+?>
Index: /extensions/UserCollections/template/edit.tpl
===================================================================
--- /extensions/UserCollections/template/edit.tpl	(revision 16591)
+++ /extensions/UserCollections/template/edit.tpl	(revision 16591)
@@ -0,0 +1,77 @@
+{combine_css path=$USER_COLLEC_PATH|@cat:"template/style.css"}
+{combine_script id='jquery.zclip' path=$USER_COLLEC_PATH|@cat:"template/jquery.zclip.min.js"}
+{combine_script id='jquery.tipTip' path='themes/default/js/plugins/jquery.tipTip.minified.js'}
+
+{footer_script require='jquery'}
+function bindZclip() {ldelim}
+  jQuery("#publicURL .button").zclip({ldelim}
+    path:'{$USER_COLLEC_PATH}template/ZeroClipboard.swf',
+    copy:$("#publicURL .url").html(),
+    afterCopy: function() {ldelim}
+      $('<span class="confirm" style="display:none;">{'Copied'|@translate}</span>').appendTo("#publicURL")
+        .fadeIn(400).delay(1000).fadeOut(400, function(){ldelim} $(this).remove(); });
+    }
+  });
+}
+
+jQuery("input[name='public']").change(function() {ldelim}
+  jQuery("#publicURL").fadeToggle("fast");
+  bindZclip();
+});
+jQuery("#publicURL .button").tipTip({ldelim}
+  delay: 0,
+  defaultPosition: 'right'
+});
+{if $collection.PUBLIC}bindZclip();{/if}
+{/footer_script}
+
+{$MENUBAR}
+
+<div id="content" class="content{if isset($MENUBAR)} contentWithMenu{/if}">
+<div class="titrePage{if isset($chronology.TITLE)} calendarTitleBar{/if}">
+  <ul class="categoryActions">
+  {if !empty($COLLECTION_ACTIONS)}{$COLLECTION_ACTIONS}{/if}
+  </ul>
+  <h2>{$TITLE}</h2>
+</div>{* <!-- titrePage --> *}
+
+{if isset($errors) or not empty($infos)}
+{include file='infos_errors.tpl'}
+{/if}
+
+{if $collection and not $collection.IS_TEMP}
+<form action="{$U_VIEW}" method="post">
+<fieldset id="colProperties">
+  <legend>{'Properties'|@translate}</legend>
+  
+  <p class="title"><label for="name">{'Name'|@translate}</label></p>
+  <p><input type="text" name="name" id="name" value="{$collection.NAME}" size="60"></p>
+  <p class="title">{'Public'|@translate}</p>
+  <p>
+    <label><input type="radio" name="public" value="0" {if not $collection.PUBLIC}checked="checked"{/if}> {'No'|@translate}</label>
+    <label><input type="radio" name="public" value="1" {if $collection.PUBLIC}checked="checked"{/if}> {'Yes'|@translate}</label>
+    <span id="publicURL" {if not $collection.PUBLIC}style="display:none;"{/if}><span class="button" title="{'Copy to clipborad'|@translate}">&nbsp;</span><span class="url">{$collection.U_PUBLIC}</span></span>
+  </p>
+  <p>
+    <input type="submit" name="save_col" value="{'Save'|@translate}">
+    <a href="{$U_LIST}" rel="nofollow">{'Return to collections list'|@translate}</a>
+  </p>
+</fieldset>
+</form>
+{/if}
+
+  
+
+{if !empty($THUMBNAILS)}
+<ul class="thumbnails" id="thumbnails">
+{$THUMBNAILS}
+</ul>
+{else}
+<p><i>{'This collection is empty'|@translate}</i></p>
+{/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_LIST}" rel="nofollow">{'Return to collections list'|@translate}</a></p>
+
+</div>{* <!-- content --> *}
Index: /extensions/UserCollections/template/jquery.zclip.min.js
===================================================================
--- /extensions/UserCollections/template/jquery.zclip.min.js	(revision 16591)
+++ /extensions/UserCollections/template/jquery.zclip.min.js	(revision 16591)
@@ -0,0 +1,12 @@
+/*
+ * zClip :: jQuery ZeroClipboard v1.1.1
+ * http://steamdev.com/zclip
+ *
+ * Copyright 2011, SteamDev
+ * Released under the MIT license.
+ * http://www.opensource.org/licenses/mit-license.php
+ *
+ * Date: Wed Jun 01, 2011
+ */
+
+(function(a){a.fn.zclip=function(c){if(typeof c=="object"&&!c.length){var b=a.extend({path:"ZeroClipboard.swf",copy:null,beforeCopy:null,afterCopy:null,clickAfter:true,setHandCursor:true,setCSSEffects:true},c);return this.each(function(){var e=a(this);if(e.is(":visible")&&(typeof b.copy=="string"||a.isFunction(b.copy))){ZeroClipboard.setMoviePath(b.path);var d=new ZeroClipboard.Client();if(a.isFunction(b.copy)){e.bind("zClip_copy",b.copy)}if(a.isFunction(b.beforeCopy)){e.bind("zClip_beforeCopy",b.beforeCopy)}if(a.isFunction(b.afterCopy)){e.bind("zClip_afterCopy",b.afterCopy)}d.setHandCursor(b.setHandCursor);d.setCSSEffects(b.setCSSEffects);d.addEventListener("mouseOver",function(f){e.trigger("mouseenter")});d.addEventListener("mouseOut",function(f){e.trigger("mouseleave")});d.addEventListener("mouseDown",function(f){e.trigger("mousedown");if(!a.isFunction(b.copy)){d.setText(b.copy)}else{d.setText(e.triggerHandler("zClip_copy"))}if(a.isFunction(b.beforeCopy)){e.trigger("zClip_beforeCopy")}});d.addEventListener("complete",function(f,g){if(a.isFunction(b.afterCopy)){e.trigger("zClip_afterCopy")}else{if(g.length>500){g=g.substr(0,500)+"...\n\n("+(g.length-500)+" characters not shown)"}e.removeClass("hover");/*alert("Copied text to clipboard:\n\n "+g)*/}if(b.clickAfter){e.trigger("click")}});d.glue(e[0],e.parent()[0]);a(window).bind("load resize",function(){d.reposition()})}})}else{if(typeof c=="string"){return this.each(function(){var f=a(this);c=c.toLowerCase();var e=f.data("zclipId");var d=a("#"+e+".zclip");if(c=="remove"){d.remove();f.removeClass("active hover")}else{if(c=="hide"){d.hide();f.removeClass("active hover")}else{if(c=="show"){d.show()}}}})}}}})(jQuery);var ZeroClipboard={version:"1.0.7",clients:{},moviePath:"ZeroClipboard.swf",nextId:1,$:function(a){if(typeof(a)=="string"){a=document.getElementById(a)}if(!a.addClass){a.hide=function(){this.style.display="none"};a.show=function(){this.style.display=""};a.addClass=function(b){this.removeClass(b);this.className+=" "+b};a.removeClass=function(d){var e=this.className.split(/\s+/);var b=-1;for(var c=0;c<e.length;c++){if(e[c]==d){b=c;c=e.length}}if(b>-1){e.splice(b,1);this.className=e.join(" ")}return this};a.hasClass=function(b){return !!this.className.match(new RegExp("\\s*"+b+"\\s*"))}}return a},setMoviePath:function(a){this.moviePath=a},dispatch:function(d,b,c){var a=this.clients[d];if(a){a.receiveEvent(b,c)}},register:function(b,a){this.clients[b]=a},getDOMObjectPosition:function(c,a){var b={left:0,top:0,width:c.width?c.width:c.offsetWidth,height:c.height?c.height:c.offsetHeight};if(c&&(c!=a)){b.left+=c.offsetLeft;b.top+=c.offsetTop}return b},Client:function(a){this.handlers={};this.id=ZeroClipboard.nextId++;this.movieId="ZeroClipboardMovie_"+this.id;ZeroClipboard.register(this.id,this);if(a){this.glue(a)}}};ZeroClipboard.Client.prototype={id:0,ready:false,movie:null,clipText:"",handCursorEnabled:true,cssEffects:true,handlers:null,glue:function(d,b,e){this.domElement=ZeroClipboard.$(d);var f=99;if(this.domElement.style.zIndex){f=parseInt(this.domElement.style.zIndex,10)+1}if(typeof(b)=="string"){b=ZeroClipboard.$(b)}else{if(typeof(b)=="undefined"){b=document.getElementsByTagName("body")[0]}}var c=ZeroClipboard.getDOMObjectPosition(this.domElement,b);this.div=document.createElement("div");this.div.className="zclip";this.div.id="zclip-"+this.movieId;$(this.domElement).data("zclipId","zclip-"+this.movieId);var a=this.div.style;a.position="absolute";a.left=""+c.left+"px";a.top=""+c.top+"px";a.width=""+c.width+"px";a.height=""+c.height+"px";a.zIndex=f;if(typeof(e)=="object"){for(addedStyle in e){a[addedStyle]=e[addedStyle]}}b.appendChild(this.div);this.div.innerHTML=this.getHTML(c.width,c.height)},getHTML:function(d,a){var c="";var b="id="+this.id+"&width="+d+"&height="+a;if(navigator.userAgent.match(/MSIE/)){var e=location.href.match(/^https/i)?"https://":"http://";c+='<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="'+e+'download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0" width="'+d+'" height="'+a+'" id="'+this.movieId+'" align="middle"><param name="allowScriptAccess" value="always" /><param name="allowFullScreen" value="false" /><param name="movie" value="'+ZeroClipboard.moviePath+'" /><param name="loop" value="false" /><param name="menu" value="false" /><param name="quality" value="best" /><param name="bgcolor" value="#ffffff" /><param name="flashvars" value="'+b+'"/><param name="wmode" value="transparent"/></object>'}else{c+='<embed id="'+this.movieId+'" src="'+ZeroClipboard.moviePath+'" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="'+d+'" height="'+a+'" name="'+this.movieId+'" align="middle" allowScriptAccess="always" allowFullScreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="'+b+'" wmode="transparent" />'}return c},hide:function(){if(this.div){this.div.style.left="-2000px"}},show:function(){this.reposition()},destroy:function(){if(this.domElement&&this.div){this.hide();this.div.innerHTML="";var a=document.getElementsByTagName("body")[0];try{a.removeChild(this.div)}catch(b){}this.domElement=null;this.div=null}},reposition:function(c){if(c){this.domElement=ZeroClipboard.$(c);if(!this.domElement){this.hide()}}if(this.domElement&&this.div){var b=ZeroClipboard.getDOMObjectPosition(this.domElement);var a=this.div.style;a.left=""+b.left+"px";a.top=""+b.top+"px"}},setText:function(a){this.clipText=a;if(this.ready){this.movie.setText(a)}},addEventListener:function(a,b){a=a.toString().toLowerCase().replace(/^on/,"");if(!this.handlers[a]){this.handlers[a]=[]}this.handlers[a].push(b)},setHandCursor:function(a){this.handCursorEnabled=a;if(this.ready){this.movie.setHandCursor(a)}},setCSSEffects:function(a){this.cssEffects=!!a},receiveEvent:function(d,f){d=d.toString().toLowerCase().replace(/^on/,"");switch(d){case"load":this.movie=document.getElementById(this.movieId);if(!this.movie){var c=this;setTimeout(function(){c.receiveEvent("load",null)},1);return}if(!this.ready&&navigator.userAgent.match(/Firefox/)&&navigator.userAgent.match(/Windows/)){var c=this;setTimeout(function(){c.receiveEvent("load",null)},100);this.ready=true;return}this.ready=true;try{this.movie.setText(this.clipText)}catch(h){}try{this.movie.setHandCursor(this.handCursorEnabled)}catch(h){}break;case"mouseover":if(this.domElement&&this.cssEffects){this.domElement.addClass("hover");if(this.recoverActive){this.domElement.addClass("active")}}break;case"mouseout":if(this.domElement&&this.cssEffects){this.recoverActive=false;if(this.domElement.hasClass("active")){this.domElement.removeClass("active");this.recoverActive=true}this.domElement.removeClass("hover")}break;case"mousedown":if(this.domElement&&this.cssEffects){this.domElement.addClass("active")}break;case"mouseup":if(this.domElement&&this.cssEffects){this.domElement.removeClass("active");this.recoverActive=false}break}if(this.handlers[d]){for(var b=0,a=this.handlers[d].length;b<a;b++){var g=this.handlers[d][b];if(typeof(g)=="function"){g(this,f)}else{if((typeof(g)=="object")&&(g.length==2)){g[0][g[1]](this,f)}else{if(typeof(g)=="string"){window[g](this,f)}}}}}}};
Index: /extensions/UserCollections/template/list.tpl
===================================================================
--- /extensions/UserCollections/template/list.tpl	(revision 16591)
+++ /extensions/UserCollections/template/list.tpl	(revision 16591)
@@ -0,0 +1,73 @@
+{combine_css path=$USER_COLLEC_PATH|@cat:"template/style.css"}
+
+{footer_script require='jquery'}
+jQuery(".save_col").click(function() {ldelim}
+  var name = prompt("{'Collection name:'|@translate}");
+  $(this).attr("href",  $(this).attr("href") +"&name="+ name);
+  return true;
+});
+{/footer_script}
+
+{$MENUBAR}
+
+<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 style="text-align:left;font-weight:bold;margin:20px;"><a href="{$U_CREATE}" class="save_col">{'Create a new collection'|@translate}</a></p>
+
+{if $temp_col}
+<fieldset>
+  <legend>{'Unsaved collections'|@translate}</legend>
+  
+  <ul class="collecList">
+  {foreach from=$temp_col item=col}
+    <li {if $col.active}class="active"{/if}>
+      <p class="collecTitle">
+        <a href="{$col.U_VIEW}" rel="nofollow"><b>{$col.name}</b></a> 
+        <i>{'%d images'|@translate|@sprintf:$col.nb_images}</i>
+      </p>
+      <p class="collecActions">
+        <a href="{$col.U_EDIT}" rel="nofollow">{'Edit'|@translate}</a> |
+        <a href="{$col.U_SAVE}" class="save_col" rel="nofollow">{'save'|@translate}</a> |
+        <a href="{$col.U_DELETE}" onClick="return confirm('{'Are you sure?'|@translate}');" rel="nofollow">{'delete'|@translate}</a>
+        {if not $col.active}| <a href="{$col.U_ACTIVE}" rel="nofollow">{'set active'|@translate}</a>{/if}
+      </p>
+    </li>
+  {/foreach}
+  </ul>
+</fieldset>
+{/if}
+
+{if $collections}
+<fieldset>
+  <legend>{'Saved collections'|@translate}</legend>
+  
+  <ul class="collecList">
+  {foreach from=$collections item=col}
+    <li {if $col.active}class="active"{/if}>
+      <p class="collecDate">
+        {'created on %s'|@translate|@sprintf:$col.date_creation}
+      </p>
+      <p class="collecTitle">
+        <a href="{$col.U_VIEW}" rel="nofollow"><b>{$col.name}</b></a> 
+        <i>{'%d images'|@translate|@sprintf:$col.nb_images}</i>
+      </p>
+      <p class="collecActions">
+        <a href="{$col.U_EDIT}" rel="nofollow">{'Edit'|@translate}</a> |
+        <a href="{$col.U_DELETE}" onClick="return confirm('{'Are you sure?'|@translate}');" rel="nofollow">{'delete'|@translate}</a>
+        {if not $col.active}| <a href="{$col.U_ACTIVE}" rel="nofollow">{'set active'|@translate}</a>{/if}
+      </p>
+    </li>
+  {/foreach}
+  </ul>
+</fieldset>
+{/if}
+
+</div>{* <!-- content --> *}
Index: /extensions/UserCollections/template/menublock.tpl
===================================================================
--- /extensions/UserCollections/template/menublock.tpl	(revision 16591)
+++ /extensions/UserCollections/template/menublock.tpl	(revision 16591)
@@ -0,0 +1,10 @@
+<dt>{$block->get_title()}</dt>
+<dd>
+  {'Current collection:'|@translate} <b>{$block->data.current.NAME}</b>, {'%d images'|@translate|@sprintf:$block->data.current.NB_IMAGES}
+	<ul>{strip}
+		{foreach from=$block->data.links item=link}
+		<li><a href="{$link.URL}" title="{$link.TITLE}" rel="nofollow">{$link.NAME}</a></li>
+		{/foreach}
+	{/strip}</ul>
+  <a href="{$block->data.U_LIST}" rel="nofollow">{'See all my collections'|@translate}</a>
+</dd>
Index: /extensions/UserCollections/template/style.css
===================================================================
--- /extensions/UserCollections/template/style.css	(revision 16591)
+++ /extensions/UserCollections/template/style.css	(revision 16591)
@@ -0,0 +1,155 @@
+#colProperties {}
+  #colProperties p {
+    text-align:left;
+    margin:2px 0;
+  }
+  #colProperties p.title {
+    font-weight:bold;
+  }
+  #colProperties p:not(.title) {
+    margin-bottom:10px;
+  }
+  
+#publicURL {}
+  #publicURL .url {
+    display:inline-block;
+    position:relative;
+    font-family:monospace;
+    font-size:12px;
+    background:#fff;
+    color:#666;
+    padding:3px 10px;
+    border:1px solid #999;
+    border-radius:0 3px 3px 0;
+  }
+  #publicURL .button {
+    display:inline-block;
+    background:#e7e7e7 url('link.png') center center no-repeat;
+    width:25px;
+    height:20px;
+    color:#666;
+    border:1px solid #999;
+    border-right:none;
+    border-radius:3px 0 0 3px;
+  }
+  #publicURL .confirm {
+    font-weight:bold;
+    margin-left:5px;
+  }
+  
+.collecList {
+  list-style:none;
+  padding:0;
+  margin:0;
+}
+  .collecList li {
+    height:35px;
+    padding:5px 10px;
+    margin:4px 0;
+    background:#444;
+    border-radius:5px;
+  }
+    .collecList li.active {
+      background:#555;
+      border:1px solid #999;
+    }
+  .collecList p {
+    margin:0;
+  }
+    .collecList .collecDate {
+      float:right;
+      font-size:0.9em;
+    }
+    .collecList .collecActions { 
+      margin-top:2px;
+      display:none;
+    }
+    .collecList li:hover .collecActions { 
+      display:block;
+    }
+  
+  
+/* TipTip CSS - Version 1.2 */
+#tiptip_holder {
+	display: none;
+	position: absolute;
+	top: 0;
+	left: 0;
+	z-index: 99999;
+}
+#tiptip_holder.tip_top {
+	padding-bottom: 5px;
+}
+#tiptip_holder.tip_bottom {
+	padding-top: 5px;
+}
+#tiptip_holder.tip_right {
+	padding-left: 5px;
+}
+#tiptip_holder.tip_left {
+	padding-right: 5px;
+}
+#tiptip_content {
+	font-size: 11px;
+	color: #fff;
+	text-shadow: 0 0 2px #000;
+	padding: 4px 8px;
+	border: 1px solid rgba(255,255,255,0.25);
+	background-color: rgb(25,25,25);
+	background-color: rgba(25,25,25,0.92);
+	background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, from(transparent), to(#000));
+	border-radius: 3px;
+	-webkit-border-radius: 3px;
+	-moz-border-radius: 3px;
+	box-shadow: 0 0 3px #555;
+	-webkit-box-shadow: 0 0 3px #555;
+	-moz-box-shadow: 0 0 3px #555;
+}
+#tiptip_arrow, #tiptip_arrow_inner {
+	position: absolute;
+	border-color: transparent;
+	border-style: solid;
+	border-width: 6px;
+	height: 0;
+	width: 0;
+}
+#tiptip_holder.tip_top #tiptip_arrow {
+	border-top-color: #fff;
+	border-top-color: rgba(255,255,255,0.35);
+}
+#tiptip_holder.tip_bottom #tiptip_arrow {
+	border-bottom-color: #fff;
+	border-bottom-color: rgba(255,255,255,0.35);
+}
+#tiptip_holder.tip_right #tiptip_arrow {
+	border-right-color: #fff;
+	border-right-color: rgba(255,255,255,0.35);
+}
+#tiptip_holder.tip_left #tiptip_arrow {
+	border-left-color: #fff;
+	border-left-color: rgba(255,255,255,0.35);
+}
+#tiptip_holder.tip_top #tiptip_arrow_inner {
+	margin-top: -7px;
+	margin-left: -6px;
+	border-top-color: rgb(25,25,25);
+	border-top-color: rgba(25,25,25,0.92);
+}
+#tiptip_holder.tip_bottom #tiptip_arrow_inner {
+	margin-top: -5px;
+	margin-left: -6px;
+	border-bottom-color: rgb(25,25,25);
+	border-bottom-color: rgba(25,25,25,0.92);
+}
+#tiptip_holder.tip_right #tiptip_arrow_inner {
+	margin-top: -6px;
+	margin-left: -5px;
+	border-right-color: rgb(25,25,25);
+	border-right-color: rgba(25,25,25,0.92);
+}
+#tiptip_holder.tip_left #tiptip_arrow_inner {
+	margin-top: -6px;
+	margin-left: -7px;
+	border-left-color: rgb(25,25,25);
+	border-left-color: rgba(25,25,25,0.92);
+}
Index: /extensions/UserCollections/template/view.tpl
===================================================================
--- /extensions/UserCollections/template/view.tpl	(revision 16591)
+++ /extensions/UserCollections/template/view.tpl	(revision 16591)
@@ -0,0 +1,42 @@
+{combine_css path=$USER_COLLEC_PATH|@cat:"template/style.css"}
+
+{$MENUBAR}
+
+<div id="content" class="content{if isset($MENUBAR)} contentWithMenu{/if}">
+<div class="titrePage{if isset($chronology.TITLE)} calendarTitleBar{/if}">
+  <ul class="categoryActions">
+  {if !empty($COLLECTION_ACTIONS)}{$COLLECTION_ACTIONS}{/if}
+  </ul>
+  <h2>{$TITLE}</h2>
+</div>{* <!-- titrePage --> *}
+
+{if isset($errors) or not empty($infos)}
+{include file='infos_errors.tpl'}
+{/if}
+
+{if $collection}
+<fieldset id="colProperties">
+  <legend>{'Properties'|@translate}</legend>
+  
+  <p class="title">{'Name'|@translate}</p>
+  <p>{$collection.NAME}</p>
+  <p class="title">{'Owner'|@translate}</p>
+  <p>{$OWNER}</p>
+  <p class="title">{'Creation date'|@translate}</p>
+  <p>{$collection.DATE_CREATION}</p>
+</fieldset>
+</form>
+{/if}
+
+
+{if !empty($THUMBNAILS)}
+<ul class="thumbnails" id="thumbnails">
+{$THUMBNAILS}
+</ul>
+{/if}
+
+{if !empty($navbar)}{include file='navigation_bar.tpl'|@get_extent:'navbar'}{/if}
+
+{if $U_LIST}<p style="text-align:center;font-weight:bold;margin:20px;"><a href="{$U_LIST}" rel="nofollow">{'Return to collections list'|@translate}</a></p>{/if}
+
+</div>{* <!-- content --> *}
