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';
|
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
|
* 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
|
* $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.
|
* Return another DBField object with this value in lowercase.
|
||||||
*/
|
*/
|
||||||
function Lower() {
|
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.
|
* Return another DBField object with this value in uppercase.
|
||||||
*/
|
*/
|
||||||
function Upper() {
|
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);
|
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
|
* Limit the number of words of the current field's
|
||||||
* content. This is XML safe, so characters like &
|
* content. This is XML safe, so characters like &
|
||||||
@ -159,8 +145,9 @@ class Text extends StringField {
|
|||||||
return "";
|
return "";
|
||||||
|
|
||||||
// grab the first paragraph, or, failing that, the whole content
|
// grab the first paragraph, or, failing that, the whole content
|
||||||
if( strpos( $data, "\n\n" ) )
|
$pos = strpos( $data, "\n\n" );
|
||||||
$data = substr( $data, 0, strpos( $data, "\n\n" ) );
|
if( $pos )
|
||||||
|
$data = substr( $data, 0, $pos );
|
||||||
|
|
||||||
$sentences = explode( '.', $data );
|
$sentences = explode( '.', $data );
|
||||||
|
|
||||||
@ -241,8 +228,9 @@ class Text extends StringField {
|
|||||||
if( !$data ) return "";
|
if( !$data ) return "";
|
||||||
|
|
||||||
// grab the first paragraph, or, failing that, the whole content
|
// grab the first paragraph, or, failing that, the whole content
|
||||||
if( strpos( $data, "\n\n" ) )
|
$pos = strpos( $data, "\n\n" );
|
||||||
$data = substr( $data, 0, strpos( $data, "\n\n" ) );
|
if( $pos )
|
||||||
|
$data = substr( $data, 0, $pos );
|
||||||
|
|
||||||
return $data;
|
return $data;
|
||||||
|
|
||||||
|
@ -70,17 +70,6 @@ class Varchar extends StringField {
|
|||||||
return str_replace("\n", '\par ', $this->value);
|
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)
|
* (non-PHPdoc)
|
||||||
* @see DBField::scaffoldFormField()
|
* @see DBField::scaffoldFormField()
|
||||||
|
@ -192,6 +192,31 @@ class DBFieldTest extends SapphireTest {
|
|||||||
$textField->setValue(null);
|
$textField->setValue(null);
|
||||||
$this->assertFalse($textField->hasValue());
|
$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