Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Fix issues with duplicate msgid values.

Msgid values could be duplicated if the same string was used
for singular and pluralized translations.  Re-index how the data is
stored so duplicate singular detection per domain is easier.

Fixes #2538
  • Loading branch information...
commit 4949a87b7ee4aa66f9a89cdc17bdd87edd86e826 1 parent fa5f175
@markstory markstory authored
View
43 lib/Cake/Console/Command/Task/ExtractTask.php
@@ -70,18 +70,18 @@ class ExtractTask extends AppShell {
protected $_tokens = array();
/**
- * Extracted strings
+ * Extracted strings indexed by domain.
*
* @var array
*/
protected $_strings = array();
/**
- * Extracted sigular strings
+ * Singular strings and their line numbers.
*
* @var array
*/
- protected $_singulars = array();
+ protected $_lines = array();
/**
* Destination path
@@ -332,14 +332,10 @@ protected function _parse($functionName, $map) {
if ($mapCount == count($strings)) {
extract(array_combine($map, $strings));
$domain = isset($domain) ? $domain : 'default';
- if (isset($plural)) {
- if (!isset($_this->_singulars[$domain])) {
- $this->_singulars[$domain] = array();
- }
- array_push($this->_singulars[$domain], $singular);
- }
+
$string = isset($plural) ? $singular . "\0" . $plural : $singular;
- $this->_strings[$domain][$string][$this->_file][] = $line;
+ $this->_strings[$domain][] = $string;
+ $this->_lines[$domain][$singular][$this->_file][] = $line;
} else {
$this->_markerError($this->_file, $line, $functionName, $count);
}
@@ -419,7 +415,8 @@ protected function _processValidationRules($field, $rules, $file, $domain) {
$message = $rule;
}
if ($message) {
- $this->_strings[$domain][$message][$file][] = 'validation for field ' . $field;
+ $this->_strings[$domain][] = $message;
+ $this->_lines[$domain][$message][$file][] = 'validation for field ' . $field;
}
}
}
@@ -432,7 +429,16 @@ protected function _processValidationRules($field, $rules, $file, $domain) {
*/
protected function _buildFiles() {
foreach ($this->_strings as $domain => $strings) {
- foreach ($strings as $string => $files) {
+ $added = array();
+ rsort($strings);
+
+ foreach ($strings as $i => $string) {
+ $plural = false;
+ $singular = $string;
+ if (strpos($string, "\0") !== false) {
+ list($singular, $plural) = explode("\0", $string);
+ }
+ $files = $this->_lines[$domain][$singular];
$occurrences = array();
foreach ($files as $file => $lines) {
$occurrences[] = $file . ':' . implode(';', $lines);
@@ -440,20 +446,21 @@ protected function _buildFiles() {
$occurrences = implode("\n#: ", $occurrences);
$header = '#: ' . str_replace($this->_paths, '', $occurrences) . "\n";
- if (strpos($string, "\0") === false) {
- if (isset($this->_singulars[$domain]) && in_array($string, $this->_singulars[$domain])) {
- continue;
- }
- $sentence = "msgid \"{$string}\"\n";
+ if ($plural === false && !empty($added[$singular])) {
+ continue;
+ }
+
+ if ($plural === false) {
+ $sentence = "msgid \"{$string}\"\n";
$sentence .= "msgstr \"\"\n\n";
} else {
- list($singular, $plural) = explode("\0", $string);
$sentence = "msgid \"{$singular}\"\n";
$sentence .= "msgid_plural \"{$plural}\"\n";
$sentence .= "msgstr[0] \"\"\n";
$sentence .= "msgstr[1] \"\"\n\n";
}
+ $added[$singular] = true;
$this->_store($domain, $header, $sentence);
if ($domain != 'default' && $this->_merge) {
$this->_store('default', $header, $sentence);
View
17 lib/Cake/Test/Case/Console/Command/Task/ExtractTaskTest.php
@@ -93,27 +93,37 @@ public function testExecute() {
// home.ctp
$pattern = '/msgid "Your tmp directory is writable."\nmsgstr ""\n/';
$this->assertRegExp($pattern, $result);
+
$pattern = '/msgid "Your tmp directory is NOT writable."\nmsgstr ""\n/';
$this->assertRegExp($pattern, $result);
+
$pattern = '/msgid "The %s is being used for caching. To change the config edit ';
$pattern .= 'APP\/config\/core.php "\nmsgstr ""\n/';
$this->assertRegExp($pattern, $result);
+
$pattern = '/msgid "Your cache is NOT working. Please check ';
$pattern .= 'the settings in APP\/config\/core.php"\nmsgstr ""\n/';
$this->assertRegExp($pattern, $result);
+
$pattern = '/msgid "Your database configuration file is present."\nmsgstr ""\n/';
$this->assertRegExp($pattern, $result);
+
$pattern = '/msgid "Your database configuration file is NOT present."\nmsgstr ""\n/';
$this->assertRegExp($pattern, $result);
+
$pattern = '/msgid "Rename config\/database.php.default to ';
$pattern .= 'config\/database.php"\nmsgstr ""\n/';
$this->assertRegExp($pattern, $result);
+
$pattern = '/msgid "Cake is able to connect to the database."\nmsgstr ""\n/';
$this->assertRegExp($pattern, $result);
+
$pattern = '/msgid "Cake is NOT able to connect to the database."\nmsgstr ""\n/';
$this->assertRegExp($pattern, $result);
+
$pattern = '/msgid "Editing this Page"\nmsgstr ""\n/';
$this->assertRegExp($pattern, $result);
+
$pattern = '/msgid "To change the content of this page, create: APP\/views\/pages\/home\.ctp/';
$this->assertRegExp($pattern, $result);
@@ -121,10 +131,13 @@ public function testExecute() {
$this->assertRegExp($pattern, $result);
// extract.ctp
- $pattern = '/\#: (\\\\|\/)extract\.ctp:6\n';
+ $pattern = '/\#: (\\\\|\/)extract\.ctp:15;6\n';
$pattern .= 'msgid "You have %d new message."\nmsgid_plural "You have %d new messages."/';
$this->assertRegExp($pattern, $result);
+ $pattern = '/msgid "You have %d new message."\nmsgstr ""/';
+ $this->assertNotRegExp($pattern, $result, 'No duplicate msgid');
+
$pattern = '/\#: (\\\\|\/)extract\.ctp:7\n';
$pattern .= 'msgid "You deleted %d message."\nmsgid_plural "You deleted %d messages."/';
$this->assertRegExp($pattern, $result);
@@ -134,7 +147,7 @@ public function testExecute() {
$pattern .= 'msgid "Editing this Page"\nmsgstr ""/';
$this->assertRegExp($pattern, $result);
- $pattern = '/\#: (\\\\|\/)extract\.ctp:17\nmsgid "';
+ $pattern = '/\#: (\\\\|\/)extract\.ctp:18\nmsgid "';
$pattern .= 'Hot features!';
$pattern .= '\\\n - No Configuration: Set-up the database and let the magic begin';
$pattern .= '\\\n - Extremely Simple: Just look at the name...It\'s Cake';
View
1  lib/Cake/Test/test_app/View/Pages/extract.ctp
@@ -12,6 +12,7 @@ echo __dn('domain', 'You deleted %d message (domain).', 'You deleted %d messages
// Duplicated Message
echo __('Editing this Page');
+echo __('You have %d new message.');
// Multiline
__('Hot features!'
Please sign in to comment.
Something went wrong with that request. Please try again.