Index: l10n_community/ajax.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/l10n_server/l10n_community/Attic/ajax.inc,v
retrieving revision 1.1.2.18.2.5
diff -u -p -r1.1.2.18.2.5 ajax.inc
--- l10n_community/ajax.inc	18 Sep 2009 18:03:18 -0000	1.1.2.18.2.5
+++ l10n_community/ajax.inc	10 Nov 2009 09:33:31 -0000
@@ -56,16 +56,21 @@ function l10n_community_string_details($
 }
 
 function l10n_community_string_suggestions($langcode = NULL, $sid = 0) {
+  global $user;
+
   // Existing, "unresolved" suggestions.
   $suggestions = array();
   $result = db_query("SELECT t.tid, t.sid, t.translation, t.uid_entered, t.time_entered, u.name FROM {l10n_community_translation} t LEFT JOIN {users} u ON u.uid = t.uid_entered WHERE t.language = '%s' AND t.sid = %d AND t.is_active = 1 AND t.is_suggestion = 1 ORDER BY t.time_entered", $langcode, $sid);
 
-  $perm = l10n_community_get_permission($langcode);
+  $permissions = l10n_community_get_permission($langcode);
   while ($suggestion = db_fetch_object($result)) {
+    // Check whether the user can approve or decline 
+    $perm = (bool)($permissions & ($suggestion->uid_entered == $user->uid ? L10N_PERM_MODERATE_OWN : L10N_PERM_MODERATE_OTHERS));
+
     // This detail pane is only retrieved from JS, so we are free to output obtrusive JS here.
     $token = "'". drupal_get_token('l10n_server_'. $suggestion->tid .'_'. $suggestion->sid) ."'";
-    $approve_button = $perm == L10N_PERM_ALL ? theme('l10n_community_button', 'approve', 'l10n-approve', 'onclick="l10nCommunity.approveSuggestion('. $suggestion->tid .','. $suggestion->sid .', this, '. $token .');" title="'. t('Approve suggestion.') .'"') : '';
-    $decline_button = $perm == L10N_PERM_ALL ? theme('l10n_community_button', 'decline', 'l10n-decline', 'onclick="l10nCommunity.declineSuggestion('. $suggestion->tid .','. $suggestion->sid .', this, '. $token .');" title="'. t('Decline suggestion.') .'"') : '';
+    $approve_button = $perm ? theme('l10n_community_button', 'approve', 'l10n-approve', 'onclick="l10nCommunity.approveSuggestion('. $suggestion->tid .','. $suggestion->sid .', this, '. $token .');" title="'. t('Approve suggestion.') .'"') : '';
+    $decline_button = $perm ? theme('l10n_community_button', 'decline', 'l10n-decline', 'onclick="l10nCommunity.declineSuggestion('. $suggestion->tid .','. $suggestion->sid .', this, '. $token .');" title="'. t('Decline suggestion.') .'"') : '';
 
     // Plural versions are shown in a short form.
     // Since we no longer store an additional copy of strings in JS
@@ -96,7 +101,7 @@ function l10n_community_string_suggestio
  */
 function l10n_community_string_ajax_suggestion($tid = 0) {
   if (($suggestion = db_fetch_object(db_query("SELECT * FROM {l10n_community_translation} WHERE tid = %d AND is_suggestion = 1 AND is_active = 1", $tid))) &&
-      (l10n_community_get_permission($suggestion->language) == L10N_PERM_ALL) &&
+      (l10n_community_has_permission($suggestion->language, L10N_PERM_REVIEW)) &&
       !empty($_GET['form_token']) &&
       drupal_valid_token($_GET['form_token'], 'l10n_server_'. $suggestion->tid .'_'. $suggestion->sid)) {
     return $suggestion;
Index: l10n_community/import.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/l10n_server/l10n_community/Attic/import.inc,v
retrieving revision 1.1.2.5.2.15
diff -u -p -r1.1.2.5.2.15 import.inc
--- l10n_community/import.inc	22 Oct 2009 15:13:44 -0000	1.1.2.5.2.15
+++ l10n_community/import.inc	10 Nov 2009 09:33:31 -0000
@@ -11,7 +11,8 @@
  */
 function l10n_community_import_page($langcode) {
   $languages = l10n_community_get_languages();
-  if (($perm = l10n_community_get_permission($langcode)) == L10N_PERM_ALL) {
+  // @todo: fixme
+  if (l10n_community_has_permission($langcode, L10N_PERM_IMPORT)) {
     drupal_set_title(t('Import translations to @language', array('@language' => $languages[$langcode]->name)));
   }
   else {
@@ -23,13 +24,13 @@ function l10n_community_import_page($lan
       l(t('Home'), NULL),
       l(t('Translate projects'), 'translate'))
   );
-  return drupal_get_form('l10n_community_import_form', $langcode, $perm);
+  return drupal_get_form('l10n_community_import_form', $langcode);
 }
 
 /**
  * Translation import form.
  */
-function l10n_community_import_form($form_state, $langcode, $perm) {
+function l10n_community_import_form($form_state, $langcode) {
   global $user;
   
   $form['#attributes']['enctype'] = 'multipart/form-data';
@@ -46,7 +47,7 @@ function l10n_community_import_form($for
     '#description' => t('The maximum allowed size for uploads is %maxsize.', array('%maxsize' => format_size(file_upload_max_size()))),
   );
 
-  if ($perm == L10N_PERM_ALL) {
+  if (l10n_community_has_permission($langcode, L10N_PERM_MODERATE_OWN)) {
     // If can submit translations, offer option to pick mode.
     $form['is_suggestion'] = array(
       '#title' => t('Status'),
Index: l10n_community/l10n_community.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/l10n_server/l10n_community/Attic/l10n_community.module,v
retrieving revision 1.1.2.23.2.59
diff -u -p -r1.1.2.23.2.59 l10n_community.module
--- l10n_community/l10n_community.module	6 Nov 2009 15:38:16 -0000	1.1.2.23.2.59
+++ l10n_community/l10n_community.module	10 Nov 2009 09:33:32 -0000
@@ -11,19 +11,59 @@
  */
 
 /**
- * No permission to suggest or translate, just view.
+ * Base permission; no access at all.
  */
 define('L10N_PERM_NONE', 0);
 
 /**
- * Permission to suggest.
+ * User may view the translation.
  */
-define('L10N_PERM_SUGGEST', 1);
+define('L10N_PERM_VIEW', 1);
 
 /**
- * Permission both to suggest and translate.
+ * User may contribute suggestions.
  */
-define('L10N_PERM_ALL', 2);
+define('L10N_PERM_SUGGEST', 2);
+
+/**
+ * User may approve or decline other user's suggestions.
+ */
+define('L10N_PERM_MODERATE_OTHERS', 4);
+
+/**
+ * User may approve her own suggestions.
+ */
+define('L10N_PERM_MODERATE_OWN', 8);
+
+/**
+ * User may mark other user's translations as stable.
+ */
+define('L10N_PERM_STABILIZE_OTHERS', 16);
+
+/**
+ * User may mark her translations as stable.
+ */
+define('L10N_PERM_STABILIZE_OWN', 32);
+
+/**
+ * User may import translations from a file.
+ */
+define('L10N_PERM_IMPORT', 64);
+
+/**
+ * User may export translation templates or translated .po files.
+ */
+define('L10N_PERM_EXPORT', 128);
+
+/**
+ * Accumulates all permissions a contributor may have.
+ */
+define('L10N_PERM_CONTRIBUTE', L10N_PERM_SUGGEST | L10N_PERM_IMPORT);
+
+/**
+ * Accumulates all permissions a reviewer may have.
+ */
+define('L10N_PERM_REVIEW', L10N_PERM_MODERATE_OTHERS | L10N_PERM_MODERATE_OWN);
 
 /**
  * Strings with any status.
@@ -226,7 +266,8 @@ function l10n_community_menu() {
     'page callback' => 'l10n_community_translate_page',
     'page arguments' => array(2),
     'file' => 'translate.inc',
-    'access arguments' => array('browse translations'),
+    'access callback' => 'l10n_community_has_permission',
+    'access arguments' => array(2, (string)L10N_PERM_VIEW),
     'type' => MENU_LOCAL_TASK,
     'weight' => -10,
   );
@@ -235,8 +276,8 @@ function l10n_community_menu() {
     'page callback' => 'l10n_community_translate_page',
     'page arguments' => array(2, 'edit'),
     'file' => 'translate.inc',
-    'access callback' => 'l10n_community_contribute_access',
-    'access arguments' => array(2),
+    'access callback' => 'l10n_community_has_permission',
+    'access arguments' => array(2, (string)L10N_PERM_SUGGEST),
     'type' => MENU_LOCAL_TASK,
     'weight' => -8,
   );
@@ -245,8 +286,8 @@ function l10n_community_menu() {
     'page callback' => 'l10n_community_moderate_page',
     'page arguments' => array(2),
     'file' => 'moderate.inc',
-    'access callback' => 'l10n_community_moderation_access',
-    'access arguments' => array(2),
+    'access callback' => 'l10n_community_has_permission',
+    'access arguments' => array(2, (string)L10N_PERM_REVIEW),
     'type' => MENU_LOCAL_TASK,
     'weight' => -6,
   );
@@ -255,8 +296,8 @@ function l10n_community_menu() {
     'page callback' => 'l10n_community_import_page',
     'page arguments' => array(2),
     'file' => 'import.inc',
-    'access callback' => 'l10n_community_contribute_access',
-    'access arguments' => array(2, TRUE),
+    'access callback' => 'l10n_community_has_permission',
+    'access arguments' => array(2, (string)L10N_PERM_IMPORT),
     'type' => MENU_LOCAL_TASK,
     'weight' => -5,
   );
@@ -265,7 +306,8 @@ function l10n_community_menu() {
     'page callback' => 'l10n_community_export_page',
     'page arguments' => array(NULL, 2),
     'file' => 'export.inc',
-    'access callback' => 'l10n_community_export_access',
+    'access callback' => 'l10n_community_has_permission',
+    'access arguments' => array(2, (string)L10N_PERM_EXPORT),
     'type' => MENU_LOCAL_TASK,
     'weight' => 0,
   );
@@ -290,7 +332,8 @@ function l10n_community_menu() {
     'title' => 'Export template',
     'page callback' => 'l10n_community_export_page',
     'page arguments' => array(2),
-    'access callback' => 'l10n_community_export_access',
+    'access callback' => 'l10n_community_has_permission',
+    'access arguments' => array(2, (string)L10N_PERM_EXPORT),
     'file' => 'export.inc',
     'type' => MENU_LOCAL_TASK,
     'weight' => 0,
@@ -359,32 +402,6 @@ function l10n_community_project_admin_lo
 }
 
 /**
- * Access callback for editing and import paths. Requires edit privileges for given language.
- *
- * @param $langcode
- *  Language code.
- * @param $import
- *  Boolean. Whether this is a gettext import operation.
- */
-function l10n_community_contribute_access($langcode, $import = FALSE) {
-  return user_access('browse translations') && (l10n_community_get_permission($langcode) != L10N_PERM_NONE) && ($import ? user_access('import gettext files') : TRUE);
-}
-
-/**
- * Access callback for exporting paths. Requires access and export privileges.
- */
-function l10n_community_export_access() {
-  return user_access('browse translations') && user_access('export gettext templates and translations');
-}
-
-/**
- * Access to the moderation screen.
- */
-function l10n_community_moderation_access($langcode) {
-  return user_access('browse translations') && (l10n_community_get_permission($langcode) == L10N_PERM_ALL);
-}
-
-/**
  * Title callback for project pages.
  */
 function l10n_community_page_title_project($uri) {
@@ -413,7 +430,16 @@ function l10n_community_init() {
  * Implementation of hook_perm().
  */
 function l10n_community_perm() {
-  return array('access localization community', 'browse translations', 'submit suggestions', 'submit translations and approve suggestions', 'administer localization community', 'export gettext templates and translations', 'import gettext files');
+  return array(
+    'access localization community',
+    'browse translations',
+    'administer localization community',
+    'export gettext templates and translations',
+    'import gettext files',
+    'submit suggestions',
+    'moderate other people\'s suggestions',
+    'moderate own suggestions',
+  );
 }
 
 /**
@@ -485,7 +511,7 @@ function l10n_community_block_help() {
   // Match actual translation editing or review pages with the two different path models they could have.
   if (preg_match('!translate/languages/(?P<langcode>[^/]+)(/(?P<action>view|edit|import|export))?$!', $_GET['q'], $args) ||
       preg_match('!translate/projects/(?P<uri>[^/]+)(/(?P<action>|export))??$!', $_GET['q'], $args)) {
-    $perm = isset($args['langcode']) ? l10n_community_get_permission($args['langcode']) : L10N_PERM_NONE;
+    $perm = l10n_community_get_permission(isset($args['langcode']) ? $args['langcode'] : NULL);
     $permission_help = '';
     if (module_exists('l10n_groups')) {
       // We are dealing with a groups based permission model.
@@ -493,16 +519,11 @@ function l10n_community_block_help() {
     }
     else {
       // We are dealing with a simple permission model.
-      switch ($perm) {
-        case L10N_PERM_NONE:
-          // No user access to this page in this case.
-          break;
-        case L10N_PERM_SUGGEST:
-          $permission_help = t('You can suggest translations or import complete Gettext translation files to suggest multiple translations at once. People with permission to approve suggestions may either accept or decline your suggestions. To work offline, export a translation template, which contains the current state of the translation.');
-          break;
-        case L10N_PERM_ALL:
-          $permission_help = t('As a fully empowered user, you can suggest translations as well as approve translations suggested by others. Export/import of Gettext translation files is also possible.');
-          break;
+      if ($perm & L10N_PERM_REVIEW) {
+        $permission_help = t('As a fully empowered user, you can suggest translations as well as approve translations suggested by others. Export/import of Gettext translation files is also possible.');
+      }
+      elseif ($perm & L10N_PERM_SUGGEST) {
+        $permission_help = t('You can suggest translations or import complete Gettext translation files to suggest multiple translations at once. People with permission to approve suggestions may either accept or decline your suggestions. To work offline, export a translation template, which contains the current state of the translation.');
       }
       $permission_help = !empty($permission_help) ? ('<p>'. $permission_help .'</p>') : '';
     }
@@ -935,13 +956,12 @@ function l10n_community_get_languages($k
 /**
  * Get translation permission level for a specific user.
  *
- *
  * @param $langcode
  *   Language code, for example 'hu', 'pt-br', 'de' or 'it'.
  * @param $account
- *   Optional user account.
+ *   (Optional) A user account object. If not passed, the current user is used.
  * @return
- *   L10N_PERM_NONE, L10N_PERM_SUGGEST or L10N_PERM_ALL
+ *   A bitmask of all permission flags the user has.
  */
 function l10n_community_get_permission($langcode, $account = NULL) {
   static $permissions = array();
@@ -954,28 +974,25 @@ function l10n_community_get_permission($
     $account = $user;
   }
 
-  if (isset($permissions[$account->uid][$langcode])) {
-    // Return cached value if available.
-    return $permissions[$account->uid][$langcode];
-  }
-
-  // Initialize to lowest possible permission.
-  $permissions[$account->uid][$langcode] = L10N_PERM_NONE;
-
-  if ($account->uid == 1) {
-    // The administrator has all permissions in all languages.
-    return ($permissions[$account->uid][$langcode] = L10N_PERM_ALL);
+  if (!isset($permissions[$account->uid])) {
+    $permissions[$account->uid] = array();
   }
+  if (!isset($permissions[$account->uid][$langcode])) {
+    // Minimal permission.
+    $global = L10N_PERM_NONE;
+    $global |= user_access('browse translations', $account) ? L10N_PERM_VIEW : 0;
+    $global |= user_access('submit suggestions', $account) ? L10N_PERM_SUGGEST : 0;
+    $global |= user_access('moderate other people\'s suggestions', $account) ? L10N_PERM_MODERATE_OTHERS : 0;
+    $global |= user_access('moderate own suggestions', $account) ? L10N_PERM_MODERATE_OWN : 0;
+    $global |= user_access('import gettext files', $account) ? L10N_PERM_IMPORT : 0;
+    $global |= user_access('export gettext templates and translations', $account) ? L10N_PERM_EXPORT : 0;
 
-  $global_permission = user_access('submit translations and approve suggestions', $account) ? L10N_PERM_ALL : (user_access('submit suggestions', $account) ? L10N_PERM_SUGGEST : L10N_PERM_NONE);
-
-  if (($global_permission != L10N_PERM_NONE) && module_exists('l10n_groups')) {
-    // Fill up permission information for this account if it has any permission.
-    l10n_groups_get_permission($permissions, $global_permission, $langcode, $account);
-  }
-  else {
-    // Remember global permission if using l10n_community standalone.
-    $permissions[$account->uid][$langcode] = $global_permission;
+    if (!module_exists('l10n_groups')) {
+      $permissions[$account->uid][$langcode] = $global;
+    }
+    else {
+      l10n_groups_get_permission($permissions, $account, $global);
+    }
   }
 
   // Return from local cache.
@@ -983,6 +1000,20 @@ function l10n_community_get_permission($
 }
 
 /**
+ * Checks whether the current user has a certain permission.
+ *
+ * @param $langcode
+ *   Language code, for example 'hu', 'pt-br', 'de' or 'it'.
+ * @param $permission
+ *   The permission to check for.
+ * @return
+ *   TRUE if the user has at least one of the specified permissions.
+ */
+function l10n_community_has_permission($langcode, $permission) {
+  return (bool)(l10n_community_get_permission($langcode, NULL) & $permission);
+}
+
+/**
  * Provides a list of projects from the database, ordered by uri.
  *
  * @param $options
Index: l10n_community/moderate.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/l10n_server/l10n_community/Attic/moderate.inc,v
retrieving revision 1.1.2.4
diff -u -p -r1.1.2.4 moderate.inc
--- l10n_community/moderate.inc	6 Nov 2009 16:00:57 -0000	1.1.2.4
+++ l10n_community/moderate.inc	10 Nov 2009 09:33:32 -0000
@@ -77,11 +77,12 @@ function l10n_community_moderation_form(
     '#type' => 'submit',
     '#value' => t('Decline all selected'),
   );
-  
+
   // All strings and suggestions
   $form['strings'] = array(
     '#tree' => TRUE,
   );
+
   foreach ($strings as $string) {
     $form['strings']['tid'][$string->tid] = array(
       '#type' => 'checkbox',
@@ -145,6 +146,8 @@ function l10n_community_moderation_form_
  *   An array of suggestion records from database.
  */
 function l10n_community_get_suggestions($langcode, $filters) {
+  global $user;
+
   $join = $join_args = $where = $where_args = array();
   $sql = $sql_count = '';
 
@@ -205,6 +208,17 @@ function l10n_community_get_suggestions(
     $join[] = "LEFT JOIN {l10n_community_translation} tt ON tt.sid = ts.sid AND tt.is_suggestion = 0 AND tt.is_active = 1 AND tt.language = '%s'";
     $join_args[] = $langcode;
   }
+  
+  // Only show strings matching the user's permissions.
+  $permission = l10n_community_get_permission($langcode);
+  if (!($permission & L10N_PERM_MODERATE_OWN)) {
+    $where[] = "(ts.uid_entered <> %d)";
+    $where_args[] = $user->uid;
+  }
+  if (!($permission & L10N_PERM_MODERATE_OTHERS)) {
+    $where[] = "(ts.uid_entered = %d)";
+    $where_args[] = $user->uid;
+  }
 
   // Build the queries
   $sql_args = array_merge($join_args, $where_args);
Index: l10n_community/translate.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/l10n_server/l10n_community/Attic/translate.inc,v
retrieving revision 1.1.2.7.2.25
diff -u -p -r1.1.2.7.2.25 translate.inc
--- l10n_community/translate.inc	6 Nov 2009 16:00:57 -0000	1.1.2.7.2.25
+++ l10n_community/translate.inc	10 Nov 2009 09:33:32 -0000
@@ -37,7 +37,7 @@ function l10n_community_translate_page($
   if (!count($strings)) {
     drupal_set_message(t('No strings found with this filter. Try adjusting the filter options.'));
   }
-  elseif ($perm == L10N_PERM_NONE || $mode == 'view') {
+  elseif (!($perm & L10N_PERM_SUGGEST) || $mode == 'view') {
     // For users without permission to translate or suggest, display the view.
     drupal_set_title(t('@language translations', array('@language' => $languages[$langcode]->name)));
     $output .= l10n_community_translate_view($strings, $languages[$langcode], $filters);
@@ -349,11 +349,11 @@ function l10n_community_translate_form(&
         $target = $string->sid .'-'. $i;
         if ($translated) {
           // Already translated so we ask for new translation or suggestion.
-          $description = ($perm == L10N_PERM_SUGGEST) ? t('New suggestion for variant #%d', array('%d' => $i)) : t('New translation for variant #%d', array('%d' => $i));
+          $description = !($perm & L10N_PERM_MODERATE_OWN) ? t('New suggestion for variant #%d', array('%d' => $i)) : t('New translation for variant #%d', array('%d' => $i));
         }
         else {
           // Not translated yet, so we ask for initial translation or suggestion.
-          $description = ($perm == L10N_PERM_SUGGEST) ? t('Suggestion for variant #%d', array('%d' => $i)) : t('Translation for variant #%d', array('%d' => $i));
+          $description = !($perm & L10N_PERM_MODERATE_OWN) ? t('Suggestion for variant #%d', array('%d' => $i)) : t('Translation for variant #%d', array('%d' => $i));
         }
 
         // Include editing area for each plural variant.
@@ -381,7 +381,7 @@ function l10n_community_translate_form(&
         // Use textarea for long and multiline strings.
         '#type' => ((strlen($string->value) > 45) || (count(explode("\n", $string->value)) > 1)) ? 'textarea' : 'textfield',
         // Provide accurate title based on previous data and permission.
-        '#description' => $translated ? (($perm == L10N_PERM_SUGGEST) ? t('Add a new suggestion') : t('Add a new translation')) : (($perm == L10N_PERM_SUGGEST) ? t('Suggestion') : ''),
+        '#description' => $translated ? (!($perm & L10N_PERM_MODERATE_OWN) ? t('Add a new suggestion') : t('Add a new translation')) : (!($perm & L10N_PERM_MODERATE_OWN) ? t('Suggestion') : ''),
         '#rows' => 4,
         '#resizable' => FALSE,
         '#cols' => NULL,
@@ -406,7 +406,7 @@ function l10n_community_translate_form(&
       '#type' => 'markup',
     );
 
-    if ($perm == L10N_PERM_SUGGEST) {
+    if (!($perm & L10N_PERM_MODERATE_OWN)) {
       // User with suggestion capability only, record this.
       $form[$string->sid]['translation']['is_suggestion'] = array(
         '#type' => 'value',
@@ -445,7 +445,7 @@ function l10n_community_translate_form(&
   // Let the user submit the form.
   $form['submit'] = array(
     '#type' => 'submit',
-    '#value' => ($perm == L10N_PERM_SUGGEST) ? t('Save suggestions') : t('Save translations')
+    '#value' => !($perm & L10N_PERM_MODERATE_OWN) ? t('Save suggestions') : t('Save translations')
   );
 
   $form['#theme'] = 'l10n_community_translate_form';
Index: l10n_community/welcome.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/l10n_server/l10n_community/Attic/welcome.inc,v
retrieving revision 1.1.2.7.2.13
diff -u -p -r1.1.2.7.2.13 welcome.inc
--- l10n_community/welcome.inc	2 Oct 2009 08:55:36 -0000	1.1.2.7.2.13
+++ l10n_community/welcome.inc	10 Nov 2009 09:33:32 -0000
@@ -170,7 +170,7 @@ function l10n_community_pick_go_submit($
     // Project surely selected, possibly with language too.
     if (!empty($form_state['values']['langcode'])) {
       if (user_access('browse translations')) {
-        $action = l10n_community_contribute_access($form_state['values']['langcode']) ? 'edit' : 'view';
+        $action = l10n_community_has_permission($form_state['values']['langcode'], L10N_PERM_CONTRIBUTE) ? 'edit' : 'view';
         drupal_goto('translate/languages/'. $form_state['values']['langcode'] .'/'. $action, 'project='. $uri);
       }
       else {
Index: l10n_community/tests/l10n_community.test
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/l10n_server/l10n_community/tests/Attic/l10n_community.test,v
retrieving revision 1.1.2.13
diff -u -p -r1.1.2.13 l10n_community.test
--- l10n_community/tests/l10n_community.test	22 Oct 2009 14:34:23 -0000	1.1.2.13
+++ l10n_community/tests/l10n_community.test	10 Nov 2009 09:33:32 -0000
@@ -28,7 +28,7 @@ class L10nServerTestCase extends DrupalW
     $this->u_auth = $this->drupalCreateUser(array('access localization community', 'browse translations'));
     $this->u_member_1 = $this->drupalCreateUser(array('access localization community', 'browse translations', 'submit suggestions', 'import gettext files'));
     $this->u_member_2 = $this->drupalCreateUser(array('access localization community', 'browse translations', 'submit suggestions', 'import gettext files'));
-    $this->u_moderator = $this->drupalCreateUser(array('access localization community', 'browse translations', 'submit translations and approve suggestions', 'import gettext files'));
+    $this->u_moderator = $this->drupalCreateUser(array('access localization community', 'browse translations', 'moderate own suggestions', 'moderate other people\'s suggestions', 'import gettext files', 'submit suggestions'));
     $this->u_admin = $this->drupalCreateUser(array('administer languages', 'administer localization community', 'administer localization community for local packages', 'import gettext files'));
     $this->u_team = $this->drupalCreateUser();
 
Index: l10n_groups/l10n_groups.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/l10n_server/l10n_groups/Attic/l10n_groups.module,v
retrieving revision 1.1.2.4.2.7
diff -u -p -r1.1.2.4.2.7 l10n_groups.module
--- l10n_groups/l10n_groups.module	18 Sep 2009 18:03:19 -0000	1.1.2.4.2.7
+++ l10n_groups/l10n_groups.module	10 Nov 2009 09:33:32 -0000
@@ -242,18 +242,18 @@ function l10n_groups_block_help($perm, $
 
   $groups = l10n_groups_get_groups();
   $permission_help = '';
-  switch ($perm) {
-    // Inform user about her permission level in this group.
-    case L10N_PERM_NONE:
-      $permission_help = t('You are not a member of this translation group, but you can still view the existing translations and export templates or translations for your own use.') .' '. ($user->uid ? t('<a href="@group">Subscribe to this group</a> if you would like to help out.', array('@group' => url('node/'. $groups[$langcode]->nid))) : t('<a href="@register">Create an account or log in</a> and <a href="@group">subscribe to this group</a> if you would like to help out.', array('@register' => url('user'), '@group' => url('node/'. $groups[$langcode]->nid))));
-      break;
-    case L10N_PERM_SUGGEST:
-      $permission_help = t('You are a member of this translation group, so you can suggest translations or import complete Gettext translation files to suggest multiple translations at once. Administrators of this group either accept or decline suggestions provided by members of the group. To work offline, export a translation template, which contains the current state of the translation.');
-      break;
-    case L10N_PERM_ALL:
-      $permission_help = t('As a member of this translation group, you can suggest translations as well as approve translations suggested by other members of the group. Export/import of Gettext translation files is also possible.');
-      break;
+
+  // Inform user about her permission level in this group.
+  if (!((L10N_PERM_REVIEW | L10N_PERM_SUGGEST) & ~$perm)) {
+    $permission_help = t('As a member of this translation group, you can suggest translations as well as approve translations suggested by other members of the group. Export/import of Gettext translation files is also possible.');
+  }
+  elseif (L10N_PERM_SUGGEST & $perm) {
+    $permission_help = t('You are a member of this translation group, so you can suggest translations or import complete Gettext translation files to suggest multiple translations at once. Administrators of this group either accept or decline suggestions provided by members of the group. To work offline, export a translation template, which contains the current state of the translation.');
+  }
+  elseif (L10N_PERM_VIEW & $perm) {
+    $permission_help = t('You are not a member of this translation group, but you can still view the existing translations and export templates or translations for your own use.') .' '. ($user->uid ? t('<a href="@group">Subscribe to this group</a> if you would like to help out.', array('@group' => url('node/'. $groups[$langcode]->nid))) : t('<a href="@register">Create an account or log in</a> and <a href="@group">subscribe to this group</a> if you would like to help out.', array('@register' => url('user'), '@group' => url('node/'. $groups[$langcode]->nid))));
   }
+
   return '<p>'. $permission_help .'</p>';
 }
 
@@ -280,36 +280,33 @@ function l10n_groups_get_groups() {
 /**
  * Get permission level for a specific user based on group membership.
  *
- * The group permissio model is taken into account and membership of
+ * The group permission model is taken into account and membership of
  * the user in language groups is checked.
  *
  * @param $permissions
  *   Permission cache array to tunnel cache values to.
- * @param $global_permission
- *   Permission based on user access settings to consider as a base.
- * @param $langcode
- *   Language code, for example 'hu', 'pt-br', 'de' or 'it'.
  * @param $account
  *   Optional user account.
+ * @param $global
+ *   Permission based on user access settings to consider as a base.
  */
-function l10n_groups_get_permission(&$permissions, $global_permission, $langcode, $account) {
+function l10n_groups_get_permission(&$permissions, $account, $global) {
   if ($groups = l10n_groups_get_groups()) {
     // Fill up local cache with all langcode permissions of this account for
     // future reference (eg. a page showing links for all languages).
     foreach ($groups as $group) {
-      $permission = L10N_PERM_NONE;
-      if (!empty($account->og_groups) and !empty($account->og_groups[$group->nid])) {
-        if (!empty($account->og_groups[$group->nid]['is_admin'])) {
-          // Administrators of groups have all permissions in the group.
-          $permission = L10N_PERM_ALL;
-        }
-        elseif ($account->og_groups[$group->nid]['is_active']) {
-          // Members in the group have a permission depending on the model used.
-          $permission = ($group->model == L10N_MODEL_OPEN ? L10N_PERM_ALL : L10N_PERM_SUGGEST);
-        }
+      $permission = $global;
+
+      if (empty($account->og_groups) || empty($account->og_groups[$group->nid])) {
+        // The user is not in the group and may therefore only view.
+        $permission = $permission & ~(L10N_PERM_CONTRIBUTE | L10N_PERM_REVIEW);
       }
-      // Save the lowest common denominator of permissions given.
-      $permissions[$account->uid][$group->language] = min($permission, $global_permission);
+      elseif (empty($account->og_groups[$group->nid]['is_admin']) && $group->model != L10N_MODEL_OPEN) {
+        // Non-Admins of group don't have these permissions.
+        $permission = $permission & ~(L10N_PERM_REVIEW);
+      }
+
+      $permissions[$account->uid][$group->language] = $permission;
     }
   }
 }
Index: l10n_remote/l10n_remote.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/l10n_server/l10n_remote/Attic/l10n_remote.module,v
retrieving revision 1.1.2.3
diff -u -p -r1.1.2.3 l10n_remote.module
--- l10n_remote/l10n_remote.module	30 Sep 2009 12:17:09 -0000	1.1.2.3
+++ l10n_remote/l10n_remote.module	10 Nov 2009 09:33:32 -0000
@@ -142,8 +142,8 @@ function l10n_remote_xmlrpc_string_submi
     return array('status' => FALSE, 'reason' => 'Language not accepted.');
   }
   
-  // Check if the user has permission to submit strings in this language. 
-  if (l10n_community_get_permission($langcode, $account) == L10N_PERM_NONE) {
+  // Check if the user has permission to submit strings in this language.
+  if (!(l10n_community_get_permission($langcode, $account) & L10N_PERM_SUGGEST)) {
     //watchdog('l10n_community', 'Not allowed to submit translations in this language remotely.', NULL, WATCHDOG_WARNING);
     return array('status' => FALSE, 'reason' => 'Not allowed to submit translations in this language.');
   }
