Permalink
Browse files

BUGFIX Better handling of multibyte strings in LimitCharacters(), rem…

…oved code duplication by more flexible base implementation at StringField->LimitCharacters() (Merge pull request #121 from edlund/sapphire)
  • Loading branch information...
1 parent dd495fb commit 0c3af805147d9698b4bab9a8e8f35ec0ba95b7da @chillu chillu committed Dec 16, 2011
@@ -13,30 +13,6 @@
class HTMLText extends Text {
public static $escape_type = 'xml';
-
- /**
- * Limit this field's content by a number of characters.
- * This makes use of strip_tags() to avoid malforming the
- * HTML tags in the string of text.
- *
- * @param int $limit Number of characters to limit by
- * @param string $add Ellipsis to add to the end of truncated string
- * @return string
- */
- function LimitCharacters($limit = 20, $add = "...") {
- $value = trim(strip_tags($this->value));
-
- // Content html text to plan text before sub string-ing
- // to cutting off part of the html entity character
- // For example, & because &am
- $value = html_entity_decode($value, ENT_COMPAT, 'UTF-8');
- $value = (strlen($value) > $limit) ? substr($value, 0, $limit) . $add : $value;
-
- // Convert plan text back to html entities
- $value = htmlentities($value, ENT_COMPAT, 'UTF-8');
-
- return $value;
- }
/**
* Create a summary of the content. This will be some section of the first paragraph, limited by
@@ -147,4 +123,4 @@ public function scaffoldSearchField($title = null) {
}
-?>
+?>
@@ -25,7 +25,5 @@ public function scaffoldFormField($title = null, $params = null) {
public function scaffoldSearchField($title = null) {
return new TextField($this->name, $title);
}
-
-}
-
-?>
+
+}
@@ -73,20 +73,42 @@ function prepValueForDB($value) {
return parent::prepValueForDB($value);
}
}
-
+
+ /**
+ * Limit this field's content by a number of characters.
+ * This makes use of strip_tags() to avoid malforming the
+ * HTML tags in the string of text.
+ *
+ * @param int $limit Number of characters to limit by
+ * @param string $add Ellipsis to add to the end of truncated string
+ * @return string
+ */
+ function LimitCharacters($limit, $add = '...') {
+ $value = trim($this->value);
+ if($this->stat('escape_type') == 'xml') {
+ $value = strip_tags($value);
+ $value = html_entity_decode($value, ENT_COMPAT, 'UTF-8');
+ $value = (mb_strlen($value) > $limit) ? mb_substr($value, 0, $limit) . $add : $value;
+ // Avoid encoding all multibyte characters as HTML entities by using htmlspecialchars().
+ $value = htmlspecialchars($value, ENT_COMPAT, 'UTF-8');
+ } else {
+ $value = (mb_strlen($value) > $limit) ? mb_substr($value, 0, $limit) . $add : $value;
+ }
+ return $value;
+ }
/**
* Return another DBField object with this value in lowercase.
*/
function Lower() {
- return DBField::create(get_class($this), strtolower($this->value), $this->name);
+ return DBField::create(get_class($this), mb_strtolower($this->value), $this->name);
}
/**
* Return another DBField object with this value in uppercase.
*/
function Upper() {
- return DBField::create(get_class($this), strtoupper($this->value), $this->name);
+ return DBField::create(get_class($this), mb_strtoupper($this->value), $this->name);
}
}
View
@@ -77,20 +77,6 @@ function AbsoluteLinks() {
return HTTP::absoluteURLs($this->value);
}
- /**
- * Limit this field's content by a number of characters.
- * CAUTION: Does not take into account HTML tags, so it
- * has the potential to return malformed HTML.
- *
- * @param int $limit Number of characters to limit by
- * @param string $add Ellipsis to add to the end of truncated string
- * @return string
- */
- function LimitCharacters($limit = 20, $add = "...") {
- $value = trim($this->value);
- return (strlen($value) > $limit) ? substr($value, 0, $limit) . $add : $value;
- }
-
/**
* Limit the number of words of the current field's
* content. This is XML safe, so characters like &
@@ -159,9 +145,10 @@ function Summary($maxWords = 50) {
return "";
// grab the first paragraph, or, failing that, the whole content
- if( strpos( $data, "\n\n" ) )
- $data = substr( $data, 0, strpos( $data, "\n\n" ) );
-
+ $pos = strpos( $data, "\n\n" );
+ if( $pos )
+ $data = substr( $data, 0, $pos );
+
$sentences = explode( '.', $data );
$count = count( explode( ' ', $sentences[0] ) );
@@ -241,8 +228,9 @@ function FirstParagraph($plain = 1) {
if( !$data ) return "";
// grab the first paragraph, or, failing that, the whole content
- if( strpos( $data, "\n\n" ) )
- $data = substr( $data, 0, strpos( $data, "\n\n" ) );
+ $pos = strpos( $data, "\n\n" );
+ if( $pos )
+ $data = substr( $data, 0, $pos );
return $data;
@@ -69,18 +69,7 @@ function URL() {
function RTF() {
return str_replace("\n", '\par ', $this->value);
}
-
- /**
- * Returns the value of the string, limited to the specified number of characters
- * @param $limit int Character limit
- * @param $add string Extra string to add to the end of the limited string
- * @return string
- */
- function LimitCharacters($limit = 20, $add = "...") {
- $value = trim($this->value);
- return (strlen($value) > $limit) ? substr($value, 0, $limit) . $add : $value;
- }
-
+
/**
* (non-PHPdoc)
* @see DBField::scaffoldFormField()
@@ -192,6 +192,31 @@ function testHasValue() {
$textField->setValue(null);
$this->assertFalse($textField->hasValue());
}
+
+ function testStringFieldsWithMultibyteData() {
+ $plainFields = array('Varchar', 'Text');
+ $htmlFields = array('HTMLVarchar', 'HTMLText');
+ $allFields = array_merge($plainFields, $htmlFields);
+
+ $value = 'üåäöÜÅÄÖ';
+ foreach ($allFields as $stringField) {
+ $stringField = DBField::create($stringField, $value);
+ for ($i = 1; $i < mb_strlen($value); $i++) {
+ $expected = mb_substr($value, 0, $i) . '...';
+ $this->assertEquals($expected, $stringField->LimitCharacters($i));
+ }
+ }
+
+ $value = '<p>üåäö&amp;ÜÅÄÖ</p>';
+ foreach ($htmlFields as $stringField) {
+ $stringField = DBField::create($stringField, $value);
+ $this->assertEquals('üåäö&amp;ÜÅÄ...', $stringField->LimitCharacters(8));
+ }
+
+ $this->assertEquals('ÅÄÖ', DBField::create('Text', 'åäö')->Upper()->getValue());
+ $this->assertEquals('åäö', DBField::create('Text', 'ÅÄÖ')->Lower()->getValue());
+ }
+
}
?>

0 comments on commit 0c3af80

Please sign in to comment.