Index: trunk/admin/cat_list.php
===================================================================
--- trunk/admin/cat_list.php	(revision 646)
+++ trunk/admin/cat_list.php	(revision 647)
@@ -328,7 +328,16 @@
 }
 
+if (count($categories) > 0)
+{
+  $next_rank = max(array_keys($categories)) + 1;
+}
+else
+{
+  $next_rank = 1;
+}
+
 $template->assign_vars(array(
   'CATEGORIES_NAV'=>$navigation,
-  'NEXT_RANK'=>max(array_keys($categories))+1,
+  'NEXT_RANK'=>$next_rank,
   'F_ACTION'=>$form_action,
   
@@ -368,10 +377,13 @@
 // +-----------------------------------------------------------------------+
 $ranks = array();
-foreach ($categories as $category)
-{
-  $ranks[$category['id']] = $category['rank'];
-}
-
-$query = '
+
+if (count($categories) > 0)
+{
+  foreach ($categories as $category)
+  {
+    $ranks[$category['id']] = $category['rank'];
+  }
+
+  $query = '
 SELECT id_uppercat, COUNT(*) AS nb_subcats
   FROM '. CATEGORIES_TABLE.'
@@ -379,8 +391,10 @@
   GROUP BY id_uppercat
 ;';
-$result = pwg_query($query);
-while ($row = mysql_fetch_array($result))
-{
-  $categories[$ranks[$row['id_uppercat']]]['nb_subcats'] = $row['nb_subcats'];
+  $result = pwg_query($query);
+  while ($row = mysql_fetch_array($result))
+  {
+    $categories[$ranks[$row['id_uppercat']]]['nb_subcats']
+      = $row['nb_subcats'];
+  }
 }
 
Index: trunk/admin/include/functions.php
===================================================================
--- trunk/admin/include/functions.php	(revision 646)
+++ trunk/admin/include/functions.php	(revision 647)
@@ -392,53 +392,4 @@
 }
 
-// The check_favorites function deletes all the favorites of a user if he is
-// not allowed to see them (the category or an upper category is restricted
-// or invisible)
-function check_favorites( $user_id )
-{
-  $query = 'SELECT status,forbidden_categories';
-  $query.= ' FROM '.USERS_TABLE;
-  $query.= ' WHERE id = '.$user_id;
-  $query.= ';';
-  $row = mysql_fetch_array( pwg_query( $query ) );
-  $status = $row['status'];
-  // retrieving all the restricted categories for this user
-  if ( isset( $row['forbidden_categories'] ) )
-    $restricted_cat = explode( ',', $row['forbidden_categories'] );
-  else
-    $restricted_cat = array();
-  // retrieving all the favorites for this user and comparing their
-  // categories to the restricted categories
-  $query = 'SELECT image_id FROM '.FAVORITES_TABLE;
-  $query.= ' WHERE user_id = '.$user_id;
-  $query.= ';';
-  $result = pwg_query ( $query );
-  while ( $row = mysql_fetch_array( $result ) )
-  {
-    // for each picture, we have to check all the categories it belongs
-    // to. Indeed if a picture belongs to category_1 and category_2 and that
-    // category_2 is not restricted to the user, he can have the picture as
-    // favorite.
-    $query = 'SELECT DISTINCT(category_id) as category_id';
-    $query.= ' FROM '.PREFIX_TABLE.'image_category';
-    $query.= ' WHERE image_id = '.$row['image_id'];
-    $query.= ';';
-    $picture_result = pwg_query( $query );
-    $picture_cat = array();
-    while ( $picture_row = mysql_fetch_array( $picture_result ) )
-    {
-      array_push( $picture_cat, $picture_row['category_id'] );
-    }
-    if ( count( array_diff( $picture_cat, $restricted_cat ) ) == 0 )
-    {
-      $query = 'DELETE FROM '.FAVORITES_TABLE;
-      $query.= ' WHERE image_id = '.$row['image_id'];
-      $query.= ' AND user_id = '.$user_id;
-      $query.= ';';
-      pwg_query( $query );
-    }
-  }
-}
-
 /**
  * updates calculated informations about a set of categories : date_last and
@@ -480,5 +431,5 @@
     {
       $query.= '
-  WHERE id IN ('.implode(',', $ids).')';
+  WHERE id IN ('.wordwrap(implode(', ', $ids), 80, "\n").')';
     }
   }
@@ -503,5 +454,5 @@
        MAX(date_available) AS date_last
   FROM '.IMAGES_TABLE.' INNER JOIN '.IMAGE_CATEGORY_TABLE.' ON id = image_id
-  WHERE category_id IN ('.implode(',', $cat_ids).')
+  WHERE category_id IN ('.wordwrap(implode(', ', $cat_ids), 80, "\n").')
   GROUP BY category_id
 ;';
@@ -543,5 +494,5 @@
     ON id = category_id AND representative_picture_id = image_id
   WHERE representative_picture_id IS NOT NULL
-    AND id IN ('.implode(',', $cat_ids).')
+    AND id IN ('.wordwrap(implode(', ', $cat_ids), 80, "\n").')
     AND category_id IS NULL
 ;';
Index: trunk/admin/infos_images.php
===================================================================
--- trunk/admin/infos_images.php	(revision 646)
+++ trunk/admin/infos_images.php	(revision 647)
@@ -61,6 +61,4 @@
     }
 
-    $associate = false;
-    
     $query = 'SELECT id,file FROM '.IMAGES_TABLE;
     $query.= ' INNER JOIN '.IMAGE_CATEGORY_TABLE.' ON id = image_id';
@@ -112,5 +110,7 @@
       }
       // add link to another category
-      if (isset($_POST['check-'.$row['id']]) and count($errors) == 0)
+      if (isset($_POST['check-'.$row['id']])
+          and isset($_POST['associate'])
+          and $_POST['associate'] != '')
       {
         $query = 'INSERT INTO '.IMAGE_CATEGORY_TABLE;
@@ -119,9 +119,10 @@
         $query.= ';';
         pwg_query($query);
-        $associate = true;
-      }
-    }
-    if (isset($_POST['associate'])) update_category($_POST['associate']);
-    if ($associate) synchronize_all_users();
+      }
+    }
+    if (isset($_POST['associate']) and $_POST['associate'] != '')
+    {
+      update_category(array($_POST['associate']));
+    }
 // +-----------------------------------------------------------------------+
 // |                        update general options                         |
@@ -337,25 +338,12 @@
   
   // Virtualy associate a picture to a category
-  //
-  // We only show a List Of Values if the number of categories is less than
-  // $conf['max_LOV_categories']
-  $query = 'SELECT COUNT(id) AS nb_total_categories';
-  $query.= ' FROM '.CATEGORIES_TABLE.';';
-  $row = mysql_fetch_array(pwg_query($query));
-  if ($row['nb_total_categories'] < $conf['max_LOV_categories'])
-  {
-    /*$vtp->addSession($sub, 'associate_LOV');
-    $page['plain_structure'] = get_plain_structure(true);
-    $structure = create_structure('', array());
-    display_categories($structure, '&nbsp;');
-    $vtp->closeSession($sub, 'associate_LOV');*/
-  }
-  // else, we only display a small text field, we suppose the administrator
-  // knows the id of its category
-  else
-  {
-    //$vtp->addSession($sub, 'associate_text');
-    //$vtp->closeSession($sub, 'associate_text');
-  }
+  $query = '
+SELECT id,name,uppercats,global_rank
+  FROM '.CATEGORIES_TABLE.'
+;';
+  display_select_cat_wrapper($query,
+                             array(),
+                             'associate_option',
+                             true);
 }
 //----------------------------------------------------------- sending html code
