diff --git l10n_community/ajax.inc l10n_community/ajax.inc index 5fe7fcd..046b684 100644 --- l10n_community/ajax.inc +++ l10n_community/ajax.inc @@ -56,16 +56,21 @@ function l10n_community_string_details($langcode = NULL, $sid = 0) { } 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_suggestions($langcode = NULL, $sid = 0) { */ 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; diff --git l10n_community/import.inc l10n_community/import.inc index e82b357..70408bf 100644 --- l10n_community/import.inc +++ l10n_community/import.inc @@ -11,7 +11,7 @@ */ function l10n_community_import_page($langcode) { $languages = l10n_community_get_languages(); - if (($perm = l10n_community_get_permission($langcode)) == L10N_PERM_ALL) { + 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 +23,13 @@ function l10n_community_import_page($langcode) { 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) { $form['#attributes']['enctype'] = 'multipart/form-data'; $form['langcode'] = array( @@ -49,7 +49,7 @@ function l10n_community_import_form($form_state, $langcode, $perm) { '#description' => t('Check if the translations you import need discussion. If checked, all translations in the imported file will be saved as suggestions.'), ); // Restrict to suggestions if no permission to submit translations directly. - if ($perm != L10N_PERM_ALL) { + if (l10n_community_has_permission($langcode, L10N_PERM_MODERATE_OWN)) { $form['is_suggestion']['#type'] = 'value'; $form['is_suggestion']['#value'] = 1; } diff --git l10n_community/l10n_community.module l10n_community/l10n_community.module index badf646..5fd4797 100644 --- l10n_community/l10n_community.module +++ l10n_community/l10n_community.module @@ -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_load($uri) { } /** - * 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[^/]+)(/(?Pview|edit|import|export))?$!', $_GET['q'], $args) || preg_match('!translate/projects/(?P[^/]+)(/(?P|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) ? ('

'. $permission_help .'

') : ''; } @@ -936,13 +957,12 @@ function l10n_community_get_languages($key = NULL) { /** * 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(); @@ -955,28 +975,25 @@ function l10n_community_get_permission($langcode, $account = NULL) { $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. @@ -984,6 +1001,20 @@ function l10n_community_get_permission($langcode, $account = NULL) { } /** + * 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 diff --git l10n_community/moderate.inc l10n_community/moderate.inc index 585f45a..b480df3 100644 --- l10n_community/moderate.inc +++ l10n_community/moderate.inc @@ -49,6 +49,8 @@ function l10n_community_moderate_page($langcode) { * Filters used to present this moderation view. */ function l10n_community_moderation_form(&$form_state, $strings = array(), $language = NULL, $filters) { + global $user; + $form['pager'] = array( '#value' => theme('pager', NULL, $filters['limit'], 0) ); @@ -74,11 +76,12 @@ function l10n_community_moderation_form(&$form_state, $strings = array(), $langu '#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', @@ -142,6 +145,8 @@ function l10n_community_moderation_form_submit($form, &$form_state) { * 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 = ''; @@ -202,6 +207,17 @@ function l10n_community_get_suggestions($langcode, $filters) { $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); diff --git l10n_community/tests/l10n_community.test l10n_community/tests/l10n_community.test index dfd7987..18219e8 100644 --- l10n_community/tests/l10n_community.test +++ l10n_community/tests/l10n_community.test @@ -28,7 +28,7 @@ class L10nServerTestCase extends DrupalWebTestCase { $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')); $this->u_member_2 = $this->drupalCreateUser(array('access localization community', 'browse translations', 'submit suggestions')); - $this->u_moderator = $this->drupalCreateUser(array('access localization community', 'browse translations', 'submit translations and approve suggestions')); + $this->u_moderator = $this->drupalCreateUser(array('access localization community', 'browse translations', 'moderate own suggestions', 'moderate other people\'s suggestions')); $this->u_admin = $this->drupalCreateUser(array('administer languages', 'administer localization community', 'administer localization community for local packages')); // Set up temporary directory for our work. Because this is inside the diff --git l10n_community/translate.inc l10n_community/translate.inc index f51f577..50c8e5e 100644 --- l10n_community/translate.inc +++ l10n_community/translate.inc @@ -37,7 +37,7 @@ function l10n_community_translate_page($langcode = NULL, $mode = 'view') { 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); @@ -362,11 +362,11 @@ function l10n_community_translate_form(&$form_state, $strings = array(), $langua $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. @@ -394,7 +394,7 @@ function l10n_community_translate_form(&$form_state, $strings = array(), $langua // 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, @@ -419,7 +419,7 @@ function l10n_community_translate_form(&$form_state, $strings = array(), $langua '#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', @@ -458,7 +458,7 @@ function l10n_community_translate_form(&$form_state, $strings = array(), $langua // 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'; diff --git l10n_community/welcome.inc l10n_community/welcome.inc index 4698d76..d800ad8 100644 --- l10n_community/welcome.inc +++ l10n_community/welcome.inc @@ -170,7 +170,7 @@ function l10n_community_pick_go_submit($form, &$form_state) { // 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 { diff --git l10n_groups/l10n_groups.module l10n_groups/l10n_groups.module index aa39d10..8989f15 100644 --- l10n_groups/l10n_groups.module +++ l10n_groups/l10n_groups.module @@ -242,18 +242,18 @@ function l10n_groups_block_help($perm, $langcode = NULL) { $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('Subscribe to this group if you would like to help out.', array('@group' => url('node/'. $groups[$langcode]->nid))) : t('Create an account or log in and subscribe to this group 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('Subscribe to this group if you would like to help out.', array('@group' => url('node/'. $groups[$langcode]->nid))) : t('Create an account or log in and subscribe to this group if you would like to help out.', array('@register' => url('user'), '@group' => url('node/'. $groups[$langcode]->nid)))); } + return '

'. $permission_help .'

'; } @@ -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); + } + 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); } - // Save the lowest common denominator of permissions given. - $permissions[$account->uid][$group->language] = min($permission, $global_permission); + + $permissions[$account->uid][$group->language] = $permission; } } } diff --git l10n_remote/l10n_remote.module l10n_remote/l10n_remote.module index 7d9d5ba..5d5e689 100644 --- l10n_remote/l10n_remote.module +++ l10n_remote/l10n_remote.module @@ -142,8 +142,8 @@ function l10n_remote_xmlrpc_string_submit($langcode, $source, $translation, $uid 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.'); }