]> git.mjollnir.org Git - moodle.git/commitdiff
portfolio: MDL-21156 portfolio export format specific pluginfile handling
authorPenny Leach <penny@liip.ch>
Fri, 18 Dec 2009 13:44:35 +0000 (13:44 +0000)
committerPenny Leach <penny@liip.ch>
Fri, 18 Dec 2009 13:44:35 +0000 (13:44 +0000)
lib/portfolio/formats.php
lib/portfoliolib.php

index fdf86b80ebc7d1f98bf313aa2163f4fef821bcae..f4899561ff8b72219825e57d8b5c27f034780056 100644 (file)
  */
 
 /**
-* 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 '<img src="' . $path . '" alt="' . $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 '<a href="' . $path . '">' . $file->get_filename() . '</a>';
+        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 '<a rel="enclosure" href="' . $id . '">' . $file->get_filename() . '</a>';
+        $attributes['rel']    = 'enclosure';
+        return self::make_tag($file, $path, $attributes);
     }
 
     public static function leap2a_writer(stdclass $user=null) {
index a38259b7ae72ad52d0f6fb0cb3ac3e8bf5070f8b..fa4065a4b774e881aaafceff827a11f04095db6c 100644 (file)
@@ -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
+