Issue Details (XML | Word | Printable)

Key: MDL-4596
Type: Bug Bug
Status: Open Open
Priority: Trivial Trivial
Assignee: Jonathan Harker
Reporter: Imported
Votes: 3
Watchers: 2
Operations

Add/Edit UI Mockup to this issue
If you were logged in you would be able to see more operations.
Moodle

Forum Display Table Nesting Issue

Created: 17/Jan/06 05:34 AM   Updated: 02/Dec/09 06:49 AM
Component/s: Forum, General
Affects Version/s: 1.5.3, 1.8.10, 1.9.6, 2.0
Fix Version/s: 1.9.8

File Attachments: 1. File MDL-4596-fix-truncation-of-forum-posts.diff (0.9 kB)
2. File truncate.php (7 kB)

Environment: Linux

Database: Any
Participants: Imported, Jonathan Harker, Martin Dougiamas, Matthew Davidson and Sam Hemelryk
Security Level: None
Affected Branches: MOODLE_15_STABLE, MOODLE_18_STABLE, MOODLE_19_STABLE, MOODLE_20_STABLE
Fixed Branches: MOODLE_19_STABLE


 Description  « Hide
When displaying a list of forums (mod/forum/index.php...),

If a forum contains an HTML table and the forum is truncated by the parser before the </table> tag is reached, subsequent forums are displayed in a nested table format.



 All   Comments   Change History   Version Control      Sort Order: Ascending order - Click to sort in descending order
Matthew Davidson added a comment - 17/Jul/07 01:21 AM - edited
I've run against this many times because we use the forum as a "site news" thing...and we put pictures in it and we always want to be able to use tables.

I've been working on a project that ran into this same problem....this is how I fixed it. I ran this function after I truncated the posts. It might not be perfect, but it is definately better than the entire page being screwed up because of open table tags.

function closetags($html)
{
$selfclosing = ',img,input,br,hr,';

//put all opened tags into an array
preg_match_all("#<([a-z]+)(?: .*)?(?<![/|/ ])>#iU", $html, $result);
$openedtags=$result[1];

//put all closed tags into an array
preg_match_all("#</([a-z]+)>#iU",$html,$result);
$closedtags=$result[1];
$len_opened = count($openedtags);

//all tags are closed
if(count($closedtags) == $len_opened)

{ return $html; }

$openedtags = array_reverse($openedtags);

//close tags
for($i=0;$i < $len_opened;$i++)
{
$temp = $openedtags[$i];
switch ($openedtags[$i])
{
case strstr($selfclosing,",$temp,"):
break;
default:
if (!in_array($openedtags[$i],$closedtags))

{ $html .= '</'.$openedtags[$i].'>'; }

else

{ unset($closedtags[array_search($openedtags[$i],$closedtags)]); }

}
}
return $html;
}


Jonathan Harker added a comment - 13/Dec/07 07:06 AM - edited
If you are running PHP5 and have the php-tidy extension installed, this bug can also fixed in the forum_shorten_post() function in mod/forum/lib.php:
-   return substr($message, 0, $truncate);
+   $truncatedpost = substr($message, 0, $truncate);
+   if (function_exists('tidy_repair_string')) { // requires php-tidy extension
+       return tidy_repair_string($truncatedpost);
+   } else {
+       return $truncatedpost;
+   }

Jonathan Harker added a comment - 02/Nov/09 08:09 AM
Applies cleanly to CVS HEAD (2.0), MOODLE_19_STABLE, and MOODLE_18_STABLE.

Jonathan Harker added a comment - 02/Nov/09 08:09 AM
Fix relies on the php-tidy extension, falls back to normal (broken) behaviour if the extension is absent. This is a silent dependence on php-tidy, so I'm not sure whether to add it to admin/environment.xml as an optional module, or fix it permanently by making it required (I imagine on HEAD only as we probably don't want to clobber existing 1.8 and 1.9 hosting environments).

Comments on the above please - I'd like to commit this soon

Cheers, J


Martin Dougiamas added a comment - 02/Nov/09 10:35 AM
I think putting it in environment checks as optional is a good idea, and keep the code exactly as you have it. Great, thanks!

Sam Hemelryk added a comment - 02/Nov/09 10:48 AM
Hi Jonathan,

Just an idea but maybe we should think about creating a truncate function that respects HTML tags and does some other nice stuff at the same time.
This would allow us to use the function in other places and doesn't rely on HTML tidy.

I've had think about how this function would, or could operate and came up with the solution in the attached truncate.php file.
I am aware of potentially a couple of issues, such that the function relies on properly nested HTML (don't know what the output would be like with bad html) and expects the first > after a < to be the closing of a tag... really it just expects chars to be encoded properly.
Have a read of the comments for the function and let me know what you think

Cheers
Sam


Martin Dougiamas added a comment - 02/Nov/09 11:17 AM
Looks good Sam. Perhaps we could use a function like this when HTML tidy isn't present, Jonathan?

Jonathan Harker added a comment - 02/Nov/09 12:22 PM
Ah, true enough In that case, do we want to just add sam's code to 1.8 and 1.9, and use it in the fallback? In 2.0 we could get away with making php-tidy required.

Jonathan Harker added a comment - 02/Dec/09 06:49 AM
Sorry I've been swamped - I'll try to get on to committing it this week.