From 89708ffc5fd5f3bc51be8360da945b37155e8e21 Mon Sep 17 00:00:00 2001 From: Frederic Massart Date: Tue, 29 Apr 2014 15:15:58 +0800 Subject: [PATCH] MDL-45256 portfolio: Do not require strict XML when parsing content --- lib/portfoliolib.php | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/lib/portfoliolib.php b/lib/portfoliolib.php index 467855ef17e..80335465f29 100644 --- a/lib/portfoliolib.php +++ b/lib/portfoliolib.php @@ -1227,13 +1227,25 @@ function portfolio_format_text_options() { * @return object|array|string */ function portfolio_rewrite_pluginfile_url_callback($contextid, $component, $filearea, $itemid, $format, $options, $matches) { - $matches = $matches[0]; // no internal matching + $matches = $matches[0]; // No internal matching. + + // Loads the HTML. $dom = new DomDocument(); - if (!$dom->loadXML($matches)) { + if (!$dom->loadHTML($matches)) { return $matches; } + + // Navigates to the node. + $xpath = new DOMXPath($dom); + $nodes = $xpath->query('/html/body/child::*'); + if (empty($nodes) || count($nodes) > 1) { + // Unexpected sequence, none or too many nodes. + return $matches; + } + $dom = $nodes->item(0); + $attributes = array(); - foreach ($dom->documentElement->attributes as $attr => $node) { + foreach ($dom->attributes as $attr => $node) { $attributes[$attr] = $node->value; } // now figure out the file @@ -1365,7 +1377,11 @@ function portfolio_include_callback_file($component, $class = null) { * @return mixed */ function portfolio_rewrite_pluginfile_urls($text, $contextid, $component, $filearea, $itemid, $format, $options=null) { - $pattern = '/(<[^<]*?="@@PLUGINFILE@@\/[^>]*?(?:\/>|>.*?<\/[^>]*?>))/'; + $patterns = array( + '(<(a|A)[^<]*?href="@@PLUGINFILE@@/[^>]*?>.*?)', + '(<(img|IMG)\s[^<]*?src="@@PLUGINFILE@@/[^>]*?/?>)', + ); + $pattern = '~' . implode('|', $patterns) . '~'; $callback = partial('portfolio_rewrite_pluginfile_url_callback', $contextid, $component, $filearea, $itemid, $format, $options); return preg_replace_callback($pattern, $callback, $text); }