Index: trunk/include/config.inc.php
===================================================================
--- trunk/include/config.inc.php	(revision 646)
+++ trunk/include/config.inc.php	(revision 647)
@@ -191,6 +191,6 @@
 $conf['level_separator'] = ' / ';
 
-// paginate_pages_around : on paginate navigation bar, on many pages display
-// before and after the current page ?
+// paginate_pages_around : on paginate navigation bar, how many pages
+// display before and after the current page ?
 $conf['paginate_pages_around'] = 2;
 ?>
Index: trunk/include/functions_category.inc.php
===================================================================
--- trunk/include/functions_category.inc.php	(revision 646)
+++ trunk/include/functions_category.inc.php	(revision 647)
@@ -562,4 +562,6 @@
       else if ( $page['cat'] == 'fav' )
       {
+        check_user_favorites();
+        
         $page['title'] = $lang['favorites'];
 
Index: trunk/include/functions_html.inc.php
===================================================================
--- trunk/include/functions_html.inc.php	(revision 646)
+++ trunk/include/functions_html.inc.php	(revision 647)
@@ -159,9 +159,10 @@
       $navbar.= $lang['next_page'];
     }
+    
+    $navbar.= ' | ';
     // link to last page ?
     if ($cur_page != $maximum)
     {
       $temp_start = ($maximum - 1) * $nb_element_page;
-      $navbar.= ' | ';
       $navbar.= '<a href="';
       $navbar.= add_session_id($url.'&amp;start='.$temp_start);
Index: trunk/include/functions_session.inc.php
===================================================================
--- trunk/include/functions_session.inc.php	(revision 646)
+++ trunk/include/functions_session.inc.php	(revision 647)
@@ -87,14 +87,14 @@
   }
   // 3. inserting session in database
