mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
BUGFIX Better handling of multibyte strings in LimitCharacters(), removed code duplication by more flexible base implementation at StringField->LimitCharacters() (Merge pull request #121 from edlund/sapphire)
This commit is contained in:
parent
dd495fb8bf
commit
0c3af80514
@ -14,30 +14,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
|
||||
* $maxWords. All internal tags are stripped out - the return value is a string
|
||||
|
@ -27,5 +27,3 @@ class HTMLVarchar extends Varchar {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
@ -74,19 +74,41 @@ abstract class StringField extends DBField {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -77,20 +77,6 @@ class Text extends StringField {
|
||||
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,8 +145,9 @@ class Text extends StringField {
|
||||
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 );
|
||||
|
||||
@ -241,8 +228,9 @@ class Text extends StringField {
|
||||
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;
|
||||
|
||||
|
@ -70,17 +70,6 @@ class Varchar extends StringField {
|
||||
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 @@ class DBFieldTest extends SapphireTest {
|
||||
$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>üåäö&ÜÅÄÖ</p>';
|
||||
foreach ($htmlFields as $stringField) {
|
||||
$stringField = DBField::create($stringField, $value);
|
||||
$this->assertEquals('üåäö&ÜÅÄ...', $stringField->LimitCharacters(8));
|
||||
}
|
||||
|
||||
$this->assertEquals('ÅÄÖ', DBField::create('Text', 'åäö')->Upper()->getValue());
|
||||
$this->assertEquals('åäö', DBField::create('Text', 'ÅÄÖ')->Lower()->getValue());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
|
Loading…
Reference in New Issue
Block a user