Browse Source

Restructure internals of Extract task

Use variables which are easily identifiable and an internal storage
structure which prevents duplicates.
AD7six 14 years ago
parent
commit
369d316835
1 changed files with 82 additions and 54 deletions
  1. 82 54
      lib/Cake/Console/Command/Task/ExtractTask.php

+ 82 - 54
lib/Cake/Console/Command/Task/ExtractTask.php

@@ -74,14 +74,7 @@ class ExtractTask extends AppShell {
  *
  * @var array
  */
-	protected $_strings = array();
-
-/**
- * Singular strings and their line numbers.
- *
- * @var array
- */
-	protected $_lines = array();
+	protected $_translations = array();
 
 /**
  * Destination path
@@ -201,6 +194,35 @@ class ExtractTask extends AppShell {
 	}
 
 /**
+ * Add a translation to the internal translations property
+ *
+ * Takes care of duplicate translations
+ *
+ * @param string $domain
+ * @param string $msgid
+ * @param array $details
+ */
+	protected function _addTranslation($domain, $msgid, $details = array()) {
+		if (empty($this->_translations[$domain][$msgid])) {
+			$this->_translations[$domain][$msgid] = array(
+				'msgid_plural' => false
+			 );
+		}
+
+		if (isset($details['msgid_plural'])) {
+			$this->_translations[$domain][$msgid]['msgid_plural'] = $details['msgid_plural'];
+		}
+
+		if (isset($details['file'])) {
+			$line = 0;
+			if (isset($details['line'])) {
+				$line = $details['line'];
+			}
+			$this->_translations[$domain][$msgid]['references'][$details['file']][] = $line;
+		}
+	}
+
+/**
  * Extract text
  *
  * @return void
@@ -221,7 +243,7 @@ class ExtractTask extends AppShell {
 		$this->_buildFiles();
 		$this->_writeFiles();
 		$this->_paths = $this->_files = $this->_storage = array();
-		$this->_strings = $this->_tokens = array();
+		$this->_translations = $this->_tokens = array();
 		$this->_extractValidation = true;
 		$this->out();
 		$this->out(__d('cake_console', 'Done.'));
@@ -254,13 +276,16 @@ class ExtractTask extends AppShell {
 			->addOption('ignore-model-validation', array(
 				'boolean' => true,
 				'default' => false,
-				'help' => __d('cake_console', 'Ignores validation messages in the $validate property. If this flag is not set and the command is run from the same app directory, all messages in model validation rules will be extracted as tokens.')
+				'help' => __d('cake_console', 'Ignores validation messages in the $validate property.' .
+					' If this flag is not set and the command is run from the same app directory,' .
+					' all messages in model validation rules will be extracted as tokens.')
 			))
 			->addOption('validation-domain', array(
 				'help' => __d('cake_console', 'If set to a value, the localization domain to be used for model validation messages.')
 			))
 			->addOption('exclude', array(
-				'help' => __d('cake_console', 'Comma separated list of directories to exclude. Any path containing a path segment with the provided values will be skipped. E.g. test,vendors')
+				'help' => __d('cake_console', 'Comma separated list of directories to exclude.' .
+					' Any path containing a path segment with the provided values will be skipped. E.g. test,vendors')
 			));
 	}
 
@@ -306,7 +331,8 @@ class ExtractTask extends AppShell {
 		$tokenCount = count($this->_tokens);
 
 		while (($tokenCount - $count) > 1) {
-			list($countToken, $firstParenthesis) = array($this->_tokens[$count], $this->_tokens[$count + 1]);
+			$countToken = $this->_tokens[$count];
+			$firstParenthesis = $this->_tokens[$count + 1];
 			if (!is_array($countToken)) {
 				$count++;
 				continue;
@@ -332,10 +358,14 @@ class ExtractTask extends AppShell {
 				if ($mapCount == count($strings)) {
 					extract(array_combine($map, $strings));
 					$domain = isset($domain) ? $domain : 'default';
-
-					$string = isset($plural) ? $singular . "\0" . $plural : $singular;
-					$this->_strings[$domain][] = $string;
-					$this->_lines[$domain][$singular][$this->_file][] = $line;
+					$details = array(
+						'file' => $this->_file,
+						'line' => $line,
+					);
+					if (isset($plural)) {
+						$details['msgid_plural'] = $plural;
+					}
+					$this->_addTranslation($domain, $singular, $details);
 				} else {
 					$this->_markerError($this->_file, $line, $functionName, $count);
 				}
@@ -354,6 +384,7 @@ class ExtractTask extends AppShell {
 		if (!$this->_extractValidation) {
 			return;
 		}
+
 		App::uses('AppModel', 'Model');
 		$plugin = null;
 		if (!empty($this->params['plugin'])) {
@@ -396,28 +427,32 @@ class ExtractTask extends AppShell {
  * @return void
  */
 	protected function _processValidationRules($field, $rules, $file, $domain) {
-		if (is_array($rules)) {
+		if (!is_array($rules)) {
+			return;
+		}
 
-			$dims = Set::countDim($rules);
-			if ($dims == 1 || ($dims == 2 && isset($rules['message']))) {
-				$rules = array($rules);
-			}
+		$dims = Set::countDim($rules);
+		if ($dims == 1 || ($dims == 2 && isset($rules['message']))) {
+			$rules = array($rules);
+		}
 
-			foreach ($rules as $rule => $validateProp) {
-				$message = null;
-				if (isset($validateProp['message'])) {
-					if (is_array($validateProp['message'])) {
-						$message = $validateProp['message'][0];
-					} else {
-						$message = $validateProp['message'];
-					}
-				} elseif (is_string($rule)) {
-					$message = $rule;
-				}
-				if ($message) {
-					$this->_strings[$domain][] = $message;
-					$this->_lines[$domain][$message][$file][] =  'validation for field ' . $field;
+		foreach ($rules as $rule => $validateProp) {
+			$msgid = null;
+			if (isset($validateProp['message'])) {
+				if (is_array($validateProp['message'])) {
+					$msgid = $validateProp['message'][0];
+				} else {
+					$msgid = $validateProp['message'];
 				}
+			} elseif (is_string($rule)) {
+				$msgid = $rule;
+			}
+			if ($msgid) {
+				$details = array(
+					'file' => $file,
+					'line' => 'validation for field ' . $field
+				);
+				$this->_addTranslation($domain, $msgid, $details);
 			}
 		}
 	}
@@ -428,39 +463,28 @@ class ExtractTask extends AppShell {
  * @return void
  */
 	protected function _buildFiles() {
-		foreach ($this->_strings as $domain => $strings) {
-			$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];
+		foreach ($this->_translations as $domain => $translations) {
+			foreach ($translations as $msgid => $details) {
+				$plural = $details['msgid_plural'];
+				$files = $details['references'];
 				$occurrences = array();
 				foreach ($files as $file => $lines) {
+					$lines = array_unique($lines);
 					$occurrences[] = $file . ':' . implode(';', $lines);
 				}
 				$occurrences = implode("\n#: ", $occurrences);
 				$header = '#: ' . str_replace($this->_paths, '', $occurrences) . "\n";
 
-				if ($plural === false && !empty($added[$singular])) {
-					continue;
-				}
-
 				if ($plural === false) {
-					$sentence = "msgid \"{$string}\"\n";
+					$sentence = "msgid \"{$msgid}\"\n";
 					$sentence .= "msgstr \"\"\n\n";
 				} else {
-					$sentence = "msgid \"{$singular}\"\n";
+					$sentence = "msgid \"{$msgid}\"\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);
@@ -506,7 +530,11 @@ class ExtractTask extends AppShell {
 			$response = '';
 			while ($overwriteAll === false && $File->exists() && strtoupper($response) !== 'Y') {
 				$this->out();
-				$response = $this->in(__d('cake_console', 'Error: %s already exists in this location. Overwrite? [Y]es, [N]o, [A]ll', $filename), array('y', 'n', 'a'), 'y');
+				$response = $this->in(
+					__d('cake_console', 'Error: %s already exists in this location. Overwrite? [Y]es, [N]o, [A]ll', $filename),
+					array('y', 'n', 'a'),
+					'y'
+				);
 				if (strtoupper($response) === 'N') {
 					$response = '';
 					while ($response == '') {