MDL-16587 bit of a large refactor of the portfolio formats. still more to come.
authormjollnir_ <mjollnir_>
Sat, 11 Oct 2008 17:33:20 +0000 (17:33 +0000)
committermjollnir_ <mjollnir_>
Sat, 11 Oct 2008 17:33:20 +0000 (17:33 +0000)
16 files changed:
lang/en_utf8/portfolio.php
lib/portfolio/caller.php
lib/portfolio/constants.php
lib/portfolio/exporter.php
lib/portfolio/formats.php
lib/portfolio/plugin.php
lib/portfoliolib.php
mod/assignment/lib.php
mod/assignment/type/online/assignment.class.php
mod/assignment/type/upload/assignment.class.php
mod/chat/lib.php
mod/data/lib.php
mod/forum/lib.php
mod/glossary/lib.php
mod/resource/lib.php
portfolio/type/download/lib.php

index a9f0dec..74d338c 100644 (file)
@@ -74,6 +74,8 @@ $string['instancesaved'] = 'Portfolio saved successfully';
 $string['invalidaddformat'] = 'Invalid add format passed to portfolio_add_button. ($a) Must be one of PORTFOLIO_ADD_XXX';
 $string['invalidtempid'] = 'Invalid export id. maybe it has expired';
 $string['invalidfileargument'] = 'Invalid file argument passed to portfolio_format_from_file - must be stored_file object';
+$string['invalidfileareaargs'] = 'Invalid file area arguments passed to set_file_and_format_data - must contain contextid, filearea and itemid';
+$string['invalidsha1file'] = 'Invalid call to get_sha1_file - either single or multifiles must be set';
 $string['invalidformat'] = 'Something is exporting an invalid format, $a';
 $string['invalidinstance'] = 'Could not find that portfolio instance';
 $string['invalidproperty'] = 'Could not find that property ($a->property of $a->class)';