-  $expiration = $session_length + time();
   $query = '
 INSERT INTO '.SESSIONS_TABLE.'
-  (id,user_id,expiration,ip)
+  (id,user_id,expiration)
   VALUES
-  (\''.$generated_id.'\','.$userid.','.$expiration.',
-   \''.$_SERVER['REMOTE_ADDR'].'\')
+  (\''.$generated_id.'\','.$userid.',
+   ADDDATE(NOW(), INTERVAL '.$session_length.' SECOND))
 ;';
   pwg_query($query);
 
+  $expiration = $session_length + time();
   setcookie('id', $generated_id, $expiration, cookie_path());
                 
Index: trunk/include/functions_user.inc.php
===================================================================
--- trunk/include/functions_user.inc.php	(revision 646)
+++ trunk/include/functions_user.inc.php	(revision 647)
@@ -238,3 +238,42 @@
   return ( $row = mysql_fetch_array($result) ) ? $row : false;
 }
+
+/*
+ * deletes favorites of the current user if he's not allowed to see them
+ *
+ * @return void
+ */
+function check_user_favorites()
+{
+  global $user;
+
+  if ($user['forbidden_categories'] == '')
+  {
+    return;
+  }
+  
+  $query = '
+SELECT f.image_id
+  FROM '.FAVORITES_TABLE.' AS f INNER JOIN '.IMAGE_CATEGORY_TABLE.' AS ic
+    ON f.image_id = ic.image_id
+  WHERE f.user_id = '.$user['id'].'
+    AND ic.category_id IN ('.$user['forbidden_categories'].')
+;';
+  $result = pwg_query($query);
+  $elements = array();
+  while ($row = mysql_fetch_array($result))
+  {
+    array_push($elements, $row['image_id']);
+  }
+
+  if (count($elements) > 0)
+  {
+    $query = '
+DELETE FROM '.FAVORITES_TABLE.'
+  WHERE image_id IN ('.implode(',', $elements).')
+    AND user_id = '.$user['id'].'
+;';
+    pwg_query($query);
+  }
+}
 ?>
Index: trunk/include/user.inc.php
===================================================================
--- trunk/include/user.inc.php	(revision 646)
+++ trunk/include/user.inc.php	(revision 647)
@@ -60,5 +60,5 @@
   $page['session_id'] = $session_id;
   $query = '
-SELECT user_id,expiration,ip
+SELECT user_id,expiration,NOW() AS now
   FROM '.SESSIONS_TABLE.'
   WHERE id = \''.$page['session_id'].'\'
