Index: /extensions/virtualAutoGrant/VAG_admin.php
===================================================================
--- /extensions/virtualAutoGrant/VAG_admin.php	(revision 6610)
+++ /extensions/virtualAutoGrant/VAG_admin.php	(revision 6610)
@@ -0,0 +1,63 @@
+<?php
+/* Configuration of Panoramas */
+if (!defined('PHPWG_ROOT_PATH')) die('Hacking attempt!');
+if (!defined('IN_ADMIN') or !IN_ADMIN) die('Hacking attempt!');
+load_language('plugin.lang', VAG_PATH);
+
+global $conf, $template, $user;
+$errors = array();
+$infos = array();
+
+	// '' => 1,
+	// 'set_private_by_API' => 1,
+	// 'grant_to_creator' => 1,
+	// 'grant_to_webmaster' => 1,
+	// 'set_who_can_see' => 1,
+	// 'webmaster_set_who_can_see' => 1,
+	// 'ignore_who_can_see_on_private' => 1,
+	// 'Dir' => VAG_DIR,
+	// 'Path' => VAG_PATH,
+	// 'Ver' => VAG_VER,
+$vag = & $conf['virtual_AutoGrant'];
+
+$sub = ( isset($_POST['submit']) ) ? true : false;
+
+if ( $sub ) {
+  $nsp = array_merge($vag, $_POST);
+	if ( $nsp['set_private'] == 1 and $nsp['set_private_by_API'] == 0 ) {
+    $nsp['set_private_by_API'] = 1;
+    array_push($infos, l10n('New virtual categories from external API will be forced to "private" due to previous choice.'));
+  }
+  if ( $user['id'] != $conf['webmaster_id'] and $nsp['grant_to_webmaster'] != $vag['grant_to_webmaster']) {
+    $nsp['grant_to_webmaster'] = $vag['grant_to_webmaster'];
+    array_push($infos, l10n('Grant automatically the default webmaster has been reset to its previous value.'));
+  }
+	// if ( count($errors) > 0 )
+	// array_push($errors, l10n('Your configuration is NOT saved due to above reasons.'));
+  if ( !is_webmaster() and count($errors) == 0 )
+    array_push($infos, l10n('You are not authorized to change this configuration (Webmaster only).'));
+  if ( is_webmaster() and count($errors) == 0 )
+  {
+    $nsp = array_merge( $vag, array_intersect_key($nsp, $vag) );
+    // var_dump($nsp);
+    $confvag = serialize($nsp);
+    conf_update_param('virtual_AutoGrant', $confvag);
+   	array_push($infos, l10n('Your configuration is saved.'));
+  }
+  $vag = $nsp;
+}
+$template->set_filenames( array('VAG_admin' => dirname(__FILE__).'/template/VAG_admin.tpl') );
+// foreach ($vag as $k => & $v) {
+  // if (is_string($v)) $vag[$k] = htmlspecialchars($v, ENT_QUOTES, 'utf-8');
+  // else $vag[$k] = $v;
+// }
+// if (count($errors) != 0) $template->assign('errors', $errors);
+if (count($infos) != 0) $template->assign('infos', $infos);
+$vag = array_merge( $vag, array(
+	'Dir' => VAG_DIR,
+	'Path' => embellish_url($template->get_template_vars('ROOT_URL').VAG_PATH),
+	'Ver' => VAG_VER,
+  ));
+$template->assign( 'VAG', $vag );
+$template->assign_var_from_handle('ADMIN_CONTENT', 'VAG_admin');
+?>
Index: /extensions/virtualAutoGrant/VAG_default.php
===================================================================
--- /extensions/virtualAutoGrant/VAG_default.php	(revision 6610)
+++ /extensions/virtualAutoGrant/VAG_default.php	(revision 6610)
@@ -0,0 +1,16 @@
+<?php
+  $default = array(
+	'set_private' => 1,
+	'set_private_by_API' => 1,
+	'grant_to_creator' => 1,
+	'grant_to_webmaster' => 1,
+	'set_who_can_see' => 1,
+	'webmaster_set_who_can_see' => 1,
+	'ignore_who_can_see_on_private' => 1,
+	'Dir' => VAG_DIR,
+	'Path' => VAG_PATH,
+	'Ver' => VAG_VER,
+	);
+  if (!isset($conf['virtual_AutoGrant'])) $conf['virtual_AutoGrant'] = $default;
+  else $conf['virtual_AutoGrant'] = array_merge( $default, unserialize($conf['virtual_AutoGrant']));
+?>
Index: /extensions/virtualAutoGrant/css/VAG_admin.css
===================================================================
--- /extensions/virtualAutoGrant/css/VAG_admin.css	(revision 6610)
+++ /extensions/virtualAutoGrant/css/VAG_admin.css	(revision 6610)
@@ -0,0 +1,18 @@
+#VAG_Config td.label  {
+	padding:2px 10px;
+	text-align:right;
+}
+input[type="radio"] {
+	width:20px;
+}
+.infos, .errors {
+  background-color:transparent;
+}
+.clear fieldset#VAG_Config {
+  background: url(../images/Locker_clear_bg.png) scroll no-repeat 20px 50% transparent;
+  padding: 0;
+}
+.roma fieldset#VAG_Config {
+  background: url(../images/Locker_roma_bg.png) scroll no-repeat 20px 50% transparent;
+  padding: 0;
+}
Index: /extensions/virtualAutoGrant/language/en_UK/plugin.lang.php
===================================================================
--- /extensions/virtualAutoGrant/language/en_UK/plugin.lang.php	(revision 6610)
+++ /extensions/virtualAutoGrant/language/en_UK/plugin.lang.php	(revision 6610)
@@ -0,0 +1,16 @@
+<?php
+$lang['Virtual AutoGrant configuration'] = 'Virtual AutoGrant configuration';
+$lang['New virtual categories will be assumed private, access granted to creator and webmaster and/or uploaded pictures will have "Who can see" set to creator privacy level'] 
+    = 'New virtual categories will be assumed private, access granted to creator and webmaster and/or uploaded pictures will have "Who can see" set to creator privacy level';
+
+$lang['All new virtual categories will be set private'] = 'All new virtual categories will be set private';
+$lang['Categories created by the Piwigo API will be set private'] = 'Categories created by the Piwigo API will be set private';
+$lang['Grant access to creator'] = 'Grant access to creator';
+$lang['Grant access to default webmaster'] = 'Grant access to default webmaster';
+
+$lang['Force "Who can see" at the creator privacy level'] = 'Force "Who can see" at the creator privacy level';
+$lang['"Who can see" is not forced for private categories'] = '"Who can see" is not forced for private categories';
+$lang['"Who can see" is free on webmasters uploads'] = '"Who can see" is free on webmasters uploads';
+
+$lang['Only the default webmaster can change this option.'] = 'Only the default webmaster can change this option.';
+?>
Index: /extensions/virtualAutoGrant/language/fr_FR/plugin.lang.php
===================================================================
--- /extensions/virtualAutoGrant/language/fr_FR/plugin.lang.php	(revision 6610)
+++ /extensions/virtualAutoGrant/language/fr_FR/plugin.lang.php	(revision 6610)
@@ -0,0 +1,18 @@
+<?php
+$lang['On'] = 'Oui, si possible';
+$lang['Off'] = 'Non, en principe';
+$lang['Virtual AutoGrant configuration'] = 'Configuration de Virtual';
+$lang['New virtual categories will be assumed private, access granted to creator and webmaster and/or uploaded pictures will have "Who can see" set to creator privacy level'] 
+    = 'Les nouvelles catégories virtuelles seront privatives, l\'accès attribué au créateur et au webmaster,<br/> et/ou les images ajoutées auront le "Qui peut voir" au niveau de confidentialité du créateur';
+
+$lang['All new virtual categories will be set private'] = 'Toute nouvelle catégorie virtuelle sera privative';
+$lang['Categories created by the Piwigo API will be set private'] = 'Les categories crées via l\'API de Piwigo seront privatives';
+$lang['Grant access to creator'] = 'L\'accès sera attribué au créateur';
+$lang['Grant access to default webmaster'] = 'L\'accès sera attribué au webmaster';
+
+$lang['Force "Who can see" at the creator privacy level'] = 'Force le "Qui peut voir" au niveau de confidentialité du créateur';
+$lang['"Who can see" is not forced for private categories'] = '"Qui peut voir" n\'est pas forcé en cas de categories privées';
+$lang['"Who can see" is free on webmasters uploads'] = '"Qui peut voir" est libre pour les chargements du webmaster';
+
+$lang['Only the default webmaster can change this option.'] = 'Uniquement le webmaster par défaut peut modifier cette option.';
+?>
Index: /extensions/virtualAutoGrant/template/VAG_admin.tpl
===================================================================
--- /extensions/virtualAutoGrant/template/VAG_admin.tpl	(revision 6610)
+++ /extensions/virtualAutoGrant/template/VAG_admin.tpl	(revision 6610)
@@ -0,0 +1,82 @@
+{html_head}
+<link rel="stylesheet" type="text/css" href="{$VAG.Path}css/VAG_admin.css">
+{/html_head}
+<div class="titrePage">
+  <h2>Virtual AutoGrant [{$VAG.Ver}]</h2>
+</div>
+<p>
+
+{'New categories will be assumed private, access granted to creator and webmaster and/or uploaded pictures will have "Who can see" set to creator privacy level'|@translate}
+
+</p>
+<form method="post" action="" class="general">
+ <fieldset id="VAG_Config">
+  <legend>{'Virtual AutoGrant configuration'|@translate}</legend><br/>
+  <table id="table">
+   <tr>
+    <td class="label">{'All new virtual categories will be set private'|@translate}</td>
+	<td>
+		<input type="radio" value="1"  name="set_private" {if ($VAG.set_private)}  checked="checked" {/if}/>{'On'|@translate}
+		<input type="radio" value="0" name="set_private" {if (!$VAG.set_private)} checked="checked" {/if}/>{'Off'|@translate}
+	</td>
+   </tr>
+   <tr>
+    <td class="label">{'Categories created by the Piwigo API will be set private'|@translate}</td>
+	<td>
+		<input type="radio" value="1"  name="set_private_by_API" {if ($VAG.set_private_by_API)}  checked="checked" {/if}/>{'On'|@translate}
+		<input type="radio" value="0" name="set_private_by_API" {if (!$VAG.set_private_by_API)} checked="checked" {/if}/>{'Off'|@translate}
+	</td>
+   </tr>
+   <tr>
+    <td class="label">{'Grant access to creator'|@translate}</td>
+	<td>
+		<input type="radio" value="1"  name="grant_to_creator" {if ($VAG.grant_to_creator)}  checked="checked" {/if}/>{'On'|@translate}
+		<input type="radio" value="0" name="grant_to_creator" {if (!$VAG.grant_to_creator)} checked="checked" {/if}/>{'Off'|@translate}
+	</td>
+   </tr>
+   <tr>
+    <td class="label">{'Grant access to default webmaster'|@translate}</td>
+	<td>
+		<input type="radio" value="1"  name="grant_to_webmaster" {if ($VAG.grant_to_webmaster)}  checked="checked" {/if}/>{'On'|@translate}
+		<input type="radio" value="0" name="grant_to_webmaster" {if (!$VAG.grant_to_webmaster)} checked="checked" {/if}/>{'Off'|@translate} (*)
+	</td>
+   </tr>
+   <tr>
+    <td>&nbsp;</td>
+   </tr>
+   <tr>
+    <td class="label">{'Force "Who can see" at the creator privacy level'|@translate}</td>
+	<td>
+		<input type="radio" value="1"  name="set_who_can_see" {if ($VAG.set_who_can_see)}  checked="checked" {/if}/>{'On'|@translate}
+		<input type="radio" value="0" name="set_who_can_see" {if (!$VAG.set_who_can_see)} checked="checked" {/if}/>{'Off'|@translate}
+	</td>
+   </tr>
+   <tr>
+    <td class="label">{'"Who can see" is free on webmasters uploads'|@translate}</td>
+	<td>
+		<input type="radio" value="1"  name="webmaster_set_who_can_see" {if ($VAG.webmaster_set_who_can_see)}  checked="checked" {/if}/>{'On'|@translate}
+		<input type="radio" value="0" name="webmaster_set_who_can_see" {if (!$VAG.webmaster_set_who_can_see)} checked="checked" {/if}/>{'Off'|@translate}
+	</td>
+   </tr>
+   <tr>
+    <td class="label">{'"Who can see" is not forced for private categories'|@translate}</td>
+	<td>
+		<input type="radio" value="1"  name="ignore_who_can_see_on_private" {if ($VAG.ignore_who_can_see_on_private)}  checked="checked" {/if}/>{'On'|@translate}
+		<input type="radio" value="0" name="ignore_who_can_see_on_private" {if (!$VAG.ignore_who_can_see_on_private)} checked="checked" {/if}/>{'Off'|@translate}
+	</td>
+   </tr>
+  </table>
+  <p>(*) : {'Only the default webmaster can change this option.'|@translate}<br/><br/></p>
+  </fieldset>
+
+ <p><input type="submit" value="{'Submit'|@translate}" name="submit" /></p>
+</form>
+{html_head}
+<script type="text/javascript">
+jQuery(document).ready(function() {ldelim}
+  jQuery('#theAdminPage #the_page').addClass('{$themeconf.name}');
+	jQuery(".infos").fadeOut(800).fadeIn(1200).fadeOut(400).fadeIn(800).fadeOut(400);
+	jQuery(".errors").fadeOut(200).fadeIn(200).fadeOut(300).fadeIn(300).fadeOut(400).fadeIn(400); 
+});
+</script>
+{/html_head}
Index: /extensions/virtualAutoGrant/virtual_categories_granted_to_creator.php
===================================================================
--- /extensions/virtualAutoGrant/virtual_categories_granted_to_creator.php	(revision 6609)
+++ /extensions/virtualAutoGrant/virtual_categories_granted_to_creator.php	(revision 6610)
@@ -2,25 +2,104 @@
 /* Virtual AutoGrant */
 if (!defined('PHPWG_ROOT_PATH') or !defined('VAG_DIR')) die('Hacking attempt!');
