Browse Source

mergeQuotes for TypographicBehavior

euromark 13 years ago
parent
commit
4a4e7d5bd6

+ 33 - 22
Model/Behavior/TypographicBehavior.php

@@ -13,6 +13,11 @@ App::uses('ModelBehavior', 'Model');
  * according to the language/regional setting (in some languages
  * the high-high smart quotes, in others the low-high ones are preferred)
  *
+ * Settings are:
+ * - string $before (validate/save)
+ * - array $fields (leave empty for auto detection)
+ * - bool $mergeQuotes (merge single and double into " or any custom char)
+ *
  * @link http://en.wikipedia.org/wiki/Non-English_usage_of_quotation_marks
  * @cakephp 2.x
  * @license MIT
@@ -20,15 +25,15 @@ App::uses('ModelBehavior', 'Model');
  */
 class TypographicBehavior extends ModelBehavior {
 
-	protected $map = array(
+	protected $_map = array(
 		'in' => array(
-			'‘' => '"',
+			'‘' => '\'',
 			//'‘' => '"', # ‘
-			'’' => '"',
+			'’' => '\'',
 			//'’' => '"', # ’
-			'‚' => '"',
+			'‚' => '\'',
 			//'‚' => '"', # ‚
-			'‛' => '"',
+			'‛' => '\'',
 			//'‛' => '"', # ‛
 			'“' => '"',
 			//'“' => '"', # “
@@ -42,9 +47,9 @@ class TypographicBehavior extends ModelBehavior {
 			//'«' => '"', # «
 			'»' => '"',
 			//'»' => '"', # »
-			'‹' => '"',
+			'‹' => '\'',
 			//'«' => '"', # ‹
-			'›' => '"',
+			'›' => '\'',
 			//'»' => '"', # ›
 		),
 		'out'=> array(
@@ -52,6 +57,12 @@ class TypographicBehavior extends ModelBehavior {
 		),
 	);
 
+	protected $_defaults = array(
+		'before' => 'save',
+		'fields' => array(),
+		'mergeQuotes' => false, // set to true for " or explicitly set a char (" or ')
+	);
+
 	/**
 	 * Initiate behavior for the model using specified settings. Available settings:
 	 *
@@ -62,15 +73,11 @@ class TypographicBehavior extends ModelBehavior {
 	 * 2011-12-06 ms
 	 */
 	public function setup(Model $Model, $settings = array()) {
-		$default = array(
-			'before' => 'save',
-			'fields' => array()
-		);
 		if (!isset($this->settings[$Model->alias])) {
-			$this->settings[$Model->alias] = $default;
+			$this->settings[$Model->alias] = $this->_defaults;
 		}
+		$this->settings[$Model->alias] = array_merge($this->settings[$Model->alias], $settings);
 
-		$this->settings[$Model->alias] = array_merge($this->settings[$Model->alias], is_array($settings) ? $settings : array());
 		if (empty($this->settings[$Model->alias]['fields'])) {
 			$schema = $Model->schema();
 			$fields = array();
@@ -88,6 +95,9 @@ class TypographicBehavior extends ModelBehavior {
 			}
 			$this->settings[$Model->alias]['fields'] = $fields;
 		}
+		if ($this->settings[$Model->alias]['mergeQuotes'] === true) {
+			$this->settings[$Model->alias]['mergeQuotes'] = '"';
+		}
 	}
 
 
@@ -127,7 +137,7 @@ class TypographicBehavior extends ModelBehavior {
 				if (empty($record[$Model->alias][$field])) {
 					continue;
 				}
-				$tmp = $this->_prepareInput($record[$Model->alias][$field]);
+				$tmp = $this->_prepareInput($Model, $record[$Model->alias][$field]);
 				if ($tmp == $record[$Model->alias][$field]) {
 					continue;
 				}
@@ -154,7 +164,7 @@ class TypographicBehavior extends ModelBehavior {
 	public function process(Model $Model, $return = true) {
 		foreach ($this->settings[$Model->alias]['fields'] as $field) {
 			if (!empty($Model->data[$Model->alias][$field])) {
-				$Model->data[$Model->alias][$field] = $this->_prepareInput($Model->data[$Model->alias][$field]);
+				$Model->data[$Model->alias][$field] = $this->_prepareInput($Model, $Model->data[$Model->alias][$field]);
 			}
 		}
 
@@ -166,13 +176,14 @@ class TypographicBehavior extends ModelBehavior {
 	 * @return string $cleanedInput
 	 * 2011-12-06 ms
 	 */
-	protected function _prepareInput($string) {
-		$map = $this->map['in'];
-
-		//return $string;
-
-		$string = str_replace(array_keys($map), array_values($map), $string);
-		return $string;
+	protected function _prepareInput(Model $Model, $string) {
+		$map = $this->_map['in'];
+		if ($this->settings[$Model->alias]['mergeQuotes']) {
+   		foreach ($map as $key => $val) {
+				$map[$key] = $this->settings[$Model->alias]['mergeQuotes'];
+   		}
+		}
+		return str_replace(array_keys($map), array_values($map), $string);
 	}
 
 }

+ 26 - 2
Test/Case/Model/Behavior/TypographicBehaviorTest.php

@@ -37,9 +37,9 @@ class TypographicBehaviorTest extends MyCakeTestCase {
 		$this->assertSame($data, $res['Article']);
 
 		$strings = array(
-			'some string with ‹single angle quotes›' => 'some string with "single angle quotes"',
+			'some string with ‹single angle quotes›' => 'some string with \'single angle quotes\'',
 			'other string with „German‟ quotes' => 'other string with "German" quotes',
-			'mixed single ‚one‛ and ‘two’.' => 'mixed single "one" and "two".',
+			'mixed single ‚one‛ and ‘two’.' => 'mixed single \'one\' and \'two\'.',
 			'mixed double “one” and «two».' => 'mixed double "one" and "two".',
 		);
 		foreach ($strings as $was => $expected) {
@@ -58,6 +58,30 @@ class TypographicBehaviorTest extends MyCakeTestCase {
 
 	}
 
+	public function testMergeQuotes() {
+		$this->Model->Behaviors->detach('Typographic');
+		$this->Model->Behaviors->attach('Tools.Typographic', array('before' => 'validate', 'mergeQuotes' => true));
+		$strings = array(
+			'some string with ‹single angle quotes›' => 'some string with "single angle quotes"',
+			'other string with „German‟ quotes' => 'other string with "German" quotes',
+			'mixed single ‚one‛ and ‘two’.' => 'mixed single "one" and "two".',
+			'mixed double “one” and «two».' => 'mixed double "one" and "two".',
+		);
+		foreach ($strings as $was => $expected) {
+			$data = array(
+				'title' => 'some «cool» title',
+				'body' => $was
+			);
+			$this->Model->set($data);
+			$res = $this->Model->validates();
+			$this->assertTrue($res);
+
+			$res = $this->Model->data;
+			$this->assertSame('some "cool" title', $res['Article']['title']);
+			$this->assertSame($expected, $res['Article']['body']);
+		}
+	}
+
 	/**
 	 * test that not defining fields results in all textarea and text fields being processed
 	 * 2012-08-07 ms