index 4923c8f..cf945be 100644 (file)
@@ -64,6 +64,15 @@ abstract class portfolio_caller_base {
     */
     protected $supportedformats;
 
+    /**
+    * set this for single file exports
+    */
+    protected $singlefile;
+
+    /**
+    * set this for multi file exports
+    */
+    protected $multifiles;
 
     public function __construct($callbackargs) {
         $expected = call_user_func(array(get_class($this), 'expected_callbackargs'));
@@ -122,6 +131,19 @@ abstract class portfolio_caller_base {
     */
     public abstract function expected_time();
 
+    /**
+    * helper method to calculate expected time for multi or single file exports
+    */
+    public function expected_time_file() {
+        if ($this->multifiles) {
+            return portfolio_expected_time_file($this->multifiles);
+        }
+        else if ($this->singlefile) {
+            return portfolio_expected_time_file($this->singlefile);
+        }
+        return PORTFOLIO_TIME_LOW;
+    }
+
     /**
     * used for displaying the navigation during the export screens.
     *
@@ -139,6 +161,24 @@ abstract class portfolio_caller_base {
     */
     public abstract function get_sha1();
 
+    /**
+    * helper function to calculate the sha1 for multi or single file exports
+    */
+    public function get_sha1_file() {
+        if (empty($this->singlefile) && empty($this->multifiles)) {
+            throw new portfolio_caller_exception('invalidsha1file', 'portfolio', $this->get_return_url());
+        }
+        if ($this->singlefile) {
+            return $this->singlefile->get_contenthash();
+        }
+        $sha1s = array();
+        foreach ($this->multifiles as $file) {
+            $sha1s[] = $file->get_contenthash();
+        }
+        asort($sha1s);
+        return sha1(implode('', $sha1s));
+    }
+
     /*
     * generic getter for properties belonging to this instance
     * <b>outside</b> the subclasses
@@ -248,6 +288,19 @@ abstract class portfolio_caller_base {
     */
     public abstract function prepare_package();
 
+    /**
+    * helper function to copy files into the temp area
+    * for single or multi file exports.
+    */
+    public function prepare_package_file() {
+        if ($this->singlefile) {
+            return $this->exporter->copy_existing_file($this->singlefile);
+        }
+        foreach ($this->multifiles as $file) {
+            $this->exporter->copy_existing_file($file);
+        }
+    }
+
     /**
     * array of formats this caller supports
     * the intersection of what this function returns
@@ -299,6 +352,44 @@ abstract class portfolio_caller_base {
 
     public abstract function load_data();
 
+    public function set_file_and_format_data($ids=null /* ..pass arguments to area files here. */) {
+        $args = func_get_args();
+        array_shift($args); // shift off $ids
+        if (empty($ids) && count($args) == 0) {
+            return;
+        }
+        $files = array();
+        $fs = get_file_storage();
+        if (!empty($ids)) {
+            if (is_numeric($ids) || $ids instanceof stored_file) {
+                $ids = array($ids);
+            }
+            foreach ($ids as $id) {
+                if ($id instanceof stored_file) {
+                    $files[] = $id;
+                } else {
+                    $files[] = $fs->get_file_by_id($id);
+                }
+            }
+        } else if (count($args) != 0) {
+            if (count($args) != 3) {
+                throw new portfolio_caller_exception('invalidfileareaargs', 'portfolio');
+            }
+            $files = array_values(call_user_func_array(array($fs, 'get_area_files'), $args));
+        }
+        switch (count($files)) {
+            case 0: return;
+            case 1: {
+                $this->singlefile = $files[0];
+                $this->supportedformats = array(portfolio_format_from_file($this->singlefile));
+                return;
+            }
+            default: {
+                $this->multifiles = $files;
+            }
+        }
+    }
+
     public static abstract function expected_callbackargs();
 
 }
index aae571b..5a0c36a 100644 (file)
@@ -97,9 +97,15 @@ define('PORTFOLIO_FORMAT_FILE', 'file');
 define('PORTFOLIO_FORMAT_MBKP', 'mbkp');
 
 /**
-* html - subtype of file
+* richhtml - like html but with attachments.
 */
-define('PORTFOLIO_FORMAT_HTML', 'html');
+define('PORTFOLIO_FORMAT_RICHHTML', 'richhtml');
+
+
+/**
+* plainhtml - a single html representation - no attachments
+*/
+define('PORTFOLIO_FORMAT_PLAINHTML', 'plainhtml');
 
 /**
 * image - subtype of file
index 5465ef1..6f0c017 100644 (file)
@@ -113,6 +113,12 @@ class portfolio_exporter {
     */
     private $newfilehashes;
 
+    /**
+    * selected exportformat
+    * this is also set in export_config in the portfolio and caller classes
+    */
+    private $format;
+
     /**
     * construct a new exporter for use
     *
@@ -142,6 +148,9 @@ class portfolio_exporter {
     * like name, visible etc.
     */
     public function get($field) {
+        if ($field == 'format') {
+            return portfolio_format_object($this->format);
+        }
         if (property_exists($this, $field)) {
             return $this->{$field};
         }
@@ -320,6 +329,7 @@ class portfolio_exporter {
                 $callerbits['hideformat'] = $pluginbits['hideformat'] = (count($formats) == 1);
                 $this->caller->set_export_config($callerbits);
                 $this->instance->set_export_config($pluginbits);
+                $this->set('format', $fromform->format);
                 return true;
             } else {
                 $this->print_header('configexport');
@@ -338,6 +348,7 @@ class portfolio_exporter {
                 'format' => $format,
                 'hideformat' => 1
             );
+            $this->set('format', $format);
             $this->instance->set_export_config($config);
             $this->caller->set_export_config(array('format' => $format, 'hideformat' => 1));
             if ($expectedtime == PORTFOLIO_TIME_FORCEQUEUE) {
@@ -680,6 +691,9 @@ class portfolio_exporter {
         }
         $fs = get_file_storage();
         $file_record = $this->new_file_record_base($oldfile->get_filename());
+        if ($dir = $this->get('format')->get_file_directory()) {
+            $file_record->filepath = '/'. $dir . '/';
+        }
         try {
             $newfile = $fs->create_file_from_storedfile($file_record, $oldfile->get_id());
             $this->newfilehashes[$newfile->get_contenthash()] = $newfile;
@@ -698,9 +712,12 @@ class portfolio_exporter {
     * @param string $name filename to use
     * @return new stored_file object
     */
-    public function write_new_file($content, $name) {
+    public function write_new_file($content, $name, $manifest=true) {
         $fs = get_file_storage();
         $file_record = $this->new_file_record_base($name);
+        if (empty($manifest) && ($dir = $this->get('format')->get_file_directory())) {
+            $file_record->filepath = '/' . $dir . '/';
+        }
         return $fs->create_file_from_string($file_record, $content);
     }
 
index 8ca8902..982d3f6 100644 (file)
@@ -35,6 +35,14 @@ class portfolio_format_file {
     public static function mimetypes() {
         return array(null);
     }
+
+    public static function get_file_directory() {
+        return null;
+    }
+
+    public static function file_output($file) {
+        return '';
+    }
 }
 
 /**
@@ -51,7 +59,7 @@ class portfolio_format_image extends portfolio_format_file {
 *
 * in case we want to be really specific.
 */
-class portfolio_format_html extends portfolio_format_file {
+class portfolio_format_plainhtml extends portfolio_format_file {
     public static function mimetypes() {
         return array('text/html');
     }
@@ -82,11 +90,33 @@ class portfolio_format_text extends portfolio_format_file {
     }
 }
 
+class portfolio_format_rich {
+    public static function mimetypes() {
+        return array(null);
+    }
+}
+
+class portfolio_format_richhtml extends portfolio_format_rich {
+    public static function get_file_directory() {
+        return 'site_files';
+    }
+    public static function file_output($file) {
+        $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() . '" />';
+        }
+        return '<a href="' . $path . '">' . $file->get_filename() . '</a>';
+    }
+}
+
+class portfolio_format_leap extends portfolio_format_rich { }
+
+
 /**
 * later.... a moodle plugin might support this.
 * it's commented out in portfolio_supported_formats so cannot currently be used.
 */
-class portfolio_format_mbkp extends portfolio_format_file {}
+class portfolio_format_mbkp extends portfolio_format_rich {}
 
 
 ?>
index f6a7240..508da42 100644 (file)
@@ -109,7 +109,17 @@ abstract class portfolio_plugin_base {
     * @return array list of formats
     */
     public static function supported_formats() {
-        return array(PORTFOLIO_FORMAT_FILE);
+        return array(PORTFOLIO_FORMAT_FILE, PORTFOLIO_FORMAT_RICHHTML);
+    }
+
+    /**
+    * override this if you are supporting the 'file' type (or a subformat)
+    * but have restrictions on mimetypes (see googledocs plugin for more info)
+    *
+    * @return boolean
+    */
+    public static function file_mime_check($mimetype) {
+        return true;
     }
 
 
index 7c3924c..24d4b10 100644 (file)
@@ -221,7 +221,9 @@ class portfolio_add_button {
             . $this->callbackclass . '&amp;course=' . (!empty($COURSE) ? $COURSE->id : 0);
         $selectoutput = '';
         if (count($this->instances) == 1) {
-            $instance = array_shift($this->instances);
+            $tmp = array_values($this->instances);
+            $instance = $tmp[0];
+            //$instance = array_shift($this->instances);
             $formats = portfolio_supported_formats_intersect($this->formats, $instance->supported_formats());
             if (count($formats) == 0) {
                 // bail. no common formats.
@@ -457,13 +459,14 @@ function portfolio_instances($visibleonly=true, $useronly=true) {
 */
 function portfolio_supported_formats() {
     return array(
-        PORTFOLIO_FORMAT_FILE  => 'portfolio_format_file',
-        PORTFOLIO_FORMAT_IMAGE => 'portfolio_format_image',
-        PORTFOLIO_FORMAT_HTML  => 'portfolio_format_html',
-        PORTFOLIO_FORMAT_TEXT  => 'portfolio_format_text',
-        PORTFOLIO_FORMAT_VIDEO => 'portfolio_format_video',
+        PORTFOLIO_FORMAT_FILE       => 'portfolio_format_file',
+        PORTFOLIO_FORMAT_IMAGE      => 'portfolio_format_image',
+        PORTFOLIO_FORMAT_RICHHTML   => 'portfolio_format_richhtml',
+        PORTFOLIO_FORMAT_PLAINHTML  => 'portfolio_format_plainhtml',
+        PORTFOLIO_FORMAT_TEXT       => 'portfolio_format_text',
+        PORTFOLIO_FORMAT_VIDEO      => 'portfolio_format_video',
         /*PORTFOLIO_FORMAT_MBKP, */ // later
-        /*PORTFOLIO_FORMAT_PIOP, */ // also later
+        /*PORTFOLIO_FORMAT_LEAP, */ // also later
     );
 }
 
@@ -570,6 +573,18 @@ function portfolio_most_specific_formats($specificformats, $generalformats) {
     return array_merge(array_values($specificformats), array_values($generalformats));
 }
 
+/**
+* helper function to return a format object from the constant
+*
+* @param string $name the constant PORTFOLIO_FORMAT_XXX
+*
+* @return portfolio_format object
+*/
+function portfolio_format_object($name) {
+    $formats = portfolio_supported_formats();
+    return new $formats[$name];
+}
+
 /**
 * helper function to return an instance of a plugin (with config loaded)
 *
index d971507..f1b1bd5 100644 (file)
@@ -1709,7 +1709,7 @@ class assignment_base {
                 $path = $browser->encodepath($CFG->wwwroot.'/pluginfile.php', '/'.$this->context->id.'/assignment_submission/'.$userid.'/'.$filename);
                 $output .= '<a href="'.$path.'" ><img src="'.$CFG->pixpath.'/f/'.$icon.'" class="icon" alt="'.$icon.'" />'.s($filename).'</a>';
                 if ($this->portfolio_exportable() && has_capability('mod/assignment:exportownsubmission', $this->context)) {
-                    $button->set_callback_options('assignment_portfolio_caller', array('id' => $this->cm->id, 'file' => $file->get_id()));
+                    $button->set_callback_options('assignment_portfolio_caller', array('id' => $this->cm->id, 'fileid' => $file->get_id()));
                     $button->set_formats(portfolio_format_from_file($file));
                     $output .= $button->to_html(PORTFOLIO_ADD_ICON_LINK);
                 }
@@ -3138,9 +3138,19 @@ function assignment_get_extra_capabilities() {
 require_once($CFG->libdir . '/portfoliolib.php');
 class assignment_portfolio_caller extends portfolio_module_caller_base {
 
+    /**
+    * the assignment subclass
+    */
     private $assignment;
+
+    /**
+    * the file to include when waking up to load the assignment subclass def
+    */
     private $assignmentfile;
-    private $files;
+
+    /**
+    * callback arg for a single file export
+    */
     protected $fileid;
 
     public static function expected_callbackargs() {
@@ -3171,17 +3181,7 @@ class assignment_portfolio_caller extends portfolio_module_caller_base {
             throw new portfolio_caller_exception('notexportable', 'portfolio', $this->get_return_url());
         }
 
-        $fs = get_file_storage();
-        if ($this->fileid) {
-            $f = $fs->get_file_by_id($this->fileid);
-            $this->files = array($f);
-        } else {
-            $this->files = $fs->get_area_files($this->assignment->context->id, 'assignment_submission', $this->user->id, '', false);
-        }
-        if (is_array($this->files) && count($this->files) == 1) {
-            $f = array_values($this->files);
-            $this->supportedformats = array(portfolio_format_from_file($f[0]));
-        }
+        $this->set_file_and_format_data($this->fileid, $this->assignment->context->id, 'assignment_submission', $this->user->id);
         if (empty($this->supportedformats) && is_callable(array($this->assignment, 'portfolio_supported_formats'))) {
             $this->supportedformats = $this->assignment->portfolio_supported_formats();
         }
@@ -3192,9 +3192,7 @@ class assignment_portfolio_caller extends portfolio_module_caller_base {
         if (is_callable(array($this->assignment, 'portfolio_prepare_package'))) {
             return $this->assignment->portfolio_prepare_package($this->exporter, $this->user->id);
         }
-        foreach ($this->files as $file) {
-            $this->exporter->copy_existing_file($file);
-        }
+        return $this->prepare_package_file();
     }
 
     public function get_sha1() {
@@ -3202,23 +3200,14 @@ class assignment_portfolio_caller extends portfolio_module_caller_base {
         if (is_callable(array($this->assignment, 'portfolio_get_sha1'))) {
             return $this->assignment->portfolio_get_sha1($this->user->id);
         }
-        $sha1s = array();
-        foreach ($this->files as $file) {
-            $sha1s[] = $file->get_contenthash();
-        }
-        asort($sha1s);
-        return sha1(implode('', $sha1s));
-
+        return $this->get_sha1_file();
     }
 
     public function expected_time() {
         if (is_callable(array($this->assignment, 'portfolio_get_expected_time'))) {
             return $this->assignment->portfolio_get_expected_time();
         }
-        if (is_array($this->files)) {
-            return portfolio_expected_time_file($this->files);
-        }
-        return PORTFOLIO_TIME_LOW;
+        return $this->expected_time_file();
     }
 
     public function check_permissions() {
index f4a3ca1..b0685d9 100644 (file)
@@ -275,11 +275,11 @@ class assignment_online extends assignment_base {
 
     function portfolio_prepare_package($exporter, $userid=0) {
         $submission = $this->get_submission($userid);
-        $exporter->write_new_file(format_text($submission->data1, $submission->data2), 'assignment.html');
+        $exporter->write_new_file(format_text($submission->data1, $submission->data2), 'assignment.html', false);
     }
 
     function portfolio_supported_formats() {
-        return array(PORTFOLIO_FORMAT_HTML);
+        return array(PORTFOLIO_FORMAT_PLAINHTML);
     }
 }
 
index 63248d2..f11bcca 100644 (file)
@@ -358,7 +358,7 @@ class assignment_upload extends assignment_base {
                 }
 
                 if (has_capability('mod/assignment:exportownsubmission', $this->context)) {
-                    $button->set_callback_options('assignment_portfolio_caller', array('id' => $this->cm->id, 'file' => $file->get_id()), '/mod/assignment/lib.php');
+                    $button->set_callback_options('assignment_portfolio_caller', array('id' => $this->cm->id, 'fileid' => $file->get_id()), '/mod/assignment/lib.php');
                     $button->set_formats(portfolio_format_from_file($file));
                     $output .= $button->to_html(PORTFOLIO_ADD_ICON_LINK);
                 }
index 4090553..9891ff8 100644 (file)
@@ -880,7 +880,7 @@ class chat_portfolio_caller extends portfolio_module_caller_base {
     }
 
     public static function supported_formats() {
-        return array(PORTFOLIO_FORMAT_HTML);
+        return array(PORTFOLIO_FORMAT_PLAINHTML);
     }
 
     public function expected_time() {
@@ -922,7 +922,7 @@ class chat_portfolio_caller extends portfolio_module_caller_base {
         }
         $content = preg_replace('/\<img[^>]*\>/', '', $content);
 
-        $this->exporter->write_new_file($content, clean_filename($this->cm->name . '-session.html'));
+        $this->exporter->write_new_file($content, clean_filename($this->cm->name . '-session.html'), false);
     }
 
     public static function display_name() {
index aafeec2..7ac3f84 100755 (executable)
@@ -1028,15 +1028,7 @@ function data_print_template($template, $records, $data, $search='',$page=0, $re
             require_once($CFG->libdir . '/portfoliolib.php');
             $button = new portfolio_add_button();
             $button->set_callback_options('data_portfolio_caller', array('id' => $cm->id, 'recordid' => $record->id));
-            $formats = array(PORTFOLIO_FORMAT_HTML);
-            if (count($fields) == 1) {
-                $ftmp = array_values($fields);
-                $singlefield = $ftmp[0];
-                if (is_callable(array($singlefield, 'get_file'))) { // TODO this used to be if ($singlefield instanceof data_field_file) { - see  MDL-16493
-                    $f = $singlefield->get_file($record->id);
-                    $formats= array(portfolio_format_from_file($f));
-                }
-            }
+            list($formats, $files) = data_portfolio_caller::formats($fields, $record);
             $button->set_formats($formats);
             $replacement[] = $button->to_html(PORTFOLIO_ADD_ICON_LINK);
         } else {
@@ -2600,19 +2592,15 @@ class data_portfolio_caller extends portfolio_module_caller_base {
             $this->singlerecord = $DB->get_record('data_records', array('id' => $this->recordid));
             $this->singlerecord->content = $DB->get_records('data_content', array('recordid' => $this->singlerecord->id));
             $this->exporttype = 'single';
-            $formats = array(PORTFOLIO_FORMAT_HTML);
-            if (count($this->fields) == 1) {
-                $ftmp = array_values($this->fields);
-                $singlefield = $ftmp[0];
-                if (is_callable(array($singlefield, 'get_file'))) { // TODO This used to be if ($singlefield instanceof data_field_file) { see MDL-16493
-                    $f = $singlefield->get_file($this->singlerecord->id);
-                    $formats= array(portfolio_format_from_file($f));
-                    $this->exporttype = 'singlefile';
-                    $this->singlefield = $singlefield;
-                    $this->singlefile = $this->singlefield->get_file($this->singlerecord->id);
-                }
-            }
+
+            list($formats, $files) = self::formats($this->fields, $this->singlerecord);
             $this->supportedformats = $formats;
+            if (count($files) == 1 && count($this->fields) == 1) {
+                $this->singlefile = $files[0];
+                $this->exporttype = 'singlefile';
+            } else if (count($files) > 0) {
+                $this->multifiles = $files;
+            }
         } else {
             // all records as csv or whatever
             $this->exportdata = data_get_exportdata($this->cm->instance, $this->fields, $this->selectedfields);
@@ -2686,7 +2674,11 @@ class data_portfolio_caller extends portfolio_module_caller_base {
                 throw new portfolio_caller_exception('notimplemented', 'portfolio', '', $this->exporttype);
             break;
         }
-        return $this->exporter->write_new_file($content, $filename);
+        return $this->exporter->write_new_file(
+            $content,
+            $filename,
+            ($this->exporter->get('format') instanceof PORTFOLIO_FORMAT_RICH) // if we have associate files, this is a 'manifest'
+        );
     }
 
     public function check_permissions() {
@@ -2716,13 +2708,18 @@ class data_portfolio_caller extends portfolio_module_caller_base {
         $context = get_context_instance(CONTEXT_MODULE, $this->cm->id);
 
     // Then we generate strings to replace for normal tags
+        $format = $this->get('exporter')->get('format');
         foreach ($this->fields as $field) {
             $patterns[]='[['.$field->field->name.']]';
-            if (is_callable(array($field, 'get_file'))) { // TODO this used to be if ($field instanceof data_field_file) { - see  MDL-16493
+            if (is_callable(array($field, 'get_file'))) {
+                // TODO this used to be:
+                // if ($field instanceof data_field_file) {
+                // - see  MDL-16493
                 if (!$file = $field->get_file($this->singlerecord->id)) {
+                    $replacement[] = '';
                     continue; // probably left empty
                 }
-                $replacement[] = $file->get_filename();
+                $replacement[] = $format->file_output($file);
                 $this->get('exporter')->copy_existing_file($file);
             } else {
                 $replacement[] = $field->display_browse_field($this->singlerecord->id, 'singletemplate');
@@ -2754,5 +2751,21 @@ class data_portfolio_caller extends portfolio_module_caller_base {
         // actual replacement of the tags
         return str_ireplace($patterns, $replacement, $this->data->singletemplate);
     }
+
+    public static function formats($fields, $record) {
+        $formats = array(PORTFOLIO_FORMAT_PLAINHTML);
+        $includedfiles = array();
+        foreach ($fields as $singlefield) {
+            if (is_callable(array($singlefield, 'get_file'))) {
+                $includedfiles[] = $singlefield->get_file($record->id);
+            }
+        }
+        if (count($includedfiles) == 1 && count($fields) == 1) {
+            $formats= array(portfolio_format_from_file($includedfiles[0]));
+        } else if (count($includedfiles) > 0) {
+            $formats = array(PORTFOLIO_FORMAT_RICHHTML);
+        }
+        return array($formats, $includedfiles);
+    }
 }
 ?>
index 50f4314..ecfeeeb 100644 (file)
@@ -3178,7 +3178,9 @@ function forum_print_post($post, $discussion, $forum, &$cm, $course, $ownpost=fa
         $button = new portfolio_add_button();
         $button->set_callback_options('forum_portfolio_caller', array('postid' => $post->id));
         if (empty($attachments)) {
-            $button->set_formats(PORTFOLIO_FORMAT_HTML);
+            $button->set_formats(PORTFOLIO_FORMAT_PLAINHTML);
+        } else {
+            $button->set_formats(PORTFOLIO_FORMAT_RICHHTML);
         }
         $commands[] = $button->to_html(PORTFOLIO_ADD_TEXT_LINK);
     }
@@ -7229,9 +7231,8 @@ class forum_portfolio_caller extends portfolio_module_caller_base {
     private $post;
     private $forum;
     private $discussion;
-    private $postfiles;
-    private $allfiles;
     private $posts;
+    private $keyedfiles;
 
     public static function expected_callbackargs() {
         return array(
@@ -7278,22 +7279,32 @@ class forum_portfolio_caller extends portfolio_module_caller_base {
             throw new portfolio_caller_exception('invalidcoursemodule');
         }
 
-        $fs = get_file_storage();
-        if ($this->attachment) {
-            if (!$f = $fs->get_file_by_id($this->attachment)) {
-                throw new portfolio_caller_exception('noattachments', 'forum');
+        $modcontext = get_context_instance(CONTEXT_MODULE, $this->cm->id);
+        if ($this->post) {
+            $this->set_file_and_format_data($this->attachment, $modcontext->id, 'forum_attachment', $this->post->id);
+            if (!empty($this->multifiles)) {
+                $this->keyedfiles[$this->post->id] = $this->multifiles;
+            } else if (!empty($this->singlefile)) {
+                $this->keyedfiles[$this->post->id] = $this->singlefile;
             }
-            $this->postfiles = array($f);
-            $this->supportedformats = array(portfolio_format_from_file($f));
-        } elseif ($this->post) {
-            $this->postfiles = $fs->get_area_files(get_context_instance(CONTEXT_MODULE, $this->cm->id)->id, 'forum_attachment', $this->post->id, "timemodified", false);
-            $this->supportedformats = array(PORTFOLIO_FORMAT_HTML);
-        } else {
+        } else { // whole thread
+            $fs = get_file_storage();
             $this->posts = forum_get_all_discussion_posts($this->discussion->id, 'p.created ASC');
+            $this->multifiles = array();
             foreach ($this->posts as $post) {
-                $this->allfiles[$post->id] = $fs->get_area_files(get_context_instance(CONTEXT_MODULE, $this->cm->id)->id, 'forum_attachment', $post->id, "timemodified", false);
+                if (!$this->keyedfiles[$post->id] = $fs->get_area_files($modcontext->id, 'forum_attachment', $post->id, "timemodified", false)) {
+                    continue;
+                }
+                $this->multifiles = array_merge($this->multifiles, array_values($this->keyedfiles[$post->id]));
             }
         }
+        if ($this->attachment) {
+            // do nothing
+        } else if (!empty($this->multifiles) || !empty($this->singlefile)) {
+            $this->supportedformats = array(PORTFOLIO_FORMAT_RICHHTML);
+        } else {
+            $this->supportedformats = array(PORTFOLIO_FORMAT_PLAINHTML);
+        }
     }
 
     function get_return_url() {
@@ -7318,20 +7329,21 @@ class forum_portfolio_caller extends portfolio_module_caller_base {
         // either a whole discussion
         // a single post, with or without attachment
         // or just an attachment with no post
+        $manifest = ($this->exporter->get('format') instanceof PORTFOLIO_FORMAT_RICH);
         if (!$this->post) { // whole discussion
             $content = '';
             foreach ($this->posts as $post) {
                 $content .= '<br /><br />' . $this->prepare_post($post);
-                $this->copy_files($this->allfiles[$post->id]);
             }
-            return $this->get('exporter')->write_new_file($content, 'discussion.html');
+            $this->copy_files($this->multifiles);
+            return $this->get('exporter')->write_new_file($content, 'discussion.html', $manifest);
         }
-        $this->copy_files($this->postfiles, $this->attachment);
         if ($this->attachment) {
-            return; // all we need to do
+            return $this->copy_files(array($this->singlefile), $this->attachment); // all we need to do
         }
+        $this->copy_files($this->multifiles, $this->attachment);
         $post = $this->prepare_post($this->post);
-        $this->get('exporter')->write_new_file($post, 'post.html');
+        $this->get('exporter')->write_new_file($post, 'post.html', $manifest);
     }
 
     private function copy_files($files, $justone=false) {
@@ -7392,17 +7404,12 @@ class forum_portfolio_caller extends portfolio_module_caller_base {
 
         $output .= $formattedtext;
 
-        if (!empty($this->postfiles)) {
-            $attachments = $this->postfiles;
-        } else if (!empty($this->allfiles) && array_key_exists($post->userid, $this->allfiles)) {
-            $attachments = $this->allfiles[$post->userid];
-        }
-        if (!empty($attachments)) {
-            $post->course = $this->get('course')->id;
+        if (array_key_exists($post->id, $this->keyedfiles) && is_array($this->keyedfiles[$post->id])) {
             $output .= '<div class="attachments">';
             $output .= '<br /><b>' .  get_string('attachments', 'forum') . '</b>:<br /><br />';
-            foreach ($attachments as $file) {
-                $output .= $file->get_filename() . '<br />';
+            $format = $this->get('exporter')->get('format');
+            foreach ($this->keyedfiles[$post->id] as $file) {
+                $output .= $format->file_output($file) . '<br/ >';
             }
             $output .= "</div>";
         }
@@ -7413,50 +7420,31 @@ class forum_portfolio_caller extends portfolio_module_caller_base {
     }
 
     function get_sha1() {
+        $filesha = '';
+        try {
+            $filesha = $this->get_sha1_file();
+        } catch (portfolio_caller_exception $e) { } // no files
+
         if ($this->post) {
-            $attachsha1 = $this->files_sha1($this->postfiles, $this->attachment);
-            return sha1($attachsha1 . ',' . $this->post->subject . ',' . $this->post->message);
+            return sha1($filesha . ',' . $this->post->subject . ',' . $this->post->message);
         } else {
-            $sha1s = array();
+            $sha1s = array($filesha);
             foreach ($this->posts as $post) {
-                $sha1s[] = $this->files_sha1($this->allfiles[$post->id]);
                 $sha1s[] = sha1($post->subject . ',' . $post->message);
             }
             return sha1(implode(',', $sha1s));
         }
     }
 
-    function files_sha1($files, $justone=false) {
-        if (empty($files)) {
-            return;
-        }
-        $sha1s = array();
-        foreach ($files as $file) {
-            if ($justone && $file->get_id() == $justone) {
-                return $file->get_contenthash(); // all we have to do
-            }
-            $sha1s[] = $file->get_contenthash();
-        }
-        asort($sha1s);
-        return sha1(implode('', $sha1s));
-    }
-
     function expected_time() {
-        // default...
-        $time = PORTFOLIO_TIME_LOW; // generally just means one post with no attachments
-        if ($this->postfiles) {
-            $time = portfolio_expected_time_file($this->postfiles);
-        } else if ($this->allfiles) {
-            // we have something two dimensional...
-            $files = array();
-            foreach ($this->allfiles as $post => $postfiles) {
-                $files = array_merge($files, $postfiles);
+        $filetime = $this->expected_time_file();
+        if ($this->posts) {
+            $posttime = portfolio_expected_time_db(count($this->posts));
+            if ($filetime < $posttime) {
+                return $posttime;
             }
-            $time = portfolio_expected_time_file($files);
-        } else if ($this->posts) {
-            $time = portfolio_expected_time_db(count($this->posts));
         }
-        return $time;
+        return $filetime;
     }
 
     function check_permissions() {
index 9fdaaff..bcd518e 100644 (file)
@@ -2446,7 +2446,7 @@ class glossary_csv_portfolio_caller extends portfolio_module_caller_base {
             }
         }
         $csv = glossary_generate_export_csv($entries, $aliases, $categories);
-        return $this->exporter->write_new_file($csv, clean_filename($this->cm->name) . '.csv');
+        return $this->exporter->write_new_file($csv, clean_filename($this->cm->name) . '.csv', false);
     }
 
     public function check_permissions() {
@@ -2486,7 +2486,7 @@ class glossary_entry_portfolio_caller extends portfolio_module_caller_base {
             // in case we don't have USER this will make the entry be printed
             $this->entry->approved = true;
         }
-        $this->supportedformats = array(PORTFOLIO_FORMAT_HTML);
+        $this->supportedformats = array(PORTFOLIO_FORMAT_PLAINHTML);
     }
 
     public function expected_time() {
@@ -2509,7 +2509,7 @@ class glossary_entry_portfolio_caller extends portfolio_module_caller_base {
         $entry = clone $this->entry;
         glossary_print_entry($this->get('course'), $this->cm, $this->glossary, $entry, null, null, false);
         $content = ob_get_clean();
-        return $this->exporter->write_new_file($content, clean_filename($this->entry->concept) . '.html');
+        return $this->exporter->write_new_file($content, clean_filename($this->entry->concept) . '.html', false);
     }
 
     public function get_sha1() {
index 7e43f65..8c0285b 100644 (file)
@@ -259,7 +259,7 @@ class resource_base {
         $formatoptions = (object)array('noclean' => true);
         $format = (($text) ? FORMAT_MOODLE : FORMAT_HTML);
         $content = format_text($this->resource->alltext, $format, $formatoptions, $this->course->id);
-        return $exporter->write_new_file($content, $filename);
+        return $exporter->write_new_file($content, $filename, false);
     }
 
     function portfolio_get_sha1_online($text=false) {
@@ -739,7 +739,7 @@ class resource_portfolio_caller extends portfolio_module_caller_base {
         $format = PORTFOLIO_FORMAT_FILE;
         switch ($type) {
             case 'html':
-                $format = PORTFOLIO_FORMAT_HTML;
+                $format = PORTFOLIO_FORMAT_PLAINHTML;
             case 'text':
                 $format = PORTFOLIO_FORMAT_TEXT;
             case 'file':
index d7d3ba3..10978f6 100644 (file)
@@ -36,13 +36,6 @@ class portfolio_plugin_download extends portfolio_plugin_pull_base {
         }
     }
 
-    /*
-    public function get_extra_finish_options() {
-        global $CFG;
-        return array($this->get_base_file_url() => get_string('downloadfile', 'portfolio_download'));
-    }
-    */
-
     public function send_package() {}
 
     public function verify_file_request_params($params) {