? l10n
Index: extractor.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/l10n_server/l10n_community/Attic/extractor.inc,v
retrieving revision 1.1.2.13.2.2
diff -u -p -r1.1.2.13.2.2 extractor.inc
--- extractor.inc	15 Oct 2008 00:09:30 -0000	1.1.2.13.2.2
+++ extractor.inc	11 Apr 2009 09:15:53 -0000
@@ -127,7 +127,7 @@ function l10n_community_parse_package($p
 function l10n_community_save_file($revision = NULL, $file = NULL) {
   static $rid = 0;
   static $files = array();
-  
+
   if (!isset($file)) {
     // We get the release number for the files.
     $rid = $revision;
@@ -146,7 +146,8 @@ function l10n_community_save_file($revis
     }
     else {
       // New file in this release.
-      db_query("INSERT INTO {l10n_community_file} (rid, location, revision) VALUES(%d, '%s', '%s')", $rid, $file, $revision);
+      $pid = db_result(db_query("SELECT pid FROM {l10n_community_release} WHERE rid = %d", $rid));
+      db_query("INSERT INTO {l10n_community_file} (rid, pid, location, revision) VALUES(%d, %d, '%s', '%s')", $rid, $pid, $file, $revision);
       $fid = db_result(db_query("SELECT fid FROM {l10n_community_file} WHERE rid = %d and location = '%s'", $rid, $file));
     }
     $files[$file] = $fid;
@@ -174,7 +175,7 @@ function l10n_community_save_file($revis
  */
 function l10n_community_save_string($value = NULL, $file = NULL, $line = 0, $string_type = 2 /*POTX_STRING_RUNTIME*/) {
   static $files = array();
-  
+
   // Strip all slashes from string.
   $value = stripcslashes($value);
   
@@ -192,10 +193,19 @@ function l10n_community_save_string($val
       // String does not exist.
       db_query("INSERT INTO {l10n_community_string} (value) VALUES ('%s')", $value);
       $sid = db_result(db_query("SELECT sid FROM {l10n_community_string} WHERE value = BINARY '%s'", $value));
+      // Add empty translation for every language.
+      $languages = language_list('enabled');
+      unset($languages[1]['en']);
+
+      foreach($languages[1] as $language) { 
+        $langcode = $language->language;
+        db_query("INSERT INTO {l10n_community_translation} (sid, translation, language, uid_entered, time_entered, has_suggestion, is_active) VALUES (%d, '', '%s', 0, %d, 1, 1)", $sid, $langcode, time());
+      }
     }
     if (!db_result(db_query("SELECT fid FROM {l10n_community_line} WHERE fid = %d AND sid = %d AND lineno = %d AND type = %d", $files[$file], $sid, $line, $string_type))) {
       // Location does not exist with this string.
-      db_query("INSERT INTO {l10n_community_line} (fid, sid, lineno, type) VALUES (%d, %d, %d, %d)", $files[$file], $sid, $line, $string_type);
+      $row = db_fetch_object(db_query("SELECT rid, pid FROM {l10n_community_file} WHERE fid = %d", $files[$file]));
+      db_query("INSERT INTO {l10n_community_line} (fid, sid, lineno, type, rid, pid) VALUES (%d, %d, %d, %d, %d, %d)", $files[$file], $sid, $line, $string_type, $row->rid, $row->pid);
     }
   }
 }
Index: l10n_community.install
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/l10n_server/l10n_community/Attic/l10n_community.install,v
retrieving revision 1.1.2.11.2.7
diff -u -p -r1.1.2.11.2.7 l10n_community.install
--- l10n_community.install	26 Oct 2008 20:56:42 -0000	1.1.2.11.2.7
+++ l10n_community.install	11 Apr 2009 09:15:53 -0000
@@ -170,6 +170,12 @@ function l10n_community_schema() {
         'not null' => FALSE,
         'disp-width' => '11'
       ),
+      'pid' => array(
+        'description' => $t('Reference to the {l10n_community_project}.pid of the parent project.'),
+        'type' => 'int',
+        'not null' => FALSE,
+        'disp-width' => '11'
+      ),
       'location' => array(
         'description' => $t('Path to the file within the release package.'),
         'type' => 'varchar',
@@ -198,6 +204,18 @@ function l10n_community_schema() {
         'not null' => FALSE,
         'disp-width' => '11'
       ),
+      'pid' => array(
+        'description' => $t('Reference to the {l10n_community_project}.pid of the parent project.'),
+        'type' => 'int',
+        'not null' => FALSE,
+        'disp-width' => '11'
+      ),
+      'rid' => array(
+        'description' => $t('Reference to the {l10n_community_release}.rid of the parent release.'),
+        'type' => 'int',
+        'not null' => FALSE,
+        'disp-width' => '11'
+      ),
       'lineno' => array(
         'description' => $t('Number of line where the string occurance was found.'),
         'type' => 'int',
@@ -504,3 +522,48 @@ function l10n_community_update_6004() {
   db_add_index($ret, 'l10n_community_translation', 'sid_language_suggestion', array('sid', 'language', 'is_suggestion'));
   return $ret;
 }
+
+/**
+ * Denormalize data in order to improve performance: Push project ID to file table.
+ */
+function l10n_community_update_6005() {
+  $ret = array();
+
+  db_add_field($ret, 'l10n_community_file', 'pid', array('type' => 'int', 'not null' => FALSE, 'disp-width' => 11));
+
+  $q = db_query("SELECT f.fid, r.pid FROM {l10n_community_release} r, {l10n_community_file} f WHERE r.rid = f.rid");
+  while ($row = db_fetch_object($q)) {
+    db_query("UPDATE {l10n_community_file} SET pid = %d WHERE fid = %d", $row->pid, $row->fid);
+  }
+  return $ret;
+}
+
+/**
+ * Denormalize data in order to improve performance: Push project and release ID to line table.
+ */
+function l10n_community_update_6006() {
+  $ret = array();
+
+  db_add_field($ret, 'l10n_community_line', 'pid', array('type' => 'int', 'not null' => FALSE, 'disp-width' => 11));
+  db_add_field($ret, 'l10n_community_line', 'rid', array('type' => 'int', 'not null' => FALSE, 'disp-width' => 11));
+
+  $q = db_query("SELECT l.lineno, l.fid, l.sid, l.type, f.rid, f.pid FROM {l10n_community_line} l, {l10n_community_file} f WHERE f.fid = l.fid");
+  while ($row = db_fetch_object($q)) {
+    db_query("UPDATE {l10n_community_line} SET pid = %d, rid = %d WHERE fid = %d AND lineno = %d AND type = %d AND sid = %d", $row->pid, $row->rid, $row->fid, $row->lineno, $row->type, $row->sid);
+  }
+  return $ret;
+}
+
+/**
+  * Populate empty translations for every languages in order to use LEFT JOIN
+  * instead of INNER JOIN.
+  */
+function l10n_community_update_6007() {
+  $ret = array();
+  $languages = language_list('enabled');
+  unset($languages[1]['en']);
+  foreach($languages as $language) {
+    l10n_community_populate_translations($language->language);
+  }
+  return $ret;
+}
Index: 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.18
diff -u -p -r1.1.2.23.2.18 l10n_community.module
--- l10n_community.module	30 Dec 2008 16:30:21 -0000	1.1.2.23.2.18
+++ l10n_community.module	11 Apr 2009 09:15:54 -0000
@@ -699,9 +699,15 @@ function l10n_community_target_save($sid
   // Load source string and adjust translation whitespace based on source.
   $source_string = db_result(db_query('SELECT value FROM {l10n_community_string} WHERE sid = %d', $sid));
   $translation = l10n_community_trim($translation, $source_string);
+
+  // Remove placeholder translation record (which was there if
+  // first came suggestions, before an actual translation).
+  db_query("DELETE FROM {l10n_community_translation} WHERE sid = %d AND translation = '' AND language = '%s'", $sid, $langcode);
+
   // Look for an existing active translation, if any.
   $existing_string = db_fetch_object(db_query("SELECT sid, tid, translation FROM {l10n_community_translation} WHERE sid = %d AND language = '%s' AND is_suggestion = 0 AND is_active = 1", $sid, $langcode));
 
+ 
   if (!empty($existing_string->sid)) {
 
     // We have an active translation.
@@ -728,8 +734,7 @@ function l10n_community_target_save($sid
   else {
     // No active translation exists.
     if ($suggestion) {
-      // No translation yet -> INSERT empty placeholder so we can track suggestions.
-      db_query("INSERT INTO {l10n_community_translation} (sid, translation, language, uid_entered, time_entered, has_suggestion, is_active) VALUES (%d, '', '%s', 0, %d, 1, 1)", $sid, $langcode, time());
+      l10n_community_insert_empty_translation($sid, $langcode);
       db_query("INSERT INTO {l10n_community_translation} (sid, language, translation, uid_entered, time_entered, is_suggestion, is_active) VALUES (%d, '%s', '%s', %d, %d, 1, 1)", $sid, $langcode, $translation, $uid, time());
       $suggested++;
     }
@@ -847,7 +852,7 @@ function l10n_community_project_uri_by_t
  * Check whether $suggestion is duplicate for $sid in $langcode.
  */
 function l10n_community_is_duplicate($suggestion, $sid, $langcode) {
-  return (bool) db_result(db_query("SELECT s.sid FROM {l10n_community_string} s LEFT JOIN {l10n_community_translation} t ON s.sid = t.sid WHERE t.translation = '%s' AND t.is_active = 1 AND t.language = '%s' AND s.sid = %d", $suggestion, $langcode, $sid));
+  return (bool) db_result(db_query("SELECT s.sid FROM {l10n_community_string} s LEFT JOIN {l10n_community_translation} t ON s.sid = t.sid WHERE t.translation = BINARY '%s' AND t.is_active = 1 AND t.language = '%s' AND s.sid = %d", $suggestion, $langcode, $sid));
 }
 
 // = Theme functions ===========================================================
@@ -1064,3 +1069,58 @@ function l10n_community_cron() {
     variable_set('l10n_cron_stats', $_SERVER['REQUEST_TIME']);
   }
 }
+
+/**
+ * Implementation of hook_form_alter(). Populates translation database with
+ * empty translations for every language added.
+ */
+function l10n_community_form_alter(&$form, $form_state, $form_id) {
+  if ($form_id == 'locale_languages_predefined_form' || $form_id == 'locale_languages_custom_form' || $form_id == 'locale_translate_import_form') {
+    $form['#submit'][] = '_l10n_community_add_language_submit';
+  }
+}
+
+/**
+  * Callback from language add form. Populate translations database by all
+  * untranslated strings.
+  */
+function _l10n_community_add_language_submit($form, &$form_state) {
+  // This is special case of Locale import form with not yet added language.
+  if ($form_state['values']['form_id'] == 'locale_translate_import_form' && in_array($form_state['values']['langcode'], $form['import']['langcode']['#options'][t('Already added languages')])) {
+    return;
+  }
+  l10n_community_populate_translations($langcode);
+}
+
+function l10n_community_populate_translations($langcode) {
+  // Check if there are any already translated strings in database.
+  $result = db_query("SELECT sid FROM {l10n_community_translation} WHERE language = '%d'", $langcode);
+  $strings = array();
+  while ($row = db_fetch_object($q)) {
+    $strings[] = $row->sid;
+  }
+
+  // Select all strings to be inserted in database, excluding already
+  // translated strings.
+  $query = "SELECT sid FROM {l10n_community_string}";
+  if (count($strings)) {
+    $query .= "WHERE sid NOT IN (" . db_placeholders($strings, 'int') . ")";
+  }
+  $result = db_query($query, $strings);
+  while ($row = db_fetch_object($result)) {
+    // Populate database with empty translations.
+    l10n_community_insert_empty_translation($row->sid, $langcode);
+  }
+}
+
+/**
+  * Insert empty translation of string ID $sid into translation table.
+  *
+  * @param $sid
+  *   String ID.
+  * @param $langcode
+  *   Language code.
+  */
+function l10n_community_insert_empty_translation($sid, $langcode) {
+    db_query("INSERT INTO {l10n_community_translation} (sid, translation, language, uid_entered, time_entered, has_suggestion, is_active) VALUES (%d, '', '%s', 0, %d, 1, 1)", $sid, $langcode, time());
+}
Index: translate.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/l10n_server/l10n_community/Attic/translate.inc,v
retrieving revision 1.1.2.7.2.7
diff -u -p -r1.1.2.7.2.7 translate.inc
--- translate.inc	30 Dec 2008 16:57:39 -0000	1.1.2.7.2.7
+++ translate.inc	11 Apr 2009 09:15:55 -0000
@@ -30,6 +30,7 @@ function l10n_community_translate_page($
   $languages = l10n_community_get_languages();
   $perm = l10n_community_get_permission($langcode);
 
+
   // Build filter values for the form generation.
   $project = $release = NULL;
   if (isset($_GET['project']) && ($project = l10n_community_get_projects($_GET['project']))) {
@@ -585,14 +586,14 @@ function l10n_community_get_strings($lan
   
   if (!isset($project)) {
     // No project based filtering.
-    $sql = "SELECT DISTINCT s.sid, s.value, t.tid, t.language, t.translation, t.uid_entered, t.uid_approved, t.time_entered, t.time_approved, t.has_suggestion, t.is_suggestion, t.is_active FROM {l10n_community_string} s LEFT JOIN {l10n_community_translation} t ON s.sid = t.sid AND t.language = '%s' AND t.is_active = 1 AND t.is_suggestion = 0 WHERE";
-    $sql_count = "SELECT COUNT(DISTINCT(s.sid)) FROM {l10n_community_string} s LEFT JOIN {l10n_community_translation} t ON s.sid = t.sid AND t.language = '%s' AND t.is_active = 1 AND t.is_suggestion = 0 WHERE";
+    $sql = "SELECT DISTINCT s.sid, s.value, t.tid, t.language, t.translation, t.uid_entered, t.uid_approved, t.time_entered, t.time_approved, t.has_suggestion, t.is_suggestion, t.is_active FROM {l10n_community_string} s INNER JOIN {l10n_community_translation} t ON s.sid = t.sid AND t.language = '%s' AND t.is_active = 1 AND t.is_suggestion = 0 WHERE";
+    $sql_count = "SELECT COUNT(DISTINCT(s.sid)) FROM {l10n_community_string} s INNER JOIN {l10n_community_translation} t ON s.sid = t.sid AND t.language = '%s' AND t.is_active = 1 AND t.is_suggestion = 0 WHERE";
     $sql_args = array($langcode);
   }
   else {
     // Project based filtering and language based filtering built in.
-    $sql = "SELECT DISTINCT s.sid, s.value, t.tid, t.language, t.translation, t.uid_entered, t.uid_approved, t.time_entered, t.time_approved, t.has_suggestion, t.is_suggestion, t.is_active FROM {l10n_community_release} r INNER JOIN {l10n_community_file} f ON r.rid = f.rid INNER JOIN {l10n_community_line} l ON f.fid = l.fid INNER JOIN {l10n_community_string} s ON l.sid = s.sid LEFT JOIN {l10n_community_translation} t ON s.sid = t.sid AND t.language = '%s' AND t.is_active = 1 AND t.is_suggestion = 0 WHERE r.pid = %d";
-    $sql_count = "SELECT COUNT(DISTINCT(s.sid)) FROM {l10n_community_release} r INNER JOIN {l10n_community_file} f ON r.rid = f.rid INNER JOIN {l10n_community_line} l ON f.fid = l.fid INNER JOIN {l10n_community_string} s ON l.sid = s.sid LEFT JOIN {l10n_community_translation} t ON s.sid = t.sid AND t.language = '%s' AND t.is_active = 1 AND t.is_suggestion = 0 WHERE r.pid = %d";
+    $sql = "SELECT DISTINCT s.sid, s.value, t.tid, t.language, t.translation, t.uid_entered, t.uid_approved, t.time_entered, t.time_approved, t.has_suggestion, t.is_suggestion, t.is_active FROM {l10n_community_line} l INNER JOIN {l10n_community_string} s ON l.sid = s.sid INNER JOIN {l10n_community_translation} t ON s.sid = t.sid AND t.language = '%s' AND t.is_active = 1 AND t.is_suggestion = 0 WHERE l.pid = %d";
+    $sql_count = "SELECT COUNT(DISTINCT(s.sid)) FROM {l10n_community_line} l INNER JOIN {l10n_community_string} s ON l.sid = s.sid INNER JOIN {l10n_community_translation} t ON s.sid = t.sid AND t.language = '%s' AND t.is_active = 1 AND t.is_suggestion = 0 WHERE l.pid = %d";
     $sql_args = array($langcode, $project->pid);
   }
 
@@ -609,7 +610,7 @@ function l10n_community_get_strings($lan
     // Release restriction.
     $sql_args[] = $release;
     $sql_args[] = $release;
-    $release_sql = ' AND r.rid = %d';
+    $release_sql = ' AND l.rid = %d';
     $sql .= $release_sql;
     $sql_count .= $release_sql;
   }
@@ -622,7 +623,7 @@ function l10n_community_get_strings($lan
       // records in the result set in this case). The translation field is empty or
       // NULL in this case, as we are not allowing NULL there and only saving an empty
       // translation if there are suggestions but no translation yet.
-      $status_sql = " AND (t.translation is NULL OR t.translation = '')";
+      $status_sql = " AND t.translation = ''";
       $sql .= $status_sql;
       $sql_count .= $status_sql;
       break;