@@ -68,20 +68,13 @@
   {
     $row = mysql_fetch_array($result);
-    if (!$user['has_cookie'])
+    if (strnatcmp($row['expiration'], $row['now']) < 0)
     {
-      if ($row['expiration'] < time())
-      {
-        // deletion of the session from the database,
-        // because it is out-of-date
-        $delete_query = 'DELETE FROM '.SESSIONS_TABLE;
-        $delete_query.= " WHERE id = '".$page['session_id']."'";
-        $delete_query.= ';';
-        pwg_query($delete_query);
-      }
-      else if ($_SERVER['REMOTE_ADDR'] == $row['ip'])
-      {
-        $query_user .= ' WHERE id = '.$row['user_id'];
-        $query_done = true;
-      }
+      // deletion of the session from the database, because it is
+      // out-of-date
+      $delete_query = '
+DELETE FROM '.SESSIONS_TABLE.'
+  WHERE id = \''.$page['session_id'].'\'
+;';
+      pwg_query($delete_query);
     }
     else
Index: trunk/install/dbscheme.txt
===================================================================
--- trunk/install/dbscheme.txt	(revision 646)
+++ trunk/install/dbscheme.txt	(revision 647)
@@ -79,6 +79,5 @@
 column:id                        table:sessions       type:varchar                  nullable:N length:255 binary:Y
 column:user_id                   table:sessions       type:smallint                 nullable:N length:5   signed:N
-column:expiration                table:sessions       type:int                      nullable:N length:10  signed:N
-column:ip                        table:sessions       type:varchar                  nullable:N length:255 binary:N
+column:expiration                table:sessions       type:datetime                 nullable:N
 column:id                        table:sites          type:tinyint                  nullable:N length:4   signed:Y
 column:galleries_url             table:sites          type:varchar                  nullable:N length:255 binary:N
@@ -120,5 +119,4 @@
 PK:group_access_pk   table:group_access   column:cat_id
 PK:groups_pk         table:groups         column:id
-PK:history_pk        table:history        column:date
 PK:image_category_pk table:image_category column:image_id
 PK:image_category_pk table:image_category column:category_id
@@ -136,4 +134,5 @@
 
 index:categories_i2     table:categories     column:id_uppercat
+index:history_i1        table:history        column:date
 index:image_category_i1 table:image_category column:image_id
 index:image_category_i2 table:image_category column:category_id
Index: trunk/install/phpwebgallery_structure.sql
===================================================================
--- trunk/install/phpwebgallery_structure.sql	(revision 646)
+++ trunk/install/phpwebgallery_structure.sql	(revision 647)
@@ -171,6 +171,5 @@
   id varchar(255) binary NOT NULL default '',
   user_id smallint(5) unsigned NOT NULL default '0',
-  expiration int(10) unsigned NOT NULL default '0',
-  ip varchar(255) NOT NULL default '',
+  expiration datetime NOT NULL default '0000-00-00 00:00:00',
   PRIMARY KEY  (id)
 ) TYPE=MyISAM;
Index: trunk/language/en_UK.iso-8859-1/admin.lang.php
===================================================================
--- trunk/language/en_UK.iso-8859-1/admin.lang.php	(revision 646)
+++ trunk/language/en_UK.iso-8859-1/admin.lang.php	(revision 647)
@@ -88,4 +88,5 @@
 // Categories
 $lang['cat_security'] = 'Public / Private';
+$lang['cat_options'] = 'Category options';
 $lang['cat_add'] = 'Add a virtual category';
 $lang['cat_virtual'] = 'Virtual category';
@@ -96,5 +97,5 @@
 $lang['editcat_confirm'] = 'Category informations updated successfully.';
 $lang['editcat_perm'] = 'To set permissions for this category, click';
-$lang['editcat_lock_info'] = 'The category and its sub-categories will temporary been disabled for maintenance.'
+$lang['editcat_lock_info'] = 'The category and its sub-categories will temporary been disabled for maintenance.';
 $lang['editcat_uploadable'] = 'Authorize upload';
 $lang['editcat_uploadable_info'] = 'Authorize users to upload files';
Index: trunk/template/default/admin/infos_images.tpl
===================================================================
--- trunk/template/default/admin/infos_images.tpl	(revision 646)
+++ trunk/template/default/admin/infos_images.tpl	(revision 647)
@@ -79,13 +79,11 @@
     <tr>
       <td colspan="7">
-        <img src="./template/default/admin/images/arrow_select.gif" alt="&lt;" />
+        <img src="./template/default/admin/images/arrow_select.gif" alt="&uarr;" />
         {L_INFOS_ASSOCIATE}
-        <!-- BEGIN associate_LOV -->
-        <select name="associate">
-          <!-- BEGIN associate_cat -->
-          <option value="{#value}">{#content}</option>
-          <!-- END associate_cat -->
+        <select style="width:400px" name="associate" size="1">
+          <!-- BEGIN associate_option -->
+          <option {associate_option.SELECTED} value="{associate_option.VALUE}">{associate_option.OPTION}</option>
+          <!-- END category_option -->
         </select>
-        <!-- END associate_LOV -->
       </td>
     </tr>
