Index: includes/common.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/common.inc,v retrieving revision 1.863 diff -u -p -r1.863 common.inc --- includes/common.inc 3 Feb 2009 18:55:29 -0000 1.863 +++ includes/common.inc 4 Feb 2009 04:07:02 -0000 @@ -3965,6 +3965,146 @@ function drupal_write_record($table, &$o } /** + * Load a record from the database, consulting the schema if necessary. + * + * @param $table + * The name of the table; this must exist in schema API. + * @param $alias + * An alias for the table. + * @param $conditions + * An ID or array of conditions to apply to the query. + * @param $fields + * Array: the names of the fields to be returned. If empty, all fields will be + * returned. + * @param $alter + * Boolean, whether to pass the results through drupal_alter(). + * @return + * An array of all matching records, or false on failure. + */ +function drupal_load_record($table, $alias = NULL, $conditions = array(), $fields = NULL, $alter = FALSE, $unserialize = FALSE) { + $records = drupal_load_records($table, $alias, $conditions, $fields, $alter, $unserialize); + if (!empty($records)) { + return $records[0]; + } + else { + return FALSE; + } +} + +/** + * Load one or more records from the database, consulting the schema if necessary. + * + * @param $table + * The name of the table; this must exist in schema API. + * @param $alias + * An alias for the table. + * @param $conditions + * An array of conditions to apply to the query. + * @param $fields + * Array: the names of the fields to be returned. If empty, all fields will be + * returned. + * @param $alter + * Boolean, whether to pass the results through drupal_alter(). + * @return + * An array of all matching records, or false on failure. + */ +function drupal_load_records($table, $alias = NULL, $conditions = array(), $fields = array(), $alter = FALSE, $unserialize = FALSE) { + + // If no alias was specified, use the full table name. + if (empty($alias)) { + $alias = $table; + } + + // We need schema information if loading by numerical ID or if unserializing + // unserializing without a list of fields to unserialize. + if ((!empty($unserialize) && !is_array($unserialize)) || is_numeric($conditions) || is_numeric(key($conditions))) { + $schema = drupal_get_schema($table); + if (empty($schema)) { + return FALSE; + } + // Accept a numeric ID key or an array of IDs. + if (is_numeric($conditions) || is_numeric(key($conditions))) { + $primary_keys = $schema['primary key']; + if (count($primary_keys) > 1) { + return FALSE; + } + $conditions = array($primary_keys[0], $conditions); + } + } + $query = db_select($table, $alias); + $query->fields($alias, $fields); + foreach ($conditions as $field => $value) { + $query->condition($field, $value, is_array($value) ? 'IN' : '='); + } + + $result = $query->execute()->fetchAll(); + if (empty($result)) { + return FALSE; + } + foreach (array_keys($result) as $key) { + // Send the results for altering if requested. + if ($alter) { + drupal_alter('drupal_read_records', $result[$key], $table); + } + if (!empty($unserialize)) { + // Iterate through result records. + foreach ($result[$key] as $field => $value) { + // If required, unserialize results. + if (in_array($field, $unserialize) || ($unserialize == TRUE && isset($schema['fields'][$field]) && !empty($schema['fields'][$field]['serialize']))) { + $result[$key]->$field = unserialize($value); + } + } + } + } + + return $result; +} + +/** + * Delete one or more records from the database, consulting the schema if + * necessary. + * + * @param $table + * The name of the table. + * @param $alias + * An alias for the table. + * @param $conditions + * The conditions to match for deletion. If an integer or array of integers is + * given, these are treated as primary key values with the primary key being + * determined from the schema. Matching criteria may also be fed as an array + * of key-value pairs keyed by field name, in which case the schema is not + * consulted. + * + * @return + * Failure to delete based on missing schema information will return FALSE. + * Otherwise SAVED_DELETED. + */ +function drupal_delete_records($table, $alias, $conditions) { + // If no alias was specified, use the full table name. + if (empty($alias)) { + $alias = $table; + } + + if (is_numeric($conditions) || is_numeric(key($conditions))) { + $schema = drupal_get_schema($table); + if (empty($schema)) { + return FALSE; + } + if (count($schema['primary keys']) > 1) { + return FALSE; + } + $primary_key = current($schema['primary keys']); + $conditions = array($primary_key => $value); + } + $query = db_delete($table, $alias); + foreach ($conditions as $field => $value) { + $query->condition($field, $value, is_array($value) ? 'IN' : '='); + } + + $query->execute(); +} + +/** * @} End of "ingroup schemaapi". */ Index: includes/locale.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/locale.inc,v retrieving revision 1.201 diff -u -p -r1.201 locale.inc --- includes/locale.inc 3 Feb 2009 18:55:29 -0000 1.201 +++ includes/locale.inc 4 Feb 2009 04:07:11 -0000 @@ -778,7 +778,7 @@ function locale_translate_export_po_form */ function locale_translate_edit_form(&$form_state, $lid) { // Fetch source string, if possible. - $source = db_fetch_object(db_query('SELECT source, textgroup, location FROM {locales_source} WHERE lid = %d', $lid)); + $source = locale_source_load($lid); if (!$source) { drupal_set_message(t('String not found.'), 'error'); drupal_goto('admin/build/translate/search'); @@ -874,19 +874,17 @@ function locale_translate_edit_form_vali function locale_translate_edit_form_submit($form, &$form_state) { $lid = $form_state['values']['lid']; foreach ($form_state['values']['translations'] as $key => $value) { - $translation = db_result(db_query("SELECT translation FROM {locales_target} WHERE lid = %d AND language = '%s'", $lid, $key)); + // Only update or insert if we have a value to use. if (!empty($value)) { - // Only update or insert if we have a value to use. - if (!empty($translation)) { - db_query("UPDATE {locales_target} SET translation = '%s' WHERE lid = %d AND language = '%s'", $value, $lid, $key); - } - else { - db_query("INSERT INTO {locales_target} (lid, translation, language) VALUES (%d, '%s', '%s')", $lid, $value, $key); - } + $translation = new StdClass(); + $translation->lid = $lid; + $translation->translation = $value; + $tranlation->language = $key; + locale_target_save($translation); } - elseif (!empty($translation)) { + else { // Empty translation entered: remove existing entry from database. - db_query("DELETE FROM {locales_target} WHERE lid = %d AND language = '%s'", $lid, $key); + locale_target_delete($lid, $key); } // Force JavaScript translation file recreation for this language. @@ -2651,3 +2649,177 @@ function _locale_batch_language_finished /** * @} End of "locale-autoimport" */ + +/** + * @defgroup locale-api Locale CRUD API functions for source and target strings + * @{ + */ + +/** + * Load a locale source record from the database. + * + * @param $lid + * The ID of the record to load. + * @param $fields + * An array of fields to return. If null, all fields will be returned. + * @return + * A matching record, or false on failure. + */ +function locale_source_load($lid, $fields = array()) { + return drupal_load_record('locales_source', 'ls', array('ls.lid' => $lid), $fields); +} + +/** + * Load one or more locale source records from the database. + * + * @param $lids + * An array of IDs of the records to load. + * @param $conditions + * An array field-value pairs to match. Values may be arrays, in which case + * matching will use the 'IN' operator. + * @param $fields + * An array of fields to return. If null, all fields will be returned. + * @return + * An array of all matching records, or false on failure. + */ +function locale_source_load_multiple($lids = array(), $conditions = array(), $fields = array()) { + if (!empty($lids)) { + $conditions['lid'] = $lids; + } + return drupal_load_records('locales_source', 'ls', $conditions, $fields); +} + +/** + * Save a locale source record to the database. + * + * @param $source + * A translation source object. + * @return + * SAVED_NEW, SAVED_UPDATED, or false on failure. + */ +function locale_source_save(&$source) { + return drupal_write_record('locales_source', $source); +} + +/** + * Load a locale target record from the database. + * + * @param $lid + * The ID of the record to load. + * @param $langcode + * The language code of the record to load. + * @param $plural + * The plural value of the record to load. + * @param $fields + * An array of fields to return. If null, all fields will be returned. + * @return + * A matching record, or false on failure. + */ +function locale_target_load($lid, $langcode, $plural = 0, $fields = array()) { + return drupal_load_record('locales_target', 'lt', array('lt.lid' => $lid, 'lt.language' => $langcode, 'lt.plural' => $plural), $fields); +} + +/** + * Load one or more locale target records from the database. + * + * @param $conditions + * An array field-value pairs to match. Values may be arrays, in which case + * matching will use the 'IN' operator. + * @param $fields + * An array of fields to return. If null, all fields will be returned. + * @return + * An array of all matching records, or false on failure. + */ +function locale_target_load_multiple($conditions, $fields = array()) { + return drupal_load_records('locales_target', 'lt', $conditions, $fields); +} + +/** + * Save a locale target record to the database. + * + * @param $target + * A translation target object. + * @return + * SAVED_NEW, SAVED_UPDATED, or false on failure. + */ +function locale_target_save(&$target) { + if (locale_target_load($target->lid, $target->language, $target->plural)) { + return drupal_write_record('locales_target', $target, array('lid', 'language', 'plural')); + } + else { + return drupal_write_record('locales_target', $target); + } +} + +/** + * Delete one or more locale target records from the database. + * + * @param $lids + * An array of IDs of the records to delete. + * @param $conditions + * An array field-value pairs to match. Values may be arrays, in which case + * matching will use the 'IN' operator. + * @return + * An array of all matching records, or false on failure. + */ +function locale_target_delete($lids = NULL, $conditions = array()) { + // Accept one or an array of ID values. + if (!empty($lids)) { + $conditions['lt.lid'] = $lids; + } + drupal_delete_records('locale_target', 'lt', $conditions); +} + + +/** + * Fetch a translation for a source string. + * + * @param $source + * The source string to translate. + * @param $group + * Text group that the source string belongs to. + * @param $location + * Location of the source string. + * @param $langcode + * Language code of the target string. If an array of codes is given, the first + * matched language will be returned. + * @param $plural + * Plural value of the target to be returned. + * @param $return_source + * Boolean: whether to return the original string if no translation is found. + * @return + * A requested translation, the original string if no translation was found, or + * false if no translation was found and $return_source is false. + */ +function locale_get_translation($source, $group, $location, $langcode, $plural = 0, $return_source = TRUE) { + $translations = db_select('locales_target', 'lt') + ->join('locales_source', 'ls', 'ls.lid = lt.lid') + ->condition('lt.plural', $plural) + ->condition('ls.group', $group) + ->condition('ls.group', $group) + ->condition('lt.langcode', $langcode, is_array($langcode) ? 'IN' : '=') + ->fields('lt', array('language', 'translation')) + ->execute() + ->fetchAll(); + if (empty($translations)) { + return $return_source ? $source : FALSE; + } + // If we have an array of request languages, return the first found. + if (is_array($langcode)) { + foreach ($langcode as $code) { + foreach ($translations as $translation) { + if ($translation->language == $code) { + return $translation->translation; + } + } + } + } + else { + $translation = current($translation); + return $translation->translation; + } +} + +/** + * @} End of "locale-api" + */