-if ( !function_exists( 'virtual_categories_granted_to_creator' ) ) {
-	add_event_handler('invalidate_user_cache', 'virtual_categories_granted_to_creator', 20);
+global $conf;
+include_once( VAG_PATH . 'VAG_default.php');
+$vag = & $conf['virtual_AutoGrant'];
 
-	function  virtual_categories_granted_to_creator($full) {
-    if ( !function_exists( 'ws_categories_add' ) ) return false;
-	  global $user, $conf;
+// General case for set private (exception synchronisation (categories are not virtual ones))
+if ( $conf['newcat_default_status'] == 'public' and $vag['set_private'] == 1 
+    and defined('IN_ADMIN') and IN_ADMIN and !function_exists( 'VAG_set_private' ) ) {
+  add_event_handler('get_admin_plugin_menu_links', 'VAG_set_private');
+  function VAG_set_private($menu) {
+    global $page;
+    if ( isset($page['page']) and $page['page'] != 'site_manager' )
+      $conf['newcat_default_status'] = 'private';
+    return $menu;
+  }
+} 
+// General case for set public (exception synchronisation (categories are not virtual ones))
+if ( $conf['newcat_default_status'] == 'private' and $vag['set_private'] == 0 
+    and defined('IN_ADMIN') and IN_ADMIN and !function_exists( 'VAG_set_public' ) ) {
+  add_event_handler('get_admin_plugin_menu_links', 'VAG_set_public');
+  function VAG_set_public($menu) {
+    global $page;
+    if ( isset($page['page']) and $page['page'] != 'site_manager' )
+      $conf['newcat_default_status'] = 'public';
+    return $menu;
+  }
+} 
+// General case for grant to someone
+// Don't grant on physical categories 
+if ( ($vag['grant_to_creator'] == 1 or $vag['grant_to_webmaster'] == 1)
+    and defined('IN_ADMIN') and IN_ADMIN and !function_exists( 'VAG_grant_to_prepare' ) ) {
+		add_event_handler('get_admin_plugin_menu_links', 'VAG_grant_to_prepare');
+  function VAG_grant_to_prepare($menu) {
+    global $conf, $page, $vag;
+    if ( !isset($page['page']) or $page['page'] == 'site_manager' ) return false;
+    list($max_id) = pwg_db_fetch_row(pwg_query('SELECT MAX(id) FROM '.CATEGORIES_TABLE . ';'));
+    $vag['lastcat before'] == $max_id;
+    add_event_handler('loc_end_admin', 'VAG_grant_to_somebody');
+    return $menu;
+  }
+  if ( !function_exists( 'VAG_grant_to_somebody' ) ) {
+    function VAG_grant_to_somebody() {
+      global $conf, $vag, $user;
+      if ( !isset($vag['lastcat before']) ) return false;
+      list($new_id) = pwg_db_fetch_row(pwg_query('SELECT MAX(id) FROM '.CATEGORIES_TABLE
+      . ' WHERE id > ' . $vag['lastcat before'] . ' AND site_id IS NULL;'));
+      if ( empty($newid) ) return false;
+      if ( $vag['grant_to_creator'] == 1 or $vag['grant_to_webmaster'] == 1 ) {
+        if ( $vag['grant_to_creator'] == 1 ) $insert[] = array('user_id' => $user['id'], 'cat_id' => $newid);
+        if ( $user['id'] != $conf['webmaster_id'] and $vag['grant_to_webmaster'] == 1 )
+          $insert[] = array('user_id' => $conf['webmaster_id'], 'cat_id' => $newid);
+        mass_inserts(USER_ACCESS_TABLE, array('user_id','cat_id'), $insert);
+      }
+    }
+  }
+} 
+
+// API cases : Just do it (even in Admin Photos Add case or other plugins cases)  
+if ( !function_exists( 'VAG_set_private_by_API' ) ) {
+	add_event_handler('invalidate_user_cache', 'VAG_set_private_by_API', 20);
+
+	function  VAG_set_private_by_API($full) {
+    if ( !function_exists( 'ws_categories_add' ) ) return false; // That isn't an API request
+	  global $user, $conf, $vag;
     if ( $_REQUEST['method'] == 'pwg.categories.add' ) {
       list($inserted_id) = pwg_db_fetch_row(pwg_query('SELECT MAX(id) FROM '.CATEGORIES_TABLE
-      . ' WHERE name = \'' .pwg_db_real_escape_string($_REQUEST['name']) . '\';'));
-      set_cat_status(array($inserted_id), 'private');      
-      $insert[] = array('user_id' => $user['id'], 'cat_id' => $inserted_id);
-      $insert[] = array('user_id' => $conf['webmaster_id'], 'cat_id' => $inserted_id);
-      mass_inserts(USER_ACCESS_TABLE, array('user_id','cat_id'), $insert);
+      . ' WHERE name = \'' .pwg_db_real_escape_string($_REQUEST['name']) . '\' AND site_id IS NULL;'));
+      # Note:  AND site_id IS NULL because synchro could be running in //
+      if ( $vag['set_private_by_API'] == 1 ) set_cat_status(array($inserted_id), 'private');
+        else set_cat_status(array($inserted_id), 'public');
+      if ( ($vag['grant_to_creator'] == 1 or $vag['grant_to_webmaster'] == 1 ) and $vag['set_private_by_API'] == 1 ) {
+        if ( $vag['grant_to_creator'] == 1 ) $insert[] = array('user_id' => $user['id'], 'cat_id' => $inserted_id);
+        if ( $user['id'] != $conf['webmaster_id'] and $vag['grant_to_webmaster'] == 1 )
+          $insert[] = array('user_id' => $conf['webmaster_id'], 'cat_id' => $inserted_id);
+        mass_inserts(USER_ACCESS_TABLE, array('user_id','cat_id'), $insert);
+      }
+      $vag['lastcat before'] = $inserted_id; # Admin Photos Add does not need to redo the job
     }
-    if ( $_REQUEST['method'] == 'pwg.images.add' and isset($_REQUEST['original_sum']) ) {
+    // "Who can see" management ( only for API, Synchro or old HTTP management on gallery side are ignored )
+    if ( $_REQUEST['method'] == 'pwg.images.add' and isset($_REQUEST['original_sum']) 
+        and $vag['set_who_can_see'] == 1 ) {
       # image to update
       if ('md5sum' == $conf['uniqueness_mode']) $where_clause = "md5sum = '".pwg_db_real_escape_string($_REQUEST['original_sum'])."'";
       if ('filename' == $conf['uniqueness_mode'] and isset($_REQUEST['original_filename']) ) 
           $where_clause = "file = '".pwg_db_real_escape_string($_REQUEST['original_filename'])."'";
-      if ( !isset($where_clause) or is_webmaster() ) return false;
-      if ( $user['level'] == $conf['available_permission_levels'][0] ) return false;    
+      if ( !isset($where_clause) or (is_webmaster() and $vag['webmaster_set_who_can_see'] == 1) ) return false;
+      if ( $user['level'] == $conf['available_permission_levels'][0] ) return false;   // Non privacy level won't force it
+      if (!isset($_REQUEST['categories'])) return false;
+      $tokens = explode(';', pwg_db_real_escape_string($_REQUEST['categories']));
+      $cat_ids = array();
+      foreach ($tokens as $token) {
+        list($cat_id) = explode(',', $token);
+        if (!preg_match('/^\d+$/', $cat_id)) continue;
+        array_push($cat_ids, $cat_id);
+      }
+      $cat_ids = array_unique($cat_ids);
+      if (count($cat_ids) != 0) $w = ' AND id IN ('.implode(',', $cat_ids).')'; else $w ='';
+      list($count_public_cat) = pwg_db_fetch_row(pwg_query('SELECT count(*) FROM '.CATEGORIES_TABLE
+      . ' WHERE status = \'public\' ' . $w . ' AND site_id IS NULL;'));
+      // No public category = all are private => maybe we can ignore "Who can see"
+      if ( $count_public_cat == 0 and $vag['ignore_who_can_see_on_private'] == 1 ) return false;
       $r = pwg_query('UPDATE '.IMAGES_TABLE.' SET level = ' . $user['level'] . ' WHERE level < '. $user['level'] 
           .' AND ' . $where_clause . ';');
@@ -28,3 +107,16 @@
 	}
 }
+// Configuration menu
+if ( !function_exists( 'VAG_admin_menu' ) ) {
+	if ( defined('IN_ADMIN') and IN_ADMIN ) {
+		add_event_handler('get_admin_plugin_menu_links', 'VAG_admin_menu');
+    function VAG_admin_menu($menu) {
+        array_push($menu, array(
+                'NAME' => 'Virtual AutoGrant',
+                'URL' => get_admin_plugin_menu_link(dirname(__FILE__).'/VAG_admin.php')
+        ));
+        return $menu;
+    }
+  }
+}
 ?>
