Moodle  2.2.1
http://www.collinsharper.com
C:/xampp/htdocs/moodle/portfolio/mahara/lib.php
Go to the documentation of this file.
00001 <?php
00002 // This file is part of Moodle - http://moodle.org/
00003 //
00004 // Moodle is free software: you can redistribute it and/or modify
00005 // it under the terms of the GNU General Public License as published by
00006 // the Free Software Foundation, either version 3 of the License, or
00007 // (at your option) any later version.
00008 //
00009 // Moodle is distributed in the hope that it will be useful,
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 // GNU General Public License for more details.
00013 //
00014 // You should have received a copy of the GNU General Public License
00015 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
00016 
00017 
00029 define('PORTFOLIO_MAHARA_ERR_NETWORKING_OFF', 'err_networkingoff');
00030 define('PORTFOLIO_MAHARA_ERR_NOHOSTS', 'err_nomnethosts');
00031 define('PORTFOLIO_MAHARA_ERR_INVALIDHOST', 'err_invalidhost');
00032 define('PORTFOLIO_MAHARA_ERR_NOMNETAUTH', 'err_nomnetauth');
00033 
00034 require_once($CFG->libdir . '/portfoliolib.php');
00035 require_once($CFG->libdir . '/portfolio/plugin.php');
00036 require_once($CFG->libdir . '/portfolio/exporter.php');
00037 require_once($CFG->dirroot . '/mnet/lib.php');
00038 
00039 define('PORTFOLIO_MAHARA_QUEUE', PORTFOLIO_TIME_HIGH);
00040 define('PORTFOLIO_MAHARA_IMMEDIATE', PORTFOLIO_TIME_MODERATE);
00041 
00042 class portfolio_plugin_mahara extends portfolio_plugin_pull_base {
00043 
00044     private $hosts; // used in the admin config form
00045     private $mnethost; // privately set during export from the admin config value (mnethostid)
00046     private $hostrecord; // the host record that corresponds to the peer
00047     private $token; // during-transfer token
00048     private $sendtype; // whatever mahara has said it can handle (immediate or queued)
00049     private $filesmanifest; // manifest of files to send to mahara (set during prepare_package and sent later)
00050     private $totalsize; // total size of all included files added together
00051     private $continueurl; // if we've been sent back a specific url to continue to (eg folder id)
00052 
00053     protected function init() {
00054         $this->mnet = get_mnet_environment();
00055     }
00056 
00057     public function __wakeup() {
00058         $this->mnet = get_mnet_environment();
00059     }
00060 
00061     public static function get_name() {
00062         return get_string('pluginname', 'portfolio_mahara');
00063     }
00064 
00065     public static function get_allowed_config() {
00066         return array('mnethostid', 'enableleap2a');
00067     }
00068 
00069     public function supported_formats() {
00070         if ($this->get_config('enableleap2a')) {
00071             return array(PORTFOLIO_FORMAT_FILE, PORTFOLIO_FORMAT_LEAP2A);
00072         }
00073         return array(PORTFOLIO_FORMAT_FILE);
00074     }
00075 
00076     public function expected_time($callertime) {
00077         if ($this->sendtype == PORTFOLIO_MAHARA_QUEUE) {
00078             return PORTFOLIO_TIME_FORCEQUEUE;
00079         }
00080         return $callertime;
00081     }
00082 
00083     public static function has_admin_config() {
00084         return true;
00085     }
00086 
00087     public function admin_config_form(&$mform) {
00088         $strrequired = get_string('required');
00089         $hosts = self::get_mnet_hosts(); // this is called by sanity check but it's ok because it's cached
00090         foreach ($hosts as $host) {
00091             $hosts[$host->id] = $host->name;
00092         }
00093         $mform->addElement('select', 'mnethostid', get_string('mnethost', 'portfolio_mahara'), $hosts);
00094         $mform->addRule('mnethostid', $strrequired, 'required', null, 'client');
00095         $mform->addElement('selectyesno', 'enableleap2a', get_string('enableleap2a', 'portfolio_mahara'));
00096     }
00097 
00098     public function instance_sanity_check() {
00099         // make sure the host record exists since we don't have referential integrity
00100         if (!is_enabled_auth('mnet')) {
00101             return PORTFOLIO_MAHARA_ERR_NOMNETAUTH;
00102         }
00103         try {
00104             $this->ensure_mnethost();
00105         }
00106         catch (portfolio_exception $e) {
00107             return PORTFOLIO_MAHARA_ERR_INVALIDHOST;
00108         }
00109         // make sure we have the right services
00110         $hosts = $this->get_mnet_hosts();
00111         if (!array_key_exists($this->get_config('mnethostid'), $hosts)) {
00112             return PORTFOLIO_MAHARA_ERR_INVALIDHOST;
00113         }
00114         return 0;
00115     }
00116 
00117     public static function plugin_sanity_check() {
00118         global $CFG, $DB;
00119         $errorcode = 0;
00120         if (!isset($CFG->mnet_dispatcher_mode) || $CFG->mnet_dispatcher_mode != 'strict') {
00121             $errorcode =  PORTFOLIO_MAHARA_ERR_NETWORKING_OFF;
00122         }
00123         if (!is_enabled_auth('mnet')) {
00124             $errorcode = PORTFOLIO_MAHARA_ERR_NOMNETAUTH;
00125         }
00126         if (!self::get_mnet_hosts()) {
00127             $errorcode =  PORTFOLIO_MAHARA_ERR_NOHOSTS;
00128         }
00129         return $errorcode;
00130     }
00131 
00132     private static function get_mnet_hosts() {
00133         global $DB, $CFG;
00134         static $hosts;
00135         if (isset($hosts)) {
00136             return $hosts;
00137         }
00138         $hosts = $DB->get_records_sql('  SELECT
00139                                     h.id,
00140                                     h.wwwroot,
00141                                     h.ip_address,
00142                                     h.name,
00143                                     h.public_key,
00144                                     h.public_key_expires,
00145                                     h.transport,
00146                                     h.portno,
00147                                     h.last_connect_time,
00148                                     h.last_log_id,
00149                                     h.applicationid,
00150                                     a.name as app_name,
00151                                     a.display_name as app_display_name,
00152                                     a.xmlrpc_server_url
00153                                 FROM {mnet_host} h
00154                                     JOIN {mnet_application} a ON h.applicationid=a.id
00155                                     JOIN {mnet_host2service} hs1 ON hs1.hostid = h.id
00156                                     JOIN {mnet_service} s1 ON hs1.serviceid = s1.id
00157                                     JOIN {mnet_host2service} hs2 ON hs2.hostid = h.id
00158                                     JOIN {mnet_service} s2 ON hs2.serviceid = s2.id
00159                                     JOIN {mnet_host2service} hs3 ON hs3.hostid = h.id
00160                                     JOIN {mnet_service} s3 ON hs3.serviceid = s3.id
00161                                 WHERE
00162                                     h.id <> ? AND
00163                                     h.deleted = 0 AND
00164                                     a.name = ? AND
00165                                     s1.name = ? AND hs1.publish = ? AND
00166                                     s2.name = ? AND hs2.subscribe = ? AND
00167                                     s3.name = ? AND hs3.subscribe = ? AND
00168                                     s3.name = ? AND hs3.publish = ?',
00169                         array($CFG->mnet_localhost_id, 'mahara', 'sso_idp', 1, 'sso_sp', 1, 'pf', 1, 'pf', 1));
00170         return $hosts;
00171     }
00172 
00173     public function prepare_package() {
00174         $files = $this->exporter->get_tempfiles();
00175         $this->totalsize = 0;
00176         foreach ($files as $f) {
00177             $this->filesmanifest[$f->get_contenthash()] = array(
00178                 'filename' => $f->get_filename(),
00179                 'sha1'     => $f->get_contenthash(),
00180                 'size'     => $f->get_filesize(),
00181             );
00182             $this->totalsize += $f->get_filesize();
00183         }
00184 
00185         $this->set('file', $this->exporter->zip_tempfiles());  // this will throw a file_exception which the exporter catches separately.
00186     }
00187 
00188     public function send_package() {
00189         global $CFG;
00190         // send the 'content_ready' request to mahara
00191         require_once($CFG->dirroot . '/mnet/xmlrpc/client.php');
00192         $client = new mnet_xmlrpc_client();
00193         $client->set_method('portfolio/mahara/lib.php/send_content_ready');
00194         $client->add_param($this->token);
00195         $client->add_param($this->get('user')->username);
00196         $client->add_param($this->resolve_format());
00197         $client->add_param(array(
00198             'filesmanifest' => $this->filesmanifest,
00199             'zipfilesha1'   => $this->get('file')->get_contenthash(),
00200             'zipfilesize'   => $this->get('file')->get_filesize(),
00201             'totalsize'     => $this->totalsize,
00202         ));
00203         $client->add_param($this->get_export_config('wait'));
00204         $this->ensure_mnethost();
00205         if (!$client->send($this->mnethost)) {
00206             foreach ($client->error as $errormessage) {
00207                 list($code, $message) = array_map('trim',explode(':', $errormessage, 2));
00208                 $message .= "ERROR $code:<br/>$errormessage<br/>";
00209             }
00210             throw new portfolio_export_exception($this->get('exporter'), 'failedtoping', 'portfolio_mahara', '', $message);
00211         }
00212         // we should get back...  an ok and a status
00213         // either we've been waiting a while and mahara has fetched the file or has queued it.
00214         $response = (object)$client->response;
00215         if (!$response->status) {
00216             throw new portfolio_export_exception($this->get('exporter'), 'failedtoping', 'portfolio_mahara');
00217         }
00218         if ($response->type =='queued') {
00219             $this->exporter->set_forcequeue();
00220         }
00221         if (isset($response->querystring)) {
00222             $this->continueurl = $response->querystring;
00223         }
00224         // if we're not queuing the logging might have already happened
00225         $this->exporter->update_log_url($this->get_static_continue_url());
00226     }
00227 
00228     public function get_static_continue_url() {
00229         $remoteurl = '';
00230         if ($this->resolve_format() == 'file') {
00231             $remoteurl = '/artefact/file/'; // we hopefully get the files that were imported highlighted
00232         }
00233         if (isset($this->continueurl)) {
00234             $remoteurl .= $this->continueurl;
00235         }
00236         return $remoteurl;
00237     }
00238 
00239     public function resolve_static_continue_url($remoteurl) {
00240         global $CFG;
00241         $this->ensure_mnethost();
00242         $u = new moodle_url('/auth/mnet/jump.php', array('hostid' => $this->get_config('mnethostid'), 'wantsurl' => $remoteurl));
00243         return $u->out();
00244     }
00245 
00246     public function get_interactive_continue_url() {
00247         return $this->resolve_static_continue_url($this->get_static_continue_url());
00248     }
00249 
00250     public function steal_control($stage) {
00251         if ($stage != PORTFOLIO_STAGE_CONFIG) {
00252             return false;
00253         }
00254         global $CFG;
00255         return $CFG->wwwroot . '/portfolio/mahara/preconfig.php?id=' . $this->exporter->get('id');
00256     }
00257 
00258     public function verify_file_request_params($params) {
00259         return false;
00260         // the data comes from an xmlrpc request,
00261         // not a request to file.php
00262     }
00263 
00268     public function send_intent() {
00269         global $CFG, $DB;
00270         require_once($CFG->dirroot . '/mnet/xmlrpc/client.php');
00271         $client = new mnet_xmlrpc_client();
00272         $client->set_method('portfolio/mahara/lib.php/send_content_intent');
00273         $client->add_param($this->get('user')->username);
00274         $this->ensure_mnethost();
00275         if (!$client->send($this->mnethost)) {
00276             foreach ($client->error as $errormessage) {
00277                 list($code, $message) = array_map('trim',explode(':', $errormessage, 2));
00278                 $message .= "ERROR $code:<br/>$errormessage<br/>";
00279             }
00280             throw new portfolio_export_exception($this->get('exporter'), 'failedtoping', 'portfolio_mahara', '', $message);
00281         }
00282         // we should get back... the send type and a shared token
00283         $response = (object)$client->response;
00284         if (empty($response->sendtype) || empty($response->token)) {
00285             throw new portfolio_export_exception($this->get('exporter'), 'senddisallowed', 'portfolio_mahara');
00286         }
00287         switch ($response->sendtype) {
00288             case 'immediate':
00289                 $this->sendtype = PORTFOLIO_MAHARA_IMMEDIATE;
00290                 break;
00291             case 'queue':
00292                 $this->sendtype = PORTFOLIO_MAHARA_QUEUE;
00293                 break;
00294             case 'none':
00295             default:
00296                 throw new portfolio_export_exception($this->get('exporter'), 'senddisallowed', 'portfolio_mahara');
00297         }
00298         $this->token = $response->token;
00299         $this->get('exporter')->save();
00300         // put the entry in the mahara queue table now too
00301         $q = new stdClass;
00302         $q->token = $this->token;
00303         $q->transferid = $this->get('exporter')->get('id');
00304         $DB->insert_record('portfolio_mahara_queue', $q);
00305     }
00306 
00307     private function ensure_mnethost() {
00308         if (!empty($this->hostrecord) && !empty($this->mnethost)) {
00309             return;
00310         }
00311         global $DB;
00312         if (!$this->hostrecord = $DB->get_record('mnet_host', array('id' => $this->get_config('mnethostid')))) {
00313             throw new portfolio_plugin_exception(PORTFOLIO_MAHARA_ERR_INVALIDHOST, 'portfolio_mahara');
00314         }
00315         $this->mnethost = new mnet_peer();
00316         $this->mnethost->set_wwwroot($this->hostrecord->wwwroot);
00317     }
00318 
00326     public static function fetch_file($token) {
00327         global $DB;
00328         $remoteclient = get_mnet_remote_client();
00329         try {
00330             if (!$transferid = $DB->get_field('portfolio_mahara_queue', 'transferid', array('token' => $token))) {
00331                 throw new mnet_server_exception(8009, 'mnet_notoken', 'portfolio_mahara');
00332             }
00333             $exporter = portfolio_exporter::rewaken_object($transferid);
00334         } catch (portfolio_exception $e) {
00335             throw new mnet_server_exception(8010, 'mnet_noid', 'portfolio_mahara');
00336         }
00337         if ($exporter->get('instance')->get_config('mnethostid') != $remoteclient->id) {
00338             throw new mnet_server_exception(8011, 'mnet_wronghost', 'portfolio_mahara');
00339         }
00340         global $CFG;
00341         try {
00342             $i = $exporter->get('instance');
00343             $f = $i->get('file');
00344             if (empty($f) || !($f instanceof stored_file)) {
00345                 throw new mnet_server_exception(8012, 'mnet_nofile', 'portfolio_mahara');
00346             }
00347             try {
00348                 $c = $f->get_content();
00349             } catch (file_exception $e) {
00350                 throw new mnet_server_exception(8013, 'mnet_nofilecontents', 'portfolio_mahara', $e->getMessage());
00351             }
00352             $contents = base64_encode($c);
00353         } catch (Exception $e) {
00354             throw new mnet_server_exception(8013, 'mnet_nofile', 'portfolio_mahara');
00355         }
00356         $exporter->log_transfer();
00357         $exporter->process_stage_cleanup(true);
00358         return $contents;
00359     }
00360 
00361     public function cleanup() {
00362         global $DB;
00363         $DB->delete_records('portfolio_mahara_queue', array('transferid' => $this->get('exporter')->get('id'), 'token' => $this->token));
00364     }
00365 
00366 
00372     private function resolve_format() {
00373         global $CFG;
00374         $thisformat = $this->get_export_config('format');
00375         $allformats = portfolio_supported_formats();
00376         require_once($CFG->libdir . '/portfolio/formats.php');
00377         $thisobj = new $allformats[$thisformat];
00378         foreach ($this->supported_formats() as $f) {
00379             $class = $allformats[$f];
00380             if ($thisobj instanceof $class) {
00381                 return $f;
00382             }
00383         }
00384     }
00385 }
00386 
00387 
 All Data Structures Namespaces Files Functions Variables Enumerations