Index: /trunk/include/ws_functions.inc.php
===================================================================
--- /trunk/include/ws_functions.inc.php	(revision 25244)
+++ /trunk/include/ws_functions.inc.php	(revision 25245)
@@ -3625,4 +3625,5 @@
 /**
  * API method
+ * Updates users
  * @param mixed[] $params
  *    @option int[] user_id
@@ -3812,3 +3813,208 @@
 }
 
+/**
+ * API method
+ * Returns permissions
+ * @param mixed[] $params
+ *    @option int[] cat_id (optional)
+ *    @option int[] group_id (optional)
+ *    @option int[] user_id (optional)
+ */
+function ws_permissions_getList($params, &$service)
+{
+  $my_params = array_intersect(array_keys($params), array('cat_id','group_id','user_id'));
+  if (count($my_params) > 1)
+  {
+    return new PwgError(WS_ERR_INVALID_PARAM, 'Too many parameters, provide cat_id OR user_id OR group_id');
+  }
+  
+  $cat_filter = '';
+  if (!empty($params['cat_id']))
+  {
+    $cat_filter = 'WHERE cat_id IN('. implode(',', $params['cat_id']) .')';
+  }
+  
+  $perms = array();
+  
+  // direct users
+  $query = '
+SELECT user_id, cat_id
+  FROM '. USER_ACCESS_TABLE .'
+  '. $cat_filter .'
+;';
+  $result = pwg_query($query);
+
+  while ($row = pwg_db_fetch_assoc($result))
+  {
+    if (!isset($perms[ $row['cat_id'] ]))
+    {
+      $perms[ $row['cat_id'] ]['id'] = $row['cat_id'];
+    }
+    $perms[ $row['cat_id'] ]['users'][] = $row['user_id'];
+  }
+  
+  // indirect users
+  $query = '
+SELECT ug.user_id, ga.cat_id
+  FROM '. USER_GROUP_TABLE .' AS ug
+    INNER JOIN '. GROUP_ACCESS_TABLE .' AS ga
+    ON ug.group_id = ga.group_id
+  '. $cat_filter .'
+;';
+  $result = pwg_query($query);
+  
+  while ($row = pwg_db_fetch_assoc($result))
+  {
+    if (!isset($perms[ $row['cat_id'] ]))
+    {
+      $perms[ $row['cat_id'] ]['id'] = $row['cat_id'];
+    }
+    $perms[ $row['cat_id'] ]['users_indirect'][] = $row['user_id'];
+  }
+  
+  // groups
+  $query = '
+SELECT group_id, cat_id
+  FROM '. GROUP_ACCESS_TABLE .'
+  '. $cat_filter .'
+;';
+  $result = pwg_query($query);
+  
+  while ($row = pwg_db_fetch_assoc($result))
+  {
+    if (!isset($perms[ $row['cat_id'] ]))
+    {
+      $perms[ $row['cat_id'] ]['id'] = $row['cat_id'];
+    }
+    $perms[ $row['cat_id'] ]['groups'][] = $row['group_id'];
+  }
+  
+  // filter by group and user
+  foreach ($perms as $cat_id => &$cat)
+  {
+    if (isset($filters['group_id']))
+    {
+      if (empty($cat['groups']) or count(array_intersect($cat['groups'], $params['group_id'])) == 0)
+      {
+        unset($perms[$cat_id]);
+        continue;
+      }
+    }
+    if (isset($filters['user_id']))
+    {
+      if (
+        (empty($cat['users_indirect']) or count(array_intersect($cat['users_indirect'], $params['user_id'])) == 0)
+        and (empty($cat['users']) or count(array_intersect($cat['users'], $params['user_id'])) == 0)
+      ) {
+        unset($perms[$cat_id]);
+        continue;
+      }
+    }
+    
+    $cat['groups'] = !empty($cat['groups']) ? array_unique($cat['groups']) : array();
+    $cat['users'] = !empty($cat['users']) ? array_unique($cat['users']) : array();
+    $cat['users_indirect'] = !empty($cat['users_indirect']) ? array_unique($cat['users_indirect']) : array();
+  }
+  unset($cat);
+
+  return array('categories' => new PwgNamedArray(array_values($perms), 'category', array('id')));
+}
+
+/**
+ * API method
+ * Add permissions
+ * @param mixed[] $params
+ *    @option int[] cat_id
+ *    @option int[] group_id (optional)
+ *    @option int[] user_id (optional)
+ *    @option bool recursive
+ */
+function ws_permissions_add($params, &$service)
+{
+  include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
+  
+  if (!empty($params['group_id']))
+  {
+    $cat_ids = get_uppercat_ids($params['cat_id']);
+    if ($params['recursive'])
+    {
+      $cat_ids = array_merge($cat_ids, get_subcat_ids($params['cat_id']));
+    }
+    
+    $query = '
+SELECT id
+  FROM '.CATEGORIES_TABLE.'
+  WHERE id IN ('.implode(',', $cat_ids).')
+    AND status = \'private\'
+;';
+    $private_cats = array_from_query($query, 'id');
+    
+    $inserts = array();
+    foreach ($private_cats as $cat_id)
+    {
+      foreach ($params['group_id'] as $group_id)
+      {
+        $inserts[] = array(
+          'group_id' => $group_id,
+          'cat_id' => $cat_id
+          );
+      }
+    }
+    
+    mass_inserts(
+      GROUP_ACCESS_TABLE,
+      array('group_id','cat_id'),
+      $inserts,
+      array('ignore'=>true)
+      );
+  }
+  
+  if (!empty($params['user_id']))
+  {
+    if ($params['recursive']) $_POST['apply_on_sub'] = true;
+    add_permission_on_category($params['cat_id'], $params['user_id']);
+  }
+  
+  return $service->invoke('pwg.permissions.getList', array('cat_id'=>$params['cat_id']));
+}
+
+/**
+ * API method
+ * Removes permissions
+ * @param mixed[] $params
+ *    @option int[] cat_id
+ *    @option int[] group_id (optional)
+ *    @option int[] user_id (optional)
+ */
+function ws_permissions_remove($params, &$service)
+{
+  include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
+  
+  $cat_ids = get_subcat_ids($params['cat_id']);
+  
+  if (!empty($params['group_id']))
+  {
+    $query = '
+DELETE
+  FROM '. GROUP_ACCESS_TABLE .'
+  WHERE group_id IN ('. implode(',', $params['group_id']).')
+    AND cat_id IN ('. implode(',', $cat_ids).')
+;';
+    pwg_query($query);
+  }
+  
+  if (!empty($params['user_id']))
+  {
+    $query = '
+DELETE
+  FROM '. USER_ACCESS_TABLE .'
+  WHERE user_id IN ('. implode(',', $params['user_id']) .')
+    AND cat_id IN ('. implode(',', $cat_ids) .')
+;';
+    pwg_query($query);
+  }
+  
+  return $service->invoke('pwg.permissions.getList', array('cat_id'=>$params['cat_id']));
+}
+
 ?>
