From ffcfd8a777e469aca631d2b59a773b41b3fd396e Mon Sep 17 00:00:00 2001 From: mjollnir_ Date: Wed, 30 Jul 2008 16:38:13 +0000 Subject: [PATCH] MDL-15762 log portfolio transfers and notify the user when there are dups --- lang/en_utf8/portfolio.php | 3 +- lib/portfoliolib.php | 78 +++++++++++++++---- mod/assignment/lib.php | 32 ++++++-- .../type/online/assignment.class.php | 13 ++++ mod/forum/lib.php | 19 +++++ mod/resource/lib.php | 27 +++++-- mod/resource/type/html/resource.class.php | 4 + mod/resource/type/text/resource.class.php | 5 ++ portfolio/add.php | 9 ++- 9 files changed, 159 insertions(+), 31 deletions(-) diff --git a/lang/en_utf8/portfolio.php b/lang/en_utf8/portfolio.php index f2e90c3215..18d61f753a 100644 --- a/lang/en_utf8/portfolio.php +++ b/lang/en_utf8/portfolio.php @@ -8,7 +8,7 @@ $string['callercouldnotpackage'] = 'Failed to package up your data for export'; $string['cannotsetvisible'] = 'Cannot set this to visible - the plugin has been completely disabled because of a misconfiguration'; $string['configexport'] = 'Configure exported data'; $string['configplugin'] = 'Configure portfolio plugin'; -$string['confirmexport'] = 'Please confirm the following export'; +$string['confirmexport'] = 'Please confirm this export'; $string['confirmsummary'] = 'Summary of your export'; $string['configure'] = 'Configure'; $string['continuetoportfolio'] = 'Continue to your portfolio'; @@ -20,6 +20,7 @@ $string['enabled'] = 'Enable portfolios'; $string['enableddesc'] = 'This will allow administrators to configure remote systems for users to export content to'; $string['exporting'] = 'Exporting to portfolio'; $string['exportcomplete'] = 'Portfolio export complete!'; +$string['exportedpreviously'] = 'Previous exports'; $string['failedtosendpackage'] = 'Failed to send your data to the selected portfolio system!'; $string['format_file'] = 'File'; $string['format_mbkp'] = 'Moodle Backup'; diff --git a/lib/portfoliolib.php b/lib/portfoliolib.php index d5437e80f7..96b2e9cf1c 100644 --- a/lib/portfoliolib.php +++ b/lib/portfoliolib.php @@ -1,5 +1,4 @@ outside the subclasses @@ -625,7 +629,7 @@ abstract class portfolio_caller_base { */ public final function set_export_config($config) { $allowed = array_merge( - array('wait', 'hidewait', 'format'), + array('wait', 'hidewait', 'format', 'hideformat'), $this->get_allowed_export_config() ); foreach ($config as $key => $value) { @@ -645,7 +649,7 @@ abstract class portfolio_caller_base { */ public final function get_export_config($key) { $allowed = array_merge( - array('wait', 'hidewait', 'format'), + array('wait', 'hidewait', 'format', 'hideformat'), $this->get_allowed_export_config() ); if (!in_array($key, $allowed)) { @@ -721,6 +725,11 @@ abstract class portfolio_caller_base { * in the caller (called during the export process */ public abstract function check_permissions(); + + /** + * nice name to display to the user about this caller location + */ + public abstract static function display_name(); } abstract class portfolio_module_caller_base extends portfolio_caller_base { @@ -916,7 +925,7 @@ abstract class portfolio_plugin_base { */ public function set_export_config($config) { $allowed = array_merge( - array('wait', 'format'), + array('wait', 'hidewait', 'format', 'hideformat'), $this->get_allowed_export_config() ); foreach ($config as $key => $value) { @@ -939,7 +948,7 @@ abstract class portfolio_plugin_base { */ public final function get_export_config($key) { $allowed = array_merge( - array('wait', 'format'), + array('hidewait', 'wait', 'format', 'hideformat'), $this->get_allowed_export_config() ); if (!in_array($key, $allowed)) { @@ -1740,6 +1749,7 @@ final class portfolio_exporter { $pluginbits['wait'] = 1; $pluginbits['hidewait'] = 1; } + $callerbits['hideformat'] = $pluginbits['hideformat'] = (count($formats) == 1); $this->caller->set_export_config($callerbits); $this->instance->set_export_config($pluginbits); return true; @@ -1754,36 +1764,58 @@ final class portfolio_exporter { } } else { $this->noexportconfig = true; - $this->instance->set_export_config(array('wait' => 1)); + $format = array_shift($formats); + $this->instance->set_export_config(array('hidewait' => 1, 'wait' => 1, 'format' => $format, 'hideformat' => 1)); + $this->caller->set_export_config(array('format' => $format, 'hideformat' => 1)); return true; // do not break - fall through to confirm } } - /** * processes the 'confirm' stage of the export * * @return boolean whether or not to process the next stage. this is important as the control function is called recursively. */ public function process_stage_confirm() { - global $CFG; - if (isset($this->noexportconfig)) { + global $CFG, $DB; + + $previous = $DB->get_records( + 'portfolio_log', + array( + 'userid' => $this->user->id, + 'portfolio' => $this->instance->get('id'), + 'caller_sha1' => $this->caller->get_sha1(), + ) + ); + if (isset($this->noexportconfig) && empty($previous)) { return true; } $strconfirm = get_string('confirmexport', 'portfolio'); $yesurl = $CFG->wwwroot . '/portfolio/add.php?stage=' . PORTFOLIO_STAGE_QUEUEORWAIT; - $nourl = $this->caller->get_return_url(); + $nourl = $CFG->wwwroot . '/portfolio/add.php?cancel=1'; $this->print_header(); print_heading($strconfirm); print_simple_box_start(); print_heading(get_string('confirmsummary', 'portfolio'), '', 4); - $mainsummary = array( - // @todo do something cleverer about wait - get_string('selectedformat', 'portfolio') => get_string('format_' . $this->instance->get_export_config('format'), 'portfolio'), - ); + $mainsummary = array(); + if (!$this->instance->get_export_config('hideformat')) { + $mainsummary[get_string('selectedformat', 'portfolio')] = get_string('format_' . $this->instance->get_export_config('format'), 'portfolio'); + } if (!$this->instance->get_export_config('hidewait')) { - $mainsummary[get_string('selectedwait', 'portfolio')] = get_string($this->instance->get_export_config('wait') ? 'yes' : 'no'); + $mainsummary[get_string('selectedwait', 'portfolio')] = get_string(($this->instance->get_export_config('wait') ? 'yes' : 'no')); + } + if ($previous) { + $previousstr = ''; + foreach ($previous as $row) { + $previousstr .= userdate($row->time); + if ($row->caller_class != get_class($this->caller)) { + require_once($CFG->dirroot . '/' . $row->caller_file); + $previousstr .= ' (' . call_user_func(array($row->caller_class, 'display_name')) . ')'; + } + $previousstr .= '
'; + } + $mainsummary[get_string('exportedpreviously', 'portfolio')] = $previousstr; } if (!$csummary = $this->caller->get_export_summary()) { $csummary = array(); @@ -1792,9 +1824,12 @@ final class portfolio_exporter { $isummary = array(); } $mainsummary = array_merge($mainsummary, $csummary, $isummary); + $table = new StdClass; + $table->data = array(); foreach ($mainsummary as $string => $value) { - echo '' . $string . ':' . $value . '
' . "\n"; + $table->data[] = array($string, $value); } + print_table($table); notice_yesno($strconfirm, $yesurl, $nourl); print_simple_box_end(); print_footer(); @@ -1864,6 +1899,17 @@ final class portfolio_exporter { if (!$this->instance->send_package()) { return $this->raise_error('failedtosendpackage', 'portfolio'); } + // log the transfer + global $DB; + $l = array( + 'userid' => $this->user->id, + 'portfolio' => $this->instance->get('id'), + 'caller_file' => $this->callerfile, + 'caller_sha1' => $this->caller->get_sha1(), + 'caller_class' => get_class($this->caller), + 'time' => time(), + ); + $DB->insert_record('portfolio_log', $l); return true; } diff --git a/mod/assignment/lib.php b/mod/assignment/lib.php index 799bfa16c9..c3daa1d6f7 100644 --- a/mod/assignment/lib.php +++ b/mod/assignment/lib.php @@ -3146,13 +3146,10 @@ class assignment_portfolio_caller extends portfolio_module_caller_base { public function prepare_package($tempdir) { global $CFG; - if ($this->assignment->assignment->assignmenttype == 'online') { - $submission = $this->assignment->get_submission(); - $handle = fopen($tempdir . '/assignment.html', 'w'); - $status = $handle && fwrite($handle, format_text($submission->data1, $submission->data2)); - $status = $status && fclose($handle); - return $status; + if (is_callable(array($this->assignment, 'portfolio_prepare_package'))) { + return $this->assignment->portfolio_prepare_package($tempdir); } + // default... $filearea = $CFG->dataroot . '/' . $this->assignment->file_area_name($this->userid); //@todo penny this is a dreadful thing to have to call (replace with files api anyway) require_once($CFG->dirroot . '/backup/lib.php'); @@ -3162,6 +3159,25 @@ class assignment_portfolio_caller extends portfolio_module_caller_base { return backup_copy_file($filearea, $tempdir); } + public function get_sha1() { + global $CFG; + if (is_callable(array($this->assignment, 'portfolio_get_sha1'))) { + return $this->assignment->portfolio_get_sha1(); + } + // default ... + $filearea = $CFG->dataroot . '/' . $this->assignment->file_area_name($this->userid); + if ($this->file) { + return sha1_file($filearea . '/' . $this->file); + } + $sha1s = array(); + foreach (get_directory_list($filearea) as $file) { + $sha1s[] = sha1_file($filearea . '/' . $file); + } + asort($sha1s); + return sha1(implode('', $sha1s)); + + } + public function expected_time() { return PORTFOLIO_TIME_MODERATE; // @TODO check uploaded file size } @@ -3178,6 +3194,10 @@ class assignment_portfolio_caller extends portfolio_module_caller_base { require_once($this->assignmentfile); $this->assignment = unserialize(serialize($this->assignment)); } + + public static function display_name() { + return get_string('modulename', 'assignment'); + } } /** diff --git a/mod/assignment/type/online/assignment.class.php b/mod/assignment/type/online/assignment.class.php index bf06d21591..31542098d5 100644 --- a/mod/assignment/type/online/assignment.class.php +++ b/mod/assignment/type/online/assignment.class.php @@ -269,6 +269,19 @@ class assignment_online extends assignment_base { function portfolio_exportable() { return true; } + + function portfolio_get_sha1() { + $submission = $this->get_submission(); + return sha1(format_text($submission->data1, $submission->data2)); + } + + function portfolio_prepare_package($tempdir) { + $submission = $this->get_submission(); + $handle = fopen($tempdir . '/assignment.html', 'w'); + $status = $handle && fwrite($handle, format_text($submission->data1, $submission->data2)); + $status = $status && fclose($handle); + return $status; + } } class mod_assignment_online_edit_form extends moodleform { diff --git a/mod/forum/lib.php b/mod/forum/lib.php index c238ed3910..18e535066d 100644 --- a/mod/forum/lib.php +++ b/mod/forum/lib.php @@ -7069,6 +7069,22 @@ class forum_portfolio_caller extends portfolio_module_caller_base { // @todo see MDL-15758 } + function get_sha1() { + if ($this->attachment) { + if ($basedir = forum_file_area($this->post)) { + $sha1s = array(); + foreach (get_directory_list($basedir) as $file) { + $sha1s[] = sha1_file($basedir . '/' . $file); + } + asort($sha1s); + return sha1(implode('', $sha1s)); + } + return false; + } + portfolio_exporter::raise_error('TODO - see MDL-15758'); + // @todo see MDL-15758 + } + function expected_time() { // @todo check for attachment size return PORTFOLIO_TIME_LOW; @@ -7079,6 +7095,9 @@ class forum_portfolio_caller extends portfolio_module_caller_base { return true; } + public static function display_name() { + return get_string('modulename', 'forum'); + } } ?> diff --git a/mod/resource/lib.php b/mod/resource/lib.php index 1a28119889..047ea08259 100644 --- a/mod/resource/lib.php +++ b/mod/resource/lib.php @@ -257,8 +257,7 @@ class resource_base { function portfolio_prepare_package_online($tempdir, $text=false) { //@todo penny use the files api here $status = $handle = fopen($tempdir . '/' . clean_filename($this->cm->name . '.' . (($text) ? 'txt' : 'html')), 'w'); - $formatoptions = new object(); - $formatoptions->noclean = true; + $formatoptions = (object)array('noclean' => true); $format = (($text) ? FORMAT_MOODLE : FORMAT_HTML); $content = format_text($this->resource->alltext, $format, $formatoptions, $this->course->id); $status = $status && fwrite($handle, $content); @@ -266,6 +265,17 @@ class resource_base { return $status; } + function portfolio_get_sha1_online($text=false) { + $formatoptions = (object)array('noclean' => true); + $format = (($text) ? FORMAT_MOODLE : FORMAT_HTML); + $content = format_text($this->resource->alltext, $format, $formatoptions, $this->course->id); + return sha1($content); + } + + function portfolio_get_sha1_uploaded() { + // @todo penny implement later. + } + } /// end of class definition @@ -732,9 +742,6 @@ class resource_portfolio_caller extends portfolio_module_caller_base { } public function prepare_package($tempdir) { - if (!is_callable(array($this->resource, 'portfolio_prepare_package'))) { - portfolio_exporter::raise_error('portfolionotimplemented', 'resource'); - } return $this->resource->portfolio_prepare_package($tempdir); } @@ -744,12 +751,20 @@ class resource_portfolio_caller extends portfolio_module_caller_base { public static function add_button($resource, $fullform=true, $return=false) { // @todo penny can we put the capability check in here? - if (!is_callable(array($resource, 'portfolio_prepare_package'))) { + if (!is_callable(array($resource, 'portfolio_prepare_package')) || !is_callable(array($resource, 'portfolio_get_sha1'))) { debugging(get_string('portfolionotimplemented', 'resource')); return false; } return portfolio_add_button('resource_portfolio_caller', array('id' => $resource->cm->instance), '/mod/resource/lib.php', $fullform, $return); } + + public function get_sha1() { + return $this->resource->portfolio_get_sha1(); + } + + public static function display_name() { + return get_string('modulename', 'resource'); + } } /** diff --git a/mod/resource/type/html/resource.class.php b/mod/resource/type/html/resource.class.php index e1952364cf..f77860dc04 100644 --- a/mod/resource/type/html/resource.class.php +++ b/mod/resource/type/html/resource.class.php @@ -197,6 +197,10 @@ function portfolio_prepare_package($tempdir) { return parent::portfolio_prepare_package_online($tempdir); } +function portfolio_get_sha1() { + return parent::portfolio_get_sha1_online(); +} + } diff --git a/mod/resource/type/text/resource.class.php b/mod/resource/type/text/resource.class.php index 064d664998..8c2e377fd7 100644 --- a/mod/resource/type/text/resource.class.php +++ b/mod/resource/type/text/resource.class.php @@ -202,6 +202,11 @@ function setup_elements(&$mform) { function portfolio_prepare_package($tempdir) { return parent::portfolio_prepare_package_online($tempdir, true); } + +function portfolio_get_sha1() { + return parent::portfolio_get_sha1_online(true); +} + } ?> diff --git a/portfolio/add.php b/portfolio/add.php index ddab920108..3f73727806 100644 --- a/portfolio/add.php +++ b/portfolio/add.php @@ -16,14 +16,19 @@ if (isset($SESSION->portfolio) && isset($SESSION->portfolio->exporter)) { require_once($CFG->dirroot . '/' . $exporter->callerfile); $exporter = unserialize(serialize($SESSION->portfolio->exporter)); $SESSION->portfolio->exporter =& $exporter; - if ($instance = optional_param('instance', 0, PARAM_INT)) { + if (!$exporter->get('instance')) { + $instance = required_param('instance', PARAM_INT); $instance = portfolio_instance($instance); if ($broken = portfolio_instance_sanity_check($instance)) { print_error(get_string($broken[$instance->get('id')], 'portfolio_' . $instance->get('plugin'))); } $instance->set('user', $USER); $exporter->set('instance', $instance); - + } + if ($cancel = optional_param('cancel', 0, PARAM_INT)) { + $returnurl = $exporter->get('caller')->get_return_url(); + unset($SESSION->portfolio); + redirect($returnurl); } } else { // we'e just posted here for the first time and have might the instance already -- 2.39.5