From 8192522e6381418565f5e1ae75ac809ea9feb807 Mon Sep 17 00:00:00 2001 From: Penny Leach Date: Fri, 18 Dec 2009 13:44:35 +0000 Subject: [PATCH] portfolio: MDL-21156 portfolio export format specific pluginfile handling --- lib/portfolio/formats.php | 123 +++++++++++++++++++++++++------------- lib/portfoliolib.php | 66 ++++++++++++++++++++ 2 files changed, 148 insertions(+), 41 deletions(-) diff --git a/lib/portfolio/formats.php b/lib/portfolio/formats.php index fdf86b80eb..f4899561ff 100644 --- a/lib/portfolio/formats.php +++ b/lib/portfolio/formats.php @@ -29,25 +29,22 @@ */ /** -* the most basic type - pretty much everything is a subtype -*/ -class portfolio_format_file { + * base class to inherit from + * do not use this anywhere in supported_formats + */ +abstract class portfolio_format { /** * array of mimetypes this format supports */ - public static function mimetypes() { - return array(null); - } + public static abstract function mimetypes(); /** * for multipart formats, eg html with attachments, * we need to have a directory to place associated files in * inside the zip file. this is the name of that directory */ - public static function get_file_directory() { - return null; - } + public static abstract function get_file_directory(); /** * given a file, return a snippet of markup in whatever format @@ -55,9 +52,40 @@ class portfolio_format_file { * usually involves the path given by {@link get_file_directory} * this is not supported in subclasses of portfolio_format_file * since they're all just single files. + * + * @param stored_file $file + * @param array $options array of options to pass. can contain: + * attributes => hash of existing html attributes (eg title, height, width, etc) + * and whatever the sub class adds into this list + * + * @return string some html or xml or whatever */ - public static function file_output($file) { - throw new portfolio_exception('fileoutputnotsupported', 'portfolio'); + public static abstract function file_output($file, $options=null); + + public static function make_tag($file, $path, $attributes) { + $srcattr = 'href'; + $tag = 'a'; + $content = $file->get_filename(); + if (in_array($file->get_mimetype(), portfolio_format_image::mimetypes())) { + $srcattr = 'src'; + $tag = 'img'; + $content = ''; + } + + $attributes[$srcattr] = $path; // this will override anything we might have been passed (which is good) + $dom = new DomDocument(); + $elem = null; + if ($content) { + $elem = $dom->createElement($tag, $content); + } else { + $elem = $dom->createElement($tag); + } + + foreach ($attributes as $key => $value) { + $elem->setAttribute($key, $value); + } + $dom->appendChild($elem); + return $dom->saveXML($elem); } /** @@ -84,6 +112,24 @@ class portfolio_format_file { } } +/** +* the most basic type - pretty much everything is a subtype +*/ +class portfolio_format_file extends portfolio_format { + + public static function mimetypes() { + return array(); + } + + public static function get_file_directory() { + throw new portfolio_exception('fileoutputnotsupported', 'portfolio'); + } + + public static function file_output($file, $options=null) { + throw new portfolio_exception('fileoutputnotsupported', 'portfolio'); + } +} + /** * image format, subtype of file. */ @@ -145,27 +191,12 @@ class portfolio_format_text extends portfolio_format_file { * base class for rich formats. * these are multipart - eg things with attachments */ -abstract class portfolio_format_rich { - public static function mimetypes() { - return array(null); - } +abstract class portfolio_format_rich extends portfolio_format { - public static function conflicts($format) { - return false; + public static function mimetypes() { + return array(); } - /** - * given a file, return a snippet of markup in whatever format - * to link to that file. - * usually involves the path given by {@link get_file_directory} - * this is not supported in subclasses of portfolio_format_file - * since they're all just single files. - * - * @param stored_file $file the file to link to - * @param mixed $extras any extra arguments - */ - public static abstract function file_output($file, $extras=null); - } /** @@ -174,14 +205,15 @@ abstract class portfolio_format_rich { */ class portfolio_format_richhtml extends portfolio_format_rich { public static function get_file_directory() { - return 'site_files'; + return 'site_files/'; } - public static function file_output($file, $extras=null) { - $path = self::get_file_directory() . '/' . $file->get_filename(); - if (in_array($file->get_mimetype(), portfolio_format_image::mimetypes())) { - return '' . $file->get_filename() . ''; + public static function file_output($file, $options=null) { + $path = self::get_file_directory() . $file->get_filename(); + $attributes = array(); + if (!empty($options['attributes']) && is_array($options['attributes'])) { + $attributes = $options['attributes']; } - return '' . $file->get_filename() . ''; + return self::make_tag($file, $path, $attributes); } public static function conflicts($format) { // TODO revisit the conflict with file, since we zip here return ($format == PORTFOLIO_FORMAT_PLAINHTML || $format == PORTFOLIO_FORMAT_FILE); @@ -199,16 +231,25 @@ class portfolio_format_leap2a extends portfolio_format_rich { * return the link to a file * * @param stored_file $file - * @param boolean $entry whether the file is a LEAP2A entry or just a bundled file (default false) + * @param array $options can contain the same as normal, with the addition of: + * entry => whether the file is a LEAP2A entry or just a bundled file (default false) */ - public static function file_output($file, $entry=false) { + public static function file_output($file, $options=null) { $id = ''; - if ($entry) { - $id = 'portfolio:file' . $file->get_id; + if (!is_array($options)) { + $options = array(); + } + if (!empty($options['entry'])) { + $path = 'portfolio:file' . $file->get_id; } else { - $id = self::get_file_directory() . '/' . $file->get_filename(); + $path = self::get_file_directory() . $file->get_filename(); + } + $attributes = array(); + if (!empty($options['attributes']) && is_array($options['attributes'])) { + $attributes = $options['attributes']; } - return '' . $file->get_filename() . ''; + $attributes['rel'] = 'enclosure'; + return self::make_tag($file, $path, $attributes); } public static function leap2a_writer(stdclass $user=null) { diff --git a/lib/portfoliolib.php b/lib/portfoliolib.php index a38259b7ae..fa4065a4b7 100644 --- a/lib/portfoliolib.php +++ b/lib/portfoliolib.php @@ -1154,3 +1154,69 @@ function portfolio_existing_exports_by_plugin($userid) { $values = array($userid); return $DB->get_records_sql_menu($sql, $values); } + + +/** + * callback function from {@link portfolio_rewrite_pluginfile_urls} + * looks through preg_replace matches and replaces content with whatever the active portfolio export format says + */ +function portfolio_rewrite_pluginfile_url_callback($contextid, $filearea, $itemid, $format, $options, $matches) { + $matches = $matches[0]; // no internal matching + $dom = new DomDocument(); + if (!$dom->loadXML($matches)) { + return $matches; + } + $attributes = array(); + foreach ($dom->documentElement->attributes as $attr => $node) { + $attributes[$attr] = $node->value; + } + // now figure out the file + $fs = get_file_storage(); + $key = 'href'; + if (!array_key_exists('href', $attributes) && array_key_exists('src', $attributes)) { + $key = 'src'; + } + if (!array_key_exists($key, $attributes)) { + debugging('Couldn\'t find an attribute to use that contains @@PLUGINFILE@@ in portfolio_rewrite_pluginfile'); + return $matches; + } + $filename = substr($attributes[$key], strpos($attributes[$key], '@@PLUGINFILE@@') + strlen('@@PLUGINFILE@@')); + $filepath = '/'; + if (strpos($filename, '/') !== 0) { + $bits = explode('/', $filename); + $filename = array_pop($bits); + $filepath = implode('/', $bits); + } + if (!$file = $fs->get_file($contextid, $filearea, $itemid, $filepath, $filename)) { + debugging("Couldn\t find a file from the embedded path info context $contextid filearea $filearea itemid $itemid filepath $filepath name $filename"); + return $matches; + } + if (empty($options)) { + $options = array(); + } + $options['attributes'] = $attributes; + return $format->file_output($file, $options); +} + + +/** + * go through all the @@PLUGINFILE@@ matches in some text, + * extract the file information and pass it back to the portfolio export format + * to regenerate the html to output + * + * @param string $text the text to search through + * @param int $contextid normal file_area arguments + * @param string $filearea normal file_area arguments + * @param int $itemid normal file_area arguments + * @param portfolio_format $format the portfolio export format + * @param array $options extra options to pass through to the file_output function in the format (optional) + * + * @return string + */ +function portfolio_rewrite_pluginfile_urls($text, $contextid, $filearea, $itemid, $format, $options=null) { + $pattern = '/(<[^<]*?="@@PLUGINFILE@@\/[^>]*?(?:\/>|>.*?<\/[^>]*?>))/'; + $callback = partial('portfolio_rewrite_pluginfile_url_callback', $contextid, $filearea, $itemid, $format, $options); + return preg_replace_callback($pattern, $callback, $text); +} +// this function has to go last, because the regexp screws up syntax highlighting in some editors + -- 2.39.5