MDL-15777 more fixes for portfolio to use file api
authormjollnir_ <mjollnir_>
Tue, 12 Aug 2008 13:17:34 +0000 (13:17 +0000)
committermjollnir_ <mjollnir_>
Tue, 12 Aug 2008 13:17:34 +0000 (13:17 +0000)
this introduces portfolio/file.php to serve portfolio related files - access check is delegated to the plugin.
and also two new classes in the portfolio plugin tree - push vs pull.

lang/en_utf8/portfolio.php
lib/portfoliolib.php
portfolio/add.php
portfolio/file.php [new file with mode: 0644]
portfolio/type/boxnet/lib.php
portfolio/type/download/lib.php

index 71fd960..23c808e 100644 (file)
@@ -2,7 +2,7 @@
 
 $string['addnewportfolio'] = 'Add a new portfolio';
 $string['addtoportfolio'] = 'Add to portfolio';
-$string['alreadyexporting'] = 'You already have an active portfolio export in this session. Please complete that first';
+$string['alreadyexporting'] = 'You already have an active portfolio export in this session. Please complete that first, or <a href=\"$a\">click here</a> to cancel it.';
 $string['availableformats'] = 'Available export formats';
 $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';
@@ -23,6 +23,8 @@ $string['exportcomplete'] = 'Portfolio export complete!';
 $string['exportqueued'] = 'Portfolio export has been successfully queued for transfer';
 $string['exportedpreviously'] = 'Previous exports';
 $string['failedtosendpackage'] = 'Failed to send your data to the selected portfolio system!';
+$string['filedenied'] = 'Access denied to this file';
+$string['filenotfound'] = 'File not found';
 $string['format_file'] = 'File';
 $string['format_mbkp'] = 'Moodle Backup';
 $string['hidden'] = 'Hidden';
@@ -31,7 +33,7 @@ $string['instanceismisconfigured'] = 'Portfolio instance is misconfigured, skipp
 $string['instancenotsaved'] = 'Failed to save portfolio';
 $string['instancenotdelete'] = 'Failed to delete portfolio';
 $string['instancesaved'] = 'Portfolio saved successfully';
-$string['invalidtempid'] = 'Invalid temporary id';
+$string['invalidtempid'] = 'Invalid export id. maybe it has expired';
 $string['invalidformat'] = 'Something is exporting an invalid format, $a';
 $string['invalidinstance'] = 'Could not find that portfolio instance';
 $string['manageportfolios'] = 'Manage portfolios';