Index: /trunk/ws.php
===================================================================
--- /trunk/ws.php	(revision 25244)
+++ /trunk/ws.php	(revision 25245)
@@ -883,4 +883,56 @@
       array('admin_only'=>true, 'post_only'=>true)
     );
+    
+  $service->addMethod(
+      'pwg.permissions.getList',
+      'ws_permissions_getList',
+      array(
+        'cat_id' =>     array('flags'=>WS_PARAM_FORCE_ARRAY|WS_PARAM_OPTIONAL,
+                              'type'=>WS_TYPE_ID),
+        'group_id' =>   array('flags'=>WS_PARAM_FORCE_ARRAY|WS_PARAM_OPTIONAL,
+                              'type'=>WS_TYPE_ID),
+        'user_id' =>    array('flags'=>WS_PARAM_FORCE_ARRAY|WS_PARAM_OPTIONAL,
+                              'type'=>WS_TYPE_ID),
+        ),
+      '<b>Admin only.</b> Returns permissions: user ids and group ids having access to each album ; this list can be filterd with "cat_id".
+<br>If "user_id" OR "group_id" is provided it returns a list of album ids the user or group has access to.
+<br>Provide only on parameter!',
+      null,
+      array('admin_only'=>true)
+    );
+    
+  $service->addMethod(
+      'pwg.permissions.add',
+      'ws_permissions_add',
+      array(
+        'cat_id' =>     array('flags'=>WS_PARAM_FORCE_ARRAY,
+                              'type'=>WS_TYPE_ID),
+        'group_id' =>   array('flags'=>WS_PARAM_FORCE_ARRAY|WS_PARAM_OPTIONAL,
+                              'type'=>WS_TYPE_ID),
+        'user_id' =>    array('flags'=>WS_PARAM_FORCE_ARRAY|WS_PARAM_OPTIONAL,
+                              'type'=>WS_TYPE_ID),
+        'recursive' =>  array('default'=>false,
+                              'type'=>WS_TYPE_BOOL),
+        ),
+      '<b>Admin only.</b> Adds permissions to an album.',
+      null,
+      array('admin_only'=>true)
+    );
+    
+  $service->addMethod(
+      'pwg.permissions.remove',
+      'ws_permissions_remove',
+      array(
+        'cat_id' =>   array('flags'=>WS_PARAM_FORCE_ARRAY,
+                            'type'=>WS_TYPE_ID),
+        'group_id' => array('flags'=>WS_PARAM_FORCE_ARRAY|WS_PARAM_OPTIONAL,
+                            'type'=>WS_TYPE_ID),
+        'user_id' =>  array('flags'=>WS_PARAM_FORCE_ARRAY|WS_PARAM_OPTIONAL,
+                            'type'=>WS_TYPE_ID),
+        ),
+      '<b>Admin & POST only.</b> Removes permissions from an album.',
+      null,
+      array('admin_only'=>true, 'post_only'=>true)
+    );
 }
 
