mirror of
https://github.com/moodle/moodle.git
synced 2025-04-15 13:33:52 +02:00
MDL-20537: shorten-text fix
This commit is contained in:
parent
9199f8d323
commit
9467db390c
@ -7735,13 +7735,19 @@ function shorten_text($text, $ideal=30, $exact = false, $ending='...') {
|
||||
return $text;
|
||||
}
|
||||
|
||||
// splits all html-tags to scanable lines
|
||||
// Splits on HTML tags. Each open/close/empty tag will be the first thing
|
||||
// and only tag in its 'line'
|
||||
preg_match_all('/(<.+?>)?([^<>]*)/s', $text, $lines, PREG_SET_ORDER);
|
||||
|
||||
$total_length = strlen($ending);
|
||||
$open_tags = array();
|
||||
$truncate = '';
|
||||
|
||||
// This array stores information about open and close tags and their position
|
||||
// in the truncated string. Each item in the array is an object with fields
|
||||
// ->open (true if open), ->tag (tag name in lower case), and ->pos
|
||||
// (byte position in truncated text)
|
||||
$tagdetails = array();
|
||||
|
||||
foreach ($lines as $line_matchings) {
|
||||
// if there is any html-tag in this line, handle it and add it (uncounted) to the output
|
||||
if (!empty($line_matchings[1])) {
|
||||
@ -7750,15 +7756,14 @@ function shorten_text($text, $ideal=30, $exact = false, $ending='...') {
|
||||
// do nothing
|
||||
// if tag is a closing tag (f.e. </b>)
|
||||
} else if (preg_match('/^<\s*\/([^\s]+?)\s*>$/s', $line_matchings[1], $tag_matchings)) {
|
||||
// delete tag from $open_tags list
|
||||
$pos = array_search($tag_matchings[1], array_reverse($open_tags, true)); // can have multiple exact same open tags, close the last one
|
||||
if ($pos !== false) {
|
||||
unset($open_tags[$pos]);
|
||||
}
|
||||
// record closing tag
|
||||
$tagdetails[] = (object)array('open'=>false,
|
||||
'tag'=>strtolower($tag_matchings[1]), 'pos'=>strlen($truncate));
|
||||
// if tag is an opening tag (f.e. <b>)
|
||||
} else if (preg_match('/^<\s*([^\s>!]+).*?>$/s', $line_matchings[1], $tag_matchings)) {
|
||||
// add tag to the beginning of $open_tags list
|
||||
array_unshift($open_tags, strtolower($tag_matchings[1]));
|
||||
// record opening tag
|
||||
$tagdetails[] = (object)array('open'=>true,
|
||||
'tag'=>strtolower($tag_matchings[1]), 'pos'=>strlen($truncate));
|
||||
}
|
||||
// add html-tag to $truncate'd text
|
||||
$truncate .= $line_matchings[1];
|
||||
@ -7821,6 +7826,24 @@ function shorten_text($text, $ideal=30, $exact = false, $ending='...') {
|
||||
// add the defined ending to the text
|
||||
$truncate .= $ending;
|
||||
|
||||
// Now calculate the list of open html tags based on the truncate position
|
||||
$open_tags = array();
|
||||
foreach ($tagdetails as $taginfo) {
|
||||
if(isset($breakpos) && $taginfo->pos >= $breakpos) {
|
||||
// Don't include tags after we made the break!
|
||||
break;
|
||||
}
|
||||
if($taginfo->open) {
|
||||
// add tag to the beginning of $open_tags list
|
||||
array_unshift($open_tags, $taginfo->tag);
|
||||
} else {
|
||||
$pos = array_search($taginfo->tag, array_reverse($open_tags, true)); // can have multiple exact same open tags, close the last one
|
||||
if ($pos !== false) {
|
||||
unset($open_tags[$pos]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// close all unclosed html-tags
|
||||
foreach ($open_tags as $tag) {
|
||||
$truncate .= '</' . $tag . '>';
|
||||
|
@ -354,6 +354,34 @@ class moodlelib_test extends UnitTestCase {
|
||||
$this->assertFalse(make_user_directory(true, true));
|
||||
|
||||
}
|
||||
|
||||
function test_shorten_text() {
|
||||
$text = "short text already no tags";
|
||||
$this->assertEqual($text, shorten_text($text));
|
||||
|
||||
$text = "<p>short <b>text</b> already</p><p>with tags</p>";
|
||||
$this->assertEqual($text, shorten_text($text));
|
||||
|
||||
$text = "long text without any tags blah de blah blah blah what";
|
||||
$this->assertEqual('long text without any tags ...', shorten_text($text));
|
||||
|
||||
$text = "<div class='frog'><p><blockquote>Long text with tags that will ".
|
||||
"be chopped off but <b>should be added back again</b></blockquote></p></div>";
|
||||
$this->assertEqual("<div class='frog'><p><blockquote>Long text with " .
|
||||
"tags that ...</blockquote></p></div>", shorten_text($text));
|
||||
|
||||
$text = "some text which shouldn't break there";
|
||||
$this->assertEqual("some text which shouldn't ...",
|
||||
shorten_text($text, 31));
|
||||
$this->assertEqual("some text which shouldn't ...",
|
||||
shorten_text($text, 30));
|
||||
|
||||
// This case caused a bug up to 1.9.5
|
||||
$text = "<h3>standard 'break-out' sub groups in TGs?</h3> <<There are several";
|
||||
$this->assertEqual("<h3>standard 'break-out' sub groups in ...</h3>",
|
||||
shorten_text($text, 43));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
|
Loading…
x
Reference in New Issue
Block a user