/** * Hook method to handle the remote request to install an add-on * * This is used as a callback when the admin picks a plugin version in the * Moodle Plugins directory and is redirected back to their site to install * it. * * This hook is called early from admin/tool/installaddon/index.php page so that * it has opportunity to take over the UI. * * @param tool_installaddon_renderer $output * @param string|null $request * @param bool $confirmed */ public function handle_remote_request(tool_installaddon_renderer $output, $request, $confirmed = false) { global $CFG; require_once dirname(__FILE__) . '/pluginfo_client.php'; if (is_null($request)) { return; } $data = $this->decode_remote_request($request); if ($data === false) { echo $output->remote_request_invalid_page($this->index_url()); exit; } list($plugintype, $pluginname) = normalize_component($data->component); $plugintypepath = $this->get_plugintype_root($plugintype); if (file_exists($plugintypepath . '/' . $pluginname)) { echo $output->remote_request_alreadyinstalled_page($data, $this->index_url()); exit; } if (!$this->is_plugintype_writable($plugintype)) { $continueurl = $this->index_url(array('installaddonrequest' => $request)); echo $output->remote_request_permcheck_page($data, $plugintypepath, $continueurl, $this->index_url()); exit; } $continueurl = $this->index_url(array('installaddonrequest' => $request, 'confirm' => 1, 'sesskey' => sesskey())); if (!$confirmed) { echo $output->remote_request_confirm_page($data, $continueurl, $this->index_url()); exit; } // The admin has confirmed their intention to install the add-on. require_sesskey(); // Fetch the plugin info. The essential information is the URL to download the ZIP // and the MD5 hash of the ZIP, obtained via HTTPS. $client = tool_installaddon_pluginfo_client::instance(); try { $pluginfo = $client->get_pluginfo($data->component, $data->version); } catch (tool_installaddon_pluginfo_exception $e) { if (debugging()) { throw $e; } else { echo $output->remote_request_pluginfo_exception($data, $e, $this->index_url()); exit; } } // Fetch the ZIP with the plugin version $jobid = md5(rand() . uniqid('', true)); $sourcedir = make_temp_directory('tool_installaddon/' . $jobid . '/source'); $zipfilename = 'downloaded.zip'; try { $this->download_file($pluginfo->downloadurl, $sourcedir . '/' . $zipfilename); } catch (tool_installaddon_installer_exception $e) { if (debugging()) { throw $e; } else { echo $output->installer_exception($e, $this->index_url()); exit; } } // Check the MD5 checksum $md5expected = $pluginfo->downloadmd5; $md5actual = md5_file($sourcedir . '/' . $zipfilename); if ($md5expected !== $md5actual) { $e = new tool_installaddon_installer_exception('err_zip_md5', array('expected' => $md5expected, 'actual' => $md5actual)); if (debugging()) { throw $e; } else { echo $output->installer_exception($e, $this->index_url()); exit; } } // Redirect to the validation page. $nexturl = new moodle_url('/admin/tool/installaddon/validate.php', array('sesskey' => sesskey(), 'jobid' => $jobid, 'zip' => $zipfilename, 'type' => $plugintype)); redirect($nexturl); }