index 1c2f5b9..f670a38 100644 (file)
@@ -155,7 +155,7 @@ function portfolio_add_button($callbackclass, $callbackargs, $callbackfile=null,
     }
 
     if (isset($SESSION->portfolioexport)) {
-        print_error('alreadyexporting', 'portfolio');
+        print_error('alreadyexporting', 'portfolio', null, $CFG->wwwroot . '/portfolio/add.php?cancel=1');
     }
 
     if (empty($callbackfile)) {
@@ -889,6 +889,15 @@ abstract class portfolio_plugin_base {
     */
     public abstract function expected_time($callertime);
 
+    /**
+    * is this plugin push or pill.
+    * if push, cleanup will be called directly after send_package
+    * if not, cleanup will be called after portfolio/file.php is requested
+    *
+    * @return boolean
+    */
+    public abstract function is_push();
+
     /**
     * check sanity of plugin
     * if this function returns something non empty, ALL instances of your plugin
@@ -1427,6 +1436,38 @@ abstract class portfolio_plugin_base {
     }
 }
 
+/**
+* class to inherit from for 'push' type plugins
+*/
+abstract class portfolio_plugin_push_base extends portfolio_plugin_base {
+
+    public function is_push() {
+        return true;
+    }
+}
+
+/**
+* class to inherit from for 'pull' type plugins
+*/
+abstract class portfolio_plugin_pull_base extends portfolio_plugin_base {
+
+    private $file;
+
+    public function is_push() {
+        return false;
+    }
+
+
+    /**
+    * before sending the file when the pull is requested, verify the request parameters
+    * these might include a token of some sort of whatever
+    *
+    * @param array request parameters (POST wins over GET)
+    */
+    public abstract function verify_file_request_params($params);
+
+}
+
 /**
 * this is the form that is actually used while exporting.
 * plugins and callers don't get to define their own class
@@ -1698,7 +1739,6 @@ final class portfolio_exporter {
         if (!$alreadystolen && $url = $this->instance->steal_control($stage)) {
             $this->set('stage', $stage);
             $this->save();
-            //$SESSION->portfolio->stagepresteal = $stage;
             redirect($url);
             break;
         }
@@ -1754,8 +1794,6 @@ final class portfolio_exporter {
     */
     public function process_stage_config() {
 
-        //global $SESSION;
-
         $pluginobj = $callerobj = null;
         if ($this->instance->has_export_config()) {
             $pluginobj = $this->instance;
@@ -1789,11 +1827,6 @@ final class portfolio_exporter {
             $mform = new portfolio_export_form('', $customdata);
             if ($mform->is_cancelled()){
                 $this->cancel_request();
-                /*
-                unset($SESSION->portfolio);
-                redirect($this->caller->get_return_url());
-                exit;
-                */
             } else if ($fromform = $mform->get_data()){
                 if (!confirm_sesskey()) {
                     return $this->raise_error('confirmsesskeybad', '', $caller->get_return_url());
@@ -1939,8 +1972,13 @@ final class portfolio_exporter {
     *
     * @return boolean whether or not to process the next stage. this is important as the control function is called recursively.
     */
-    public function process_stage_cleanup() {
+    public function process_stage_cleanup($pullok=false) {
         global $CFG, $DB, $SESSION;
+
+        if (!$pullok && !$this->get('instance')->is_push()) {
+            unset($SESSION->portfolioexport);
+            return true;
+        }
         // @todo maybe add a hook in the plugin(s)
         $DB->delete_records('portfolio_tempdata', array('id' => $this->id));
         $fs = get_file_storage();
@@ -1979,7 +2017,6 @@ final class portfolio_exporter {
     * @return boolean whether or not to process the next stage. this is important as the control function is called recursively.
     */
     public function process_stage_finished($queued=false) {
-        //global $SESSION;
         $returnurl = $this->caller->get_return_url();
         $continueurl = $this->instance->get_continue_url();
         $extras = $this->instance->get_extra_finish_options();
@@ -2002,7 +2039,6 @@ final class portfolio_exporter {
             }
         }
         print_footer();
-        //unset($SESSION->portfolio);
         return false;
     }
 
@@ -2024,24 +2060,22 @@ final class portfolio_exporter {
     * error handler - decides whether we're running interactively or not
     * and behaves accordingly
     */
-    public function raise_error($string, $module='moodle', $continue=null) {
+    public function raise_error($string, $module='moodle', $continue=null, $a=null) {
         if (defined('FULLME') && FULLME == 'cron') {
             debugging(get_string($string, $module));
             return false;
         }
         if (isset($this)) {
-            $this->process_stage_cleanup();
+            $this->process_stage_cleanup(true);
         }
-        //global $SESSION;
-        //unset($SESSION->portfolio);
-        print_error($string, $module, $continue);
+        print_error($string, $module, $continue, $a);
     }
 
     public function cancel_request() {
         if (!isset($this)) {
             return;
         }
-        $this->process_stage_cleanup();
+        $this->process_stage_cleanup(true);
         redirect($this->caller->get_return_url());
         exit;
     }
@@ -2066,7 +2100,7 @@ final class portfolio_exporter {
     public static function rewaken_object($id) {
         global $DB, $CFG;
         if (!$data = $DB->get_record('portfolio_tempdata', array('id' => $id))) {
-            portfolio_exporer::raise_error('invalidtempid', 'portfolio');
+            portfolio_exporter::raise_error('invalidtempid', 'portfolio');
         }
         $exporter = unserialize(base64_decode($data->data));
         if ($exporter->instancefile) {
@@ -2121,7 +2155,11 @@ final class portfolio_exporter {
         if (empty($files)) {
             return array();
         }
-        return $files;
+        $returnfiles = array();
+        foreach ($files as $f) {
+            $returnfiles[$f->get_filename()] = $f;
+        }
+        return $returnfiles;
     }
 
     /**
index e467be1..c2de922 100644 (file)
@@ -19,11 +19,6 @@ if ($dataid) {
     $exporter = portfolio_exporter::rewaken_object($dataid);
     if ($cancel = optional_param('cancel', 0, PARAM_RAW)) {
         $exporter->cancel_request();
-        /*
-        $returnurl = $exporter->get('caller')->get_return_url();
-        unset($SESSION->portfolio);
-        redirect($returnurl);
-        */
     }
     if (!$exporter->get('instance')) {
         if ($instance = optional_param('instance', '', PARAM_INT)) {
@@ -105,12 +100,6 @@ if (!$exporter->get('instance')) {
     $mform = new portfolio_instance_select('', array('caller' => $exporter->get('caller')));
     if ($mform->is_cancelled()) {
         $exporter->cancel_request();
-        /*
-        $returnurl = $caller->get_return_url();
-        unset($SESSION->portfolio);
-        redirect($returnurl);
-        exit;
-    */
     } else if ($fromform = $mform->get_data()){
         redirect($CFG->wwwroot . '/portfolio/add.php?instance=' . $fromform->instance . '&amp;id=' . $exporter->get('id'));
         exit;
diff --git a/portfolio/file.php b/portfolio/file.php
new file mode 100644 (file)
index 0000000..b53c9f5
--- /dev/null
@@ -0,0 +1,27 @@
+<?php
+require_once(dirname(dirname(__FILE__)) . '/config.php');
+require_once($CFG->libdir . '/portfoliolib.php');
+require_once($CFG->libdir . '/file/stored_file.php');
+require_once($CFG->libdir . '/filelib.php');
+
+$id = required_param('id', PARAM_INT);
+
+$exporter = portfolio_exporter::rewaken_object($id);
+
+if ($exporter->get('instance')->is_push()) {
+    $exporter->raise_error('filedenied', 'portfolio');
+}
+
+if (!$exporter->get('instance')->verify_file_request_params(array_merge($_GET, $_POST))) {
+    $exporter->raise_error('filedenied', 'portfolio');
+}
+
+$file = $exporter->get('instance')->get('file');
+if (!($file instanceof stored_file)) {
+    $exporter->raise_error('filenotfound', 'portfolio');
+}
+
+send_stored_file($file, 0, 0, true, null, true);
+$exporter->process_stage_cleanup(true);
+
+?>
index bd4d67c..471ea50 100644 (file)
@@ -2,7 +2,7 @@
 require_once($CFG->libdir.'/filelib.php');
 require_once($CFG->dirroot.'/repository/boxnet/boxlibphp5.php');
 
-class portfolio_plugin_boxnet extends portfolio_plugin_base {
+class portfolio_plugin_boxnet extends portfolio_plugin_push_base {
 
     private $boxclient;
     private $ticket;
index 1c8678f..524671f 100644 (file)
@@ -1,10 +1,11 @@
 <?php
 
 require_once($CFG->libdir . '/portfoliolib.php');
+require_once($CFG->libdir . '/packer/zip_packer.php');
 
-class portfolio_plugin_download extends portfolio_plugin_base {
+class portfolio_plugin_download extends portfolio_plugin_pull_base {
 
-    protected $zipfile;
+    protected $file;
     protected $exportconfig;
 
     public static function allows_multiple() {
@@ -16,20 +17,16 @@ class portfolio_plugin_download extends portfolio_plugin_base {
     }
 
     public function prepare_package() {
-        // just zip up whatever files the caller has created for us
-        // and move them to the user's temporary area.
-        $userdir = temp_portfolio_usertemp_directory($this->get('user')->id);
-
-        $newfile = 'portfolio_export_' . time() . '.zip';
-        $files = get_directory_list($tempdir);
-        foreach ($files as $key => $file) {
-            $files[$key] = $tempdir . '/' . $file;
-        }
 
-        zip_files($files, $userdir . '/' . $newfile);
-        $this->set('zipfile', $newfile);
+        $files = $this->exporter->get_tempfiles();
+        $zipper = new zip_packer();
 
-        return true;
+        $filename = 'portfolio-export.zip';
+        if ($newfile = $zipper->archive_to_storage($files, SYSCONTEXTID, 'portfolio_exporter', $this->exporter->get('id'), '/final/', $filename, $this->user->id)) {
+            $this->set('file', $newfile);
+            return true;
+        }
+        return false;
     }
 
     public function send_package() {
@@ -38,18 +35,21 @@ class portfolio_plugin_download extends portfolio_plugin_base {
 
     public function get_extra_finish_options() {
         global $CFG;
-        return array(
-            // @todo this will go through files api later, this is a (nonworking) hack for now.
-            $CFG->wwwroot . '/file.php?file=' . $this->zipfile => get_string('downloadfile', 'portfolio_download'),
-        );
+        return array($CFG->wwwroot . '/portfolio/file.php?id=' . $this->exporter->get('id') => get_string('downloadfile', 'portfolio_download'));
     }
 
-    public function get_continue_url() {
-        return false;
+    public function verify_file_request_params($params) {
+        // for download plugin the only thing we need to verify is that
+        // the logged in user is the same as the exporting user
+        global $USER;
+        if ($USER->id  != $this->user->id) {
+            return false;
+        }
+        return true;
     }
 
-    public static function plugin_sanity_check() {
-        return 'notupgradedtousefilesapi';
+    public function get_continue_url() {
+        return false;
     }
 }