first commit

This commit is contained in:
CHIEFSOFT\ameye
2024-09-30 18:11:26 -04:00
commit e592ca6823
27270 changed files with 5002257 additions and 0 deletions
@@ -0,0 +1,409 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Provides tool_installaddon_installer class.
*
* @package tool_installaddon
* @subpackage classes
* @copyright 2013 David Mudrak <david@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
/**
* Implements main plugin features.
*
* @copyright 2013 David Mudrak <david@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class tool_installaddon_installer {
/** @var tool_installaddon_installfromzip_form */
protected $installfromzipform = null;
/**
* Factory method returning an instance of this class.
*
* @return tool_installaddon_installer
*/
public static function instance() {
return new static();
}
/**
* Returns the URL to the main page of this admin tool
*
* @param array optional parameters
* @return moodle_url
*/
public function index_url(array $params = null) {
return new moodle_url('/admin/tool/installaddon/index.php', $params);
}
/**
* Returns URL to the repository that addons can be searched in and installed from
*
* @return moodle_url
*/
public function get_addons_repository_url() {
global $CFG;
if (!empty($CFG->config_php_settings['alternativeaddonsrepositoryurl'])) {
$url = $CFG->config_php_settings['alternativeaddonsrepositoryurl'];
} else {
$url = 'https://moodle.org/plugins/get.php';
}
if (!$this->should_send_site_info()) {
return new moodle_url($url);
}
// Append the basic information about our site.
$site = array(
'fullname' => $this->get_site_fullname(),
'url' => $this->get_site_url(),
'majorversion' => $this->get_site_major_version(),
);
$site = $this->encode_site_information($site);
return new moodle_url($url, array('site' => $site));
}
/**
* @return tool_installaddon_installfromzip_form
*/
public function get_installfromzip_form() {
if (!is_null($this->installfromzipform)) {
return $this->installfromzipform;
}
$action = $this->index_url();
$customdata = array('installer' => $this);
$this->installfromzipform = new tool_installaddon_installfromzip_form($action, $customdata);
return $this->installfromzipform;
}
/**
* Makes a unique writable storage for uploaded ZIP packages.
*
* We need the saved ZIP to survive across multiple requests so that it can
* be used by the plugin manager after the installation is confirmed. In
* other words, we cannot use make_request_directory() here.
*
* @return string full path to the directory
*/
public function make_installfromzip_storage() {
return make_unique_writable_directory(make_temp_directory('tool_installaddon'));
}
/**
* Returns localised list of available plugin types
*
* @return array (string)plugintype => (string)plugin name
*/
public function get_plugin_types_menu() {
global $CFG;
$pluginman = core_plugin_manager::instance();
$menu = array('' => get_string('choosedots'));
foreach (array_keys($pluginman->get_plugin_types()) as $plugintype) {
$menu[$plugintype] = $pluginman->plugintype_name($plugintype).' ('.$plugintype.')';
}
return $menu;
}
/**
* 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 and display the first confirmation screen.
*
* @param tool_installaddon_renderer $output
* @param string|null $request
*/
public function handle_remote_request(tool_installaddon_renderer $output, $request) {
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) = core_component::normalize_component($data->component);
$pluginman = core_plugin_manager::instance();
$plugintypepath = $pluginman->get_plugintype_root($plugintype);
if (file_exists($plugintypepath.'/'.$pluginname)) {
echo $output->remote_request_alreadyinstalled_page($data, $this->index_url());
exit();
}
if (!$pluginman->is_plugintype_writable($plugintype)) {
$continueurl = $this->index_url(array('installaddonrequest' => $request));
echo $output->remote_request_permcheck_page($data, $plugintypepath, $continueurl, $this->index_url());
exit();
}
if (!$pluginman->is_remote_plugin_installable($data->component, $data->version, $reason)) {
$data->reason = $reason;
echo $output->remote_request_non_installable_page($data, $this->index_url());
exit();
}
$continueurl = $this->index_url(array(
'installremote' => $data->component,
'installremoteversion' => $data->version
));
echo $output->remote_request_confirm_page($data, $continueurl, $this->index_url());
exit();
}
/**
* Detect the given plugin's component name
*
* Only plugins that declare valid $plugin->component value in the version.php
* are supported.
*
* @param string $zipfilepath full path to the saved ZIP file
* @return string|bool declared component name or false if unable to detect
*/
public function detect_plugin_component($zipfilepath) {
$workdir = make_request_directory();
$versionphp = $this->extract_versionphp_file($zipfilepath, $workdir);
if (empty($versionphp)) {
return false;
}
return $this->detect_plugin_component_from_versionphp(file_get_contents($workdir.'/'.$versionphp));
}
//// End of external API ///////////////////////////////////////////////////
/**
* @see self::instance()
*/
protected function __construct() {
}
/**
* @return string this site full name
*/
protected function get_site_fullname() {
global $SITE;
return strip_tags($SITE->fullname);
}
/**
* @return string this site URL
*/
protected function get_site_url() {
global $CFG;
return $CFG->wwwroot;
}
/**
* @return string major version like 2.5, 2.6 etc.
*/
protected function get_site_major_version() {
return moodle_major_version();
}
/**
* Encodes the given array in a way that can be safely appended as HTTP GET param
*
* Be ware! The recipient may rely on the exact way how the site information is encoded.
* Do not change anything here unless you know what you are doing and understand all
* consequences! (Don't you love warnings like that, too? :-p)
*
* @param array $info
* @return string
*/
protected function encode_site_information(array $info) {
return base64_encode(json_encode($info));
}
/**
* Decide if the encoded site information should be sent to the add-ons repository site
*
* For now, we just return true. In the future, we may want to implement some
* privacy aware logic (based on site/user preferences for example).
*
* @return bool
*/
protected function should_send_site_info() {
return true;
}
/**
* Decode the request from the Moodle Plugins directory
*
* @param string $request submitted via 'installaddonrequest' HTTP parameter
* @return stdClass|bool false on error, object otherwise
*/
protected function decode_remote_request($request) {
$data = base64_decode($request, true);
if ($data === false) {
return false;
}
$data = json_decode($data);
if (is_null($data)) {
return false;
}
if (!isset($data->name) or !isset($data->component) or !isset($data->version)) {
return false;
}
$data->name = s(strip_tags($data->name));
if ($data->component !== clean_param($data->component, PARAM_COMPONENT)) {
return false;
}
list($plugintype, $pluginname) = core_component::normalize_component($data->component);
if ($plugintype === 'core') {
return false;
}
if ($data->component !== $plugintype.'_'.$pluginname) {
return false;
}
if (!core_component::is_valid_plugin_name($plugintype, $pluginname)) {
return false;
}
$plugintypes = core_component::get_plugin_types();
if (!isset($plugintypes[$plugintype])) {
return false;
}
// Keep this regex in sync with the one used by the download.moodle.org/api/x.y/pluginfo.php
if (!preg_match('/^[0-9]+$/', $data->version)) {
return false;
}
return $data;
}
/**
* Extracts the version.php from the given plugin ZIP file into the target directory
*
* @param string $zipfilepath full path to the saved ZIP file
* @param string $targetdir full path to extract the file to
* @return string|bool path to the version.php within the $targetpath; false on error (e.g. not found)
*/
protected function extract_versionphp_file($zipfilepath, $targetdir) {
global $CFG;
require_once($CFG->libdir.'/filelib.php');
$fp = get_file_packer('application/zip');
$files = $fp->list_files($zipfilepath);
if (empty($files)) {
return false;
}
$rootdirname = null;
$found = null;
foreach ($files as $file) {
// Valid plugin ZIP package has just one root directory with all
// files in it.
$pathnameitems = explode('/', $file->pathname);
if (empty($pathnameitems)) {
return false;
}
// Set the expected name of the root directory in the first
// iteration of the loop.
if ($rootdirname === null) {
$rootdirname = $pathnameitems[0];
}
// Require the same root directory for all files in the ZIP
// package.
if ($rootdirname !== $pathnameitems[0]) {
return false;
}
// If we reached the valid version.php file, remember it.
if ($pathnameitems[1] === 'version.php' and !$file->is_directory and $file->size > 0) {
$found = $file->pathname;
}
}
if (empty($found)) {
return false;
}
$extracted = $fp->extract_to_pathname($zipfilepath, $targetdir, array($found));
if (empty($extracted)) {
return false;
}
// The following syntax uses function array dereferencing, added in PHP 5.4.0.
return array_keys($extracted)[0];
}
/**
* Return the plugin component declared in its version.php file
*
* @param string $code the contents of the version.php file
* @return string|bool declared plugin component or false if unable to detect
*/
protected function detect_plugin_component_from_versionphp($code) {
$result = preg_match_all('#^\s*\$plugin\->component\s*=\s*([\'"])(.+?_.+?)\1\s*;#m', $code, $matches);
// Return if and only if the single match was detected.
if ($result === 1 and !empty($matches[2][0])) {
return $matches[2][0];
}
return false;
}
}
@@ -0,0 +1,125 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* @package tool_installaddon
* @subpackage classes
* @category form
* @copyright 2013 David Mudrak <david@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
require_once($CFG->libdir.'/formslib.php');
/**
* Defines a simple form for uploading the add-on ZIP package
*
* @copyright 2013 David Mudrak <david@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class tool_installaddon_installfromzip_form extends moodleform {
/**
* Defines the form elements
*/
public function definition() {
$mform = $this->_form;
$installer = $this->_customdata['installer'];
$mform->addElement('header', 'general', get_string('installfromzip', 'tool_installaddon'));
$mform->addHelpButton('general', 'installfromzip', 'tool_installaddon');
$mform->addElement('filepicker', 'zipfile', get_string('installfromzipfile', 'tool_installaddon'),
null, array('accepted_types' => '.zip'));
$mform->addHelpButton('zipfile', 'installfromzipfile', 'tool_installaddon');
$mform->addRule('zipfile', null, 'required', null, 'client');
$options = $installer->get_plugin_types_menu();
$mform->addElement('select', 'plugintype', get_string('installfromziptype', 'tool_installaddon'), $options,
array('id' => 'tool_installaddon_installfromzip_plugintype'));
$mform->addHelpButton('plugintype', 'installfromziptype', 'tool_installaddon');
$mform->setAdvanced('plugintype');
$mform->addElement('static', 'permcheck', '',
html_writer::span(get_string('permcheck', 'tool_installaddon'), '',
array('id' => 'tool_installaddon_installfromzip_permcheck')));
$mform->setAdvanced('permcheck');
$mform->addElement('text', 'rootdir', get_string('installfromziprootdir', 'tool_installaddon'));
$mform->addHelpButton('rootdir', 'installfromziprootdir', 'tool_installaddon');
$mform->setType('rootdir', PARAM_PLUGIN);
$mform->setAdvanced('rootdir');
$this->add_action_buttons(false, get_string('installfromzipsubmit', 'tool_installaddon'));
}
/**
* Switch the form to a mode that requires manual selection of the plugin type
*/
public function require_explicit_plugintype() {
$mform = $this->_form;
$mform->addRule('plugintype', get_string('required'), 'required', null, 'client');
$mform->setAdvanced('plugintype', false);
$mform->setAdvanced('permcheck', false);
$typedetectionfailed = $mform->createElement('static', 'typedetectionfailed', '',
html_writer::span(get_string('typedetectionfailed', 'tool_installaddon'), 'error'));
$mform->insertElementBefore($typedetectionfailed, 'permcheck');
}
/**
* Warn that the selected plugin type does not match the detected one.
*
* @param string $detected detected plugin type
*/
public function selected_plugintype_mismatch($detected) {
$mform = $this->_form;
$mform->addRule('plugintype', get_string('required'), 'required', null, 'client');
$mform->setAdvanced('plugintype', false);
$mform->setAdvanced('permcheck', false);
$mform->insertElementBefore($mform->createElement('static', 'selectedplugintypemismatch', '',
html_writer::span(get_string('typedetectionmismatch', 'tool_installaddon', $detected), 'error')), 'permcheck');
}
/**
* Validate the form fields
*
* @param array $data
* @param array $files
* @return array (string)field name => (string)validation error text
*/
public function validation($data, $files) {
$pluginman = core_plugin_manager::instance();
$errors = parent::validation($data, $files);
if (!empty($data['plugintype'])) {
if (!$pluginman->is_plugintype_writable($data['plugintype'])) {
$path = $pluginman->get_plugintype_root($data['plugintype']);
$errors['plugintype'] = get_string('permcheckresultno', 'tool_installaddon', array('path' => $path));
}
}
return $errors;
}
}
@@ -0,0 +1,46 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Privacy Subsystem implementation for tool_installaddon.
*
* @package tool_installaddon
* @copyright 2018 Zig Tan <zig@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace tool_installaddon\privacy;
defined('MOODLE_INTERNAL') || die();
/**
* Privacy Subsystem for tool_installaddon implementing null_provider.
*
* @copyright 2018 Zig Tan <zig@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class provider implements \core_privacy\local\metadata\null_provider {
/**
* Get the language string identifier with the component's language
* file to explain why this plugin stores no data.
*
* @return string
*/
public static function get_reason(): string {
return 'privacy:metadata';
}
}
+142
View File
@@ -0,0 +1,142 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* The main screen of the tool.
*
* @package tool_installaddon
* @copyright 2013 David Mudrak <david@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require(__DIR__ . '/../../../config.php');
require_once($CFG->libdir.'/adminlib.php');
admin_externalpage_setup('tool_installaddon_index');
if (!empty($CFG->disableupdateautodeploy)) {
notice(get_string('featuredisabled', 'tool_installaddon'));
}
$pluginman = core_plugin_manager::instance();
$installer = tool_installaddon_installer::instance();
$output = $PAGE->get_renderer('tool_installaddon');
$output->set_installer_instance($installer);
// Handle the eventual request for installing from remote repository.
$remoterequest = optional_param('installaddonrequest', null, PARAM_RAW);
$installer->handle_remote_request($output, $remoterequest);
// Handle the confirmed installation request.
$installremote = optional_param('installremote', null, PARAM_COMPONENT);
$installremoteversion = optional_param('installremoteversion', null, PARAM_INT);
$installremoteconfirm = optional_param('installremoteconfirm', false, PARAM_BOOL);
if ($installremote and $installremoteversion) {
require_sesskey();
require_once($CFG->libdir.'/upgradelib.php');
$PAGE->set_pagelayout('maintenance');
$PAGE->set_popup_notification_allowed(false);
if ($pluginman->is_remote_plugin_installable($installremote, $installremoteversion)) {
$installable = array($pluginman->get_remote_plugin_info($installremote, $installremoteversion, true));
upgrade_install_plugins($installable, $installremoteconfirm,
get_string('installfromrepo', 'tool_installaddon'),
new moodle_url($PAGE->url, array('installremote' => $installremote,
'installremoteversion' => $installremoteversion, 'installremoteconfirm' => 1)
)
);
}
// We should never get here.
throw new moodle_exception('installing_non_installable_component', 'tool_installaddon');
}
// Handle installation of a plugin from the ZIP file.
$installzipcomponent = optional_param('installzipcomponent', null, PARAM_COMPONENT);
$installzipstorage = optional_param('installzipstorage', null, PARAM_FILE);
$installzipconfirm = optional_param('installzipconfirm', false, PARAM_BOOL);
if ($installzipcomponent and $installzipstorage) {
require_sesskey();
require_once($CFG->libdir.'/upgradelib.php');
$PAGE->set_pagelayout('maintenance');
$PAGE->set_popup_notification_allowed(false);
$installable = array((object)array(
'component' => $installzipcomponent,
'zipfilepath' => make_temp_directory('tool_installaddon').'/'.$installzipstorage.'/plugin.zip',
));
upgrade_install_plugins($installable, $installzipconfirm, get_string('installfromzip', 'tool_installaddon'),
new moodle_url($installer->index_url(), array('installzipcomponent' => $installzipcomponent,
'installzipstorage' => $installzipstorage, 'installzipconfirm' => 1)
)
);
}
$form = $installer->get_installfromzip_form();
if ($form->is_cancelled()) {
redirect($PAGE->url);
} else if ($data = $form->get_data()) {
$storage = $installer->make_installfromzip_storage();
$form->save_file('zipfile', $storage.'/plugin.zip');
$ziprootdir = $pluginman->get_plugin_zip_root_dir($storage.'/plugin.zip');
if (empty($ziprootdir)) {
echo $output->zip_not_valid_plugin_package_page($installer->index_url());
die();
}
$component = $installer->detect_plugin_component($storage.'/plugin.zip');
if (!empty($component) and !empty($data->plugintype)) {
// If the plugin type was explicitly set, make sure it matches the detected one.
list($detectedtype, $detectedname) = core_component::normalize_component($component);
if ($detectedtype !== $data->plugintype) {
$form->selected_plugintype_mismatch($detectedtype);
echo $output->index_page();
die();
}
}
if (empty($component)) {
// This should not happen as all plugins are supposed to declare their
// component. Still, let admins upload legacy packages if they want/need.
if (empty($data->plugintype)) {
$form->require_explicit_plugintype();
echo $output->index_page();
die();
}
if (!empty($data->rootdir)) {
$usepluginname = $data->rootdir;
} else {
$usepluginname = $ziprootdir;
}
$component = $data->plugintype.'_'.$usepluginname;
}
redirect($installer->index_url(array(
'installzipcomponent' => $component,
'installzipstorage' => basename($storage),
'sesskey' => sesskey(),
)));
}
// Display the tool main page.
echo $output->index_page();
@@ -0,0 +1,62 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Strings for the tool_installaddon component.
*
* @package tool_installaddon
* @category string
* @copyright 2013 David Mudrak <david@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$string['acknowledgement'] = 'Acknowledgement';
$string['acknowledgementtext'] = 'I understand that it is my responsibility to have full backups of this site prior to installing additional plugins. I accept and understand that plugins (especially but not only those originating in unofficial sources) may contain security holes, can make the site unavailable, or cause private data leaks or loss.';
$string['featuredisabled'] = 'The plugin installer is disabled on this site.';
$string['installaddon'] = 'Install plugin!';
$string['installaddons'] = 'Install plugins';
$string['installfromrepo'] = 'Install plugins from the Moodle plugins directory';
$string['installfromrepo_help'] = 'You will be redirected to the Moodle plugins directory to search for and install a plugin. Note that your site full name, URL and Moodle version will be sent as well, to make the installation process easier for you.';
$string['installfromzip'] = 'Install plugin from ZIP file';
$string['installfromzip_help'] = 'An alternative to installing a plugin directly from the Moodle plugins directory is to upload a ZIP package of the plugin. The ZIP package should have the same structure as a package downloaded from the Moodle plugins directory.';
$string['installfromzipfile'] = 'ZIP package';
$string['installfromzipfile_help'] = 'The plugin ZIP package must contain just one directory, named to match the plugin name. The ZIP will be extracted into an appropriate location for the plugin type. If the package has been downloaded from the Moodle plugins directory then it will have this structure.';
$string['installfromzipinvalid'] = 'The plugin ZIP package must contain just one directory, named to match the plugin name. The file provided is not a valid plugin ZIP package.';
$string['installfromziprootdir'] = 'Rename the root directory';
$string['installfromziprootdir_help'] = 'Some ZIP packages, such as those generated by Github, may contain an incorrect root directory name. If so, the correct name may be entered here.';
$string['installfromzipsubmit'] = 'Install plugin from the ZIP file';
$string['installfromziptype'] = 'Plugin type';
$string['installfromziptype_help'] = 'For plugins that correctly declare their component name, the installer is able to detect the plugin type automatically. If the auto-detection fails, choose the correct type of plugin manually. Warning: The installation procedure can fail badly if an incorrect plugin type is specified.';
$string['installfromziptype_link'] = 'Development:Plugins';
$string['permcheck'] = 'Make sure the plugin type root location is writable by the web server process.';
$string['permcheckerror'] = 'Error while checking for write permission';
$string['permcheckprogress'] = 'Checking for write permission ...';
$string['permcheckresultno'] = 'Plugin type location <em>{$a->path}</em> is not writable';
$string['permcheckresultyes'] = 'Plugin type location <em>{$a->path}</em> is writable';
$string['permcheckrepeat'] = 'Check again';
$string['pluginname'] = 'Plugin installer';
$string['remoterequestalreadyinstalled'] = 'There is a request to install plugin {$a->name} ({$a->component}) version {$a->version} from the Moodle plugins directory on this site. However, this plugin is <strong>already installed</strong> on the site.';
$string['remoterequestconfirm'] = 'There is a request to install plugin <strong>{$a->name}</strong> ({$a->component}) version {$a->version} from the Moodle plugins directory on this site. If you continue, the plugin ZIP package will be downloaded for validation. Nothing will be installed yet.';
$string['remoterequestinvalid'] = 'There is a request to install a plugin from the Moodle plugins directory on this site. Unfortunately the request is not valid and so the plugin cannot be installed.';
$string['remoterequestpermcheck'] = 'There is a request to install plugin {$a->name} ({$a->component}) version {$a->version} from the Moodle plugins directory on this site. However, the location <strong>{$a->typepath}</strong> is <strong>not writable</strong>. You need to give write access for the web server user to the location, then press the continue button to repeat the check.';
$string['remoterequestpluginfoexception'] = 'Oops... An error occurred while trying to obtain information about the plugin {$a->name} ({$a->component}) version {$a->version}. The plugin cannot be installed. Turn debugging mode on to see details of the error.';
$string['remoterequestnoninstallable'] = 'There is a request to install plugin {$a->name} ({$a->component}) version {$a->version} from the Moodle plugins directory on this site. However, the plugin installation pre-check failed (reason code: {$a->reason}).';
$string['typedetectionfailed'] = 'Unable to detect the plugin type. Please choose the plugin type manually.';
$string['typedetectionmismatch'] = 'The selected plugin type does not match the one declared by the plugin: {$a}';
$string['privacy:metadata'] = 'The Plugin installer plugin does not store any personal data.';
+73
View File
@@ -0,0 +1,73 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Checks the write permission for the given plugin type
*
* @package tool_installaddon
* @subpackage ajax
* @copyright 2013 David Mudrak <david@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
define('AJAX_SCRIPT', true);
require(__DIR__ . '/../../../config.php');
require_once($CFG->libdir.'/adminlib.php');
require_login(null, false);
if (!has_capability('moodle/site:config', context_system::instance())) {
header('HTTP/1.1 403 Forbidden');
die();
}
if (!empty($CFG->disableupdateautodeploy)) {
header('HTTP/1.1 403 Forbidden');
die();
}
if (!confirm_sesskey()) {
header('HTTP/1.1 403 Forbidden');
die();
}
$plugintype = optional_param('plugintype', null, PARAM_ALPHANUMEXT);
if (is_null($plugintype)) {
header('HTTP/1.1 400 Bad Request');
die();
}
$pluginman = core_plugin_manager::instance();
$plugintypepath = $pluginman->get_plugintype_root($plugintype);
if (empty($plugintypepath)) {
header('HTTP/1.1 400 Bad Request');
die();
}
$response = array('path' => $plugintypepath);
if ($pluginman->is_plugintype_writable($plugintype)) {
$response['writable'] = 1;
} else {
$response['writable'] = 0;
}
header('Content-Type: application/json; charset: utf-8');
echo json_encode($response);
Binary file not shown.

After

Width:  |  Height:  |  Size: 329 B

+3
View File
@@ -0,0 +1,3 @@
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
<!ENTITY ns_flows "http://ns.adobe.com/Flows/1.0/">
]><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" preserveAspectRatio="xMinYMid meet" overflow="visible"><path d="M16 9v6c0 .5-.5 1-1 1H1c-.5 0-1-.5-1-1V9c0-.5.5-1 1-1h1c.5 0 1 .5 1 1v4h10V9c0-.5.5-1 1-1h1c.5 0 1 .5 1 1zm-3.6-3.9l-.7-.7c-.4-.4-1-.4-1.4 0l-.8.8V1c0-.5-.4-1-1-1h-1c-.5 0-1 .5-1 1v4.2l-.8-.8c-.4-.4-1-.4-1.4 0l-.7.7c-.4.4-.4 1 0 1.4l3.7 3.7c.2.2.5.3.7.3.3 0 .5-.1.7-.3l3.7-3.7c.4-.3.4-1 0-1.4z" fill="#888"/></svg>

After

Width:  |  Height:  |  Size: 616 B

+236
View File
@@ -0,0 +1,236 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Output rendering for the plugin.
*
* @package tool_installaddon
* @category output
* @copyright 2013 David Mudrak <david@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
/**
* Implements the plugin renderer
*
* @copyright 2013 David Mudrak <david@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class tool_installaddon_renderer extends plugin_renderer_base {
/** @var tool_installaddon_installer */
protected $installer = null;
/**
* Sets the tool_installaddon_installer instance being used.
*
* @throws coding_exception if the installer has been already set
* @param tool_installaddon_installer $installer
*/
public function set_installer_instance(tool_installaddon_installer $installer) {
if (is_null($this->installer)) {
$this->installer = $installer;
} else {
throw new coding_exception('Attempting to reset the installer instance.');
}
}
/**
* Defines the index page layout
*
* @return string
*/
public function index_page() {
if (is_null($this->installer)) {
throw new coding_exception('Installer instance has not been set.');
}
$permcheckurl = new moodle_url('/admin/tool/installaddon/permcheck.php');
$this->page->requires->yui_module('moodle-tool_installaddon-permcheck', 'M.tool_installaddon.permcheck.init',
array(array('permcheckurl' => $permcheckurl->out())));
$this->page->requires->strings_for_js(
array('permcheckprogress', 'permcheckresultno', 'permcheckresultyes', 'permcheckerror', 'permcheckrepeat'),
'tool_installaddon');
$out = $this->output->header();
$out .= $this->index_page_heading();
$out .= $this->index_page_repository();
$out .= $this->index_page_upload();
$out .= $this->output->footer();
return $out;
}
/**
* Inform the user that the ZIP is not a valid plugin package file.
*
* @param moodle_url $continueurl
* @return string
*/
public function zip_not_valid_plugin_package_page(moodle_url $continueurl) {
$out = $this->output->header();
$out .= $this->output->heading(get_string('installfromzip', 'tool_installaddon'));
$out .= $this->output->box(get_string('installfromzipinvalid', 'tool_installaddon'), 'generalbox', 'notice');
$out .= $this->output->continue_button($continueurl, 'get');
$out .= $this->output->footer();
return $out;
}
/**
* Inform the user about invalid remote installation request.
*
* @param moodle_url $continueurl
* @return string
*/
public function remote_request_invalid_page(moodle_url $continueurl) {
$out = $this->output->header();
$out .= $this->output->heading(get_string('installfromrepo', 'tool_installaddon'));
$out .= $this->output->box(get_string('remoterequestinvalid', 'tool_installaddon'), 'generalbox', 'notice');
$out .= $this->output->continue_button($continueurl, 'get');
$out .= $this->output->footer();
return $out;
}
/**
* Inform the user that such plugin is already installed
*
* @param stdClass $data decoded request data
* @param moodle_url $continueurl
* @return string
*/
public function remote_request_alreadyinstalled_page(stdClass $data, moodle_url $continueurl) {
$out = $this->output->header();
$out .= $this->output->heading(get_string('installfromrepo', 'tool_installaddon'));
$out .= $this->output->box(get_string('remoterequestalreadyinstalled', 'tool_installaddon', $data), 'generalbox', 'notice');
$out .= $this->output->continue_button($continueurl, 'get');
$out .= $this->output->footer();
return $out;
}
/**
* Let the user confirm the remote installation request.
*
* @param stdClass $data decoded request data
* @param moodle_url $continueurl
* @param moodle_url $cancelurl
* @return string
*/
public function remote_request_confirm_page(stdClass $data, moodle_url $continueurl, moodle_url $cancelurl) {
$out = $this->output->header();
$out .= $this->output->heading(get_string('installfromrepo', 'tool_installaddon'));
$out .= $this->output->confirm(get_string('remoterequestconfirm', 'tool_installaddon', $data), $continueurl, $cancelurl);
$out .= $this->output->footer();
return $out;
}
/**
* Inform the user that the target plugin type location is not writable.
*
* @param stdClass $data decoded request data
* @param string $plugintypepath full path to the plugin type location
* @param moodle_url $continueurl to repeat the write permission check
* @param moodle_url $cancelurl to cancel the installation
* @return string
*/
public function remote_request_permcheck_page(stdClass $data, $plugintypepath, moodle_url $continueurl, moodle_url $cancelurl) {
$data->typepath = $plugintypepath;
$out = $this->output->header();
$out .= $this->output->heading(get_string('installfromrepo', 'tool_installaddon'));
$out .= $this->output->confirm(get_string('remoterequestpermcheck', 'tool_installaddon', $data), $continueurl, $cancelurl);
$out .= $this->output->footer();
return $out;
}
/**
* Inform the user that the requested remote plugin is not installable.
*
* @param stdClass $data decoded request data with ->reason property added
* @param moodle_url $continueurl
* @return string
*/
public function remote_request_non_installable_page(stdClass $data, moodle_url $continueurl) {
$out = $this->output->header();
$out .= $this->output->heading(get_string('installfromrepo', 'tool_installaddon'));
$out .= $this->output->box(get_string('remoterequestnoninstallable', 'tool_installaddon', $data), 'generalbox', 'notice');
$out .= $this->output->continue_button($continueurl, 'get');
$out .= $this->output->footer();
return $out;
}
// End of the external API /////////////////////////////////////////////////
/**
* Renders the index page heading
*
* @return string
*/
protected function index_page_heading() {
return $this->output->heading(get_string('pluginname', 'tool_installaddon'));
}
/**
* Renders the widget for browsing the add-on repository
*
* @return string
*/
protected function index_page_repository() {
$url = $this->installer->get_addons_repository_url();
$out = $this->box(
$this->output->single_button($url, get_string('installfromrepo', 'tool_installaddon'), 'get').
$this->output->help_icon('installfromrepo', 'tool_installaddon'),
'generalbox', 'installfromrepobox'
);
return $out;
}
/**
* Renders the widget for uploading the add-on ZIP package
*
* @return string
*/
protected function index_page_upload() {
$form = $this->installer->get_installfromzip_form();
ob_start();
$form->display();
$out = ob_get_clean();
$out = $this->box($out, 'generalbox', 'installfromzipbox');
return $out;
}
}
+33
View File
@@ -0,0 +1,33 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Puts the plugin actions into the admin settings tree.
*
* @package tool_installaddon
* @copyright 2013 David Mudrak <david@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
if ($hassiteconfig and empty($CFG->disableupdateautodeploy)) {
$ADMIN->add('modules', new admin_externalpage('tool_installaddon_index',
get_string('installaddons', 'tool_installaddon'),
"$CFG->wwwroot/$CFG->admin/tool/installaddon/index.php"), 'modsettings');
}
+13
View File
@@ -0,0 +1,13 @@
#page-admin-tool-installaddon-index #installfromrepobox {
text-align: center;
padding-top: 2em;
padding-bottom: 2em;
}
#page-admin-tool-installaddon-index #installfromrepobox .singlebutton {
display: inline-block;
}
#page-admin-tool-installaddon-index #installfromrepobox .singlebutton input[type=submit] {
padding: 1em;
}
@@ -0,0 +1,60 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Provides {@link testable_tool_installaddon_installer} class.
*
* @package tool_installaddon
* @subpackage fixtures
* @category test
* @copyright 2013, 2015 David Mudrak <david@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
/**
* Testable subclass of the tested class
*
* @copyright 2013 David Mudrak <david@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class testable_tool_installaddon_installer extends tool_installaddon_installer {
public function get_site_fullname() {
return strip_tags('<h1 onmouseover="alert(\'Hello Moodle.org!\');">Nasty site</h1>');
}
public function get_site_url() {
return 'file:///etc/passwd';
}
public function get_site_major_version() {
return "2.5'; DROP TABLE mdl_user; --";
}
public function testable_decode_remote_request($request) {
return parent::decode_remote_request($request);
}
protected function should_send_site_info() {
return true;
}
public function testable_detect_plugin_component_from_versionphp($code) {
return parent::detect_plugin_component_from_versionphp($code);
}
}
@@ -0,0 +1,157 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace tool_installaddon;
use testable_tool_installaddon_installer;
use tool_installaddon_installer;
defined('MOODLE_INTERNAL') || die();
global $CFG;
require_once(__DIR__.'/fixtures/testable_installer.php');
/**
* Unit tests for the {@link tool_installaddon_installer} class
*
* @package tool_installaddon
* @category test
* @copyright 2013 David Mudrak <david@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class installer_test extends \advanced_testcase {
public function test_get_addons_repository_url(): void {
$installer = testable_tool_installaddon_installer::instance();
$url = $installer->get_addons_repository_url();
$query = parse_url($url, PHP_URL_QUERY);
$this->assertEquals(1, preg_match('~^site=(.+)$~', $query, $matches));
$site = rawurldecode($matches[1]);
$site = json_decode(base64_decode($site), true);
$this->assertIsArray($site);
$this->assertEquals(3, count($site));
$this->assertSame('Nasty site', $site['fullname']);
$this->assertSame('file:///etc/passwd', $site['url']);
$this->assertSame("2.5'; DROP TABLE mdl_user; --", $site['majorversion']);
}
public function test_decode_remote_request(): void {
$installer = testable_tool_installaddon_installer::instance();
$request = base64_encode(json_encode(array(
'name' => '<h1>Stamp collection</h1>"; DELETE FROM mdl_users; --',
'component' => 'mod_stampcoll',
'version' => 2013032800,
)));
$request = $installer->testable_decode_remote_request($request);
$this->assertTrue(is_object($request));
// One, my little hobbit, never trusts the input parameters!
$this->assertEquals('Stamp collection&quot;; DELETE FROM mdl_users; --', $request->name);
$this->assertEquals('mod_stampcoll', $request->component);
$this->assertEquals(2013032800, $request->version);
$request = base64_encode(json_encode(array(
'name' => 'Theme with invalid version number',
'component' => 'theme_invalid',
'version' => '1.0',
)));
$this->assertSame(false, $installer->testable_decode_remote_request($request));
$request = base64_encode(json_encode(array(
'name' => 'Invalid activity name',
'component' => 'mod_invalid_activity',
'version' => 2013032800,
)));
$this->assertSame(false, $installer->testable_decode_remote_request($request));
$request = base64_encode(json_encode(array(
'name' => 'Moodle 3.0',
'component' => 'core',
'version' => 2022010100,
)));
$this->assertSame(false, $installer->testable_decode_remote_request($request));
$request = base64_encode(json_encode(array(
'name' => 'Invalid core subsystem',
'component' => 'core_cache',
'version' => 2014123400,
)));
$this->assertSame(false, $installer->testable_decode_remote_request($request));
$request = base64_encode(json_encode(array(
'name' => 'Non-existing plugintype',
'component' => 'david_mudrak',
'version' => 2012123199,
)));
$this->assertSame(false, $installer->testable_decode_remote_request($request));
$request = base64_encode(json_encode(array(
'name' => 'Bogus module name',
'component' => 'mod_xxx_yyy',
'version' => 2012123190,
)));
$this->assertSame(false, $installer->testable_decode_remote_request($request));
}
public function test_detect_plugin_component(): void {
global $CFG;
$installer = tool_installaddon_installer::instance();
$zipfile = $CFG->libdir.'/tests/fixtures/update_validator/zips/bar.zip';
$this->assertEquals('foo_bar', $installer->detect_plugin_component($zipfile));
$zipfile = $CFG->libdir.'/tests/fixtures/update_validator/zips/invalidroot.zip';
$this->assertFalse($installer->detect_plugin_component($zipfile));
}
public function test_detect_plugin_component_from_versionphp(): void {
global $CFG;
$installer = testable_tool_installaddon_installer::instance();
$fixtures = $CFG->libdir.'/tests/fixtures/update_validator/';
$this->assertEquals('bar_bar_conan', $installer->testable_detect_plugin_component_from_versionphp('
$plugin->version = 2014121300;
$plugin->component= "bar_bar_conan" ; // Go Arnie go!'));
$versionphp = file_get_contents($fixtures.'/github/moodle-repository_mahara-master/version.php');
$this->assertEquals('repository_mahara', $installer->testable_detect_plugin_component_from_versionphp($versionphp));
$versionphp = file_get_contents($fixtures.'/nocomponent/baz/version.php');
$this->assertFalse($installer->testable_detect_plugin_component_from_versionphp($versionphp));
}
public function test_make_installfromzip_storage(): void {
$installer = testable_tool_installaddon_installer::instance();
// Check we get writable directory.
$storage1 = $installer->make_installfromzip_storage();
$this->assertTrue(is_dir($storage1));
$this->assertTrue(is_writable($storage1));
file_put_contents($storage1.'/hello.txt', 'Find me if you can!');
// Check we get unique directory on each call.
$storage2 = $installer->make_installfromzip_storage();
$this->assertTrue(is_dir($storage2));
$this->assertTrue(is_writable($storage2));
$this->assertFalse(file_exists($storage2.'/hello.txt'));
// Check both are in the same parent directory.
$this->assertEquals(dirname($storage1), dirname($storage2));
}
}
+29
View File
@@ -0,0 +1,29 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* @package tool_installaddon
* @copyright 2013 David Mudrak <david@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$plugin->component = 'tool_installaddon';
$plugin->version = 2024042200;
$plugin->requires = 2024041600;
$plugin->maturity = MATURITY_STABLE;
+124
View File
@@ -0,0 +1,124 @@
/**
* Check for write permission for the selected plugin type
*
* @module moodle-tool_installaddon-permcheck
* @author David Mudrak <david@moodle.com>
*/
YUI.add('moodle-tool_installaddon-permcheck', function(Y) {
M.tool_installaddon = M.tool_installaddon || {};
/**
* @class permcheck
* @static
*/
M.tool_installaddon.permcheck = {
/**
* @method init
* @param {Object} config Configuration passed from the PHP
*/
init : function(config) {
this.config = config;
var plugintypesel = Y.one('#tool_installaddon_installfromzip_plugintype');
if (plugintypesel) {
plugintypesel.on('change', function() {
this.check_for_permission(plugintypesel);
}, this);
this.repeat_permcheck_icon = Y.Node.create('<div><a href="#repeat-permcheck"><img src="' + M.util.image_url('i/reload') + '" /> ' +
M.util.get_string('permcheckrepeat', 'tool_installaddon') + '</a></div>');
this.repeat_permcheck_icon.one('a').on('click', function(e) {
e.preventDefault();
this.check_for_permission(plugintypesel);
}, this);
}
},
/**
* @method check_for_permission
* @param {Node} plugintypesel Plugin type selector node
*/
check_for_permission : function(plugintypesel) {
var plugintype = plugintypesel.get('value');
if (plugintype == '') {
return;
}
Y.log('Selected plugin type: ' + plugintype, 'debug', 'moodle-tool_installaddon-permcheck');
Y.io(this.config.permcheckurl, {
'method' : 'GET',
'data' : {
'sesskey' : M.cfg.sesskey,
'plugintype' : plugintype
},
'context' : this,
'on' : {
'start' : function(transid, args) {
this.showresult(M.util.get_string('permcheckprogress', 'tool_installaddon'), 'progress');
},
'success': function(transid, outcome, args) {
var response;
try {
response = Y.JSON.parse(outcome.responseText);
if (response.error) {
Y.log(response.error, 'error', 'moodle-tool_installaddon-permcheck');
this.showresult(M.util.get_string('permcheckerror', 'tool_installaddon', response), 'error');
} else if (response.path && response.writable == 1) {
this.showresult(M.util.get_string('permcheckresultyes', 'tool_installaddon', response), 'success');
} else if (response.path && response.writable == 0) {
this.showresult(M.util.get_string('permcheckresultno', 'tool_installaddon', response), 'error');
} else {
Y.log(response, 'debug', 'moodle-tool_installaddon-permcheck');
this.showresult(M.util.get_string('permcheckerror', 'tool_installaddon', response), 'error');
}
} catch (e) {
Y.log(e, 'error', 'moodle-tool_installaddon-permcheck');
this.showresult(M.util.get_string('permcheckerror', 'tool_installaddon'), 'error');
}
},
'failure': function(transid, outcome, args) {
Y.log(outcome.statusText, 'error', 'moodle-tool_installaddon-permcheck');
this.showresult(M.util.get_string('permcheckerror', 'tool_installaddon'));
}
}
});
},
/**
* @method showresult
* @param {String} msg Message to display
* @param {String} status Message status
*/
showresult : function(msg, status) {
var resultline = Y.one('#tool_installaddon_installfromzip_permcheck');
if (resultline) {
if (status === 'success') {
resultline.setHTML('<span class="success"><img src="' + M.util.image_url('i/valid') + '" /> ' +
msg + '</span>');
} else if (status === 'progress') {
resultline.setHTML('<span class="progress"><img src="' + M.cfg.loadingicon + '" /> ' +
msg + '</span>');
} else {
resultline.setHTML('<span class="error"><img src="' + M.util.image_url('i/invalid') + '" /> ' +
msg + '</span>').append(this.repeat_permcheck_icon);
}
}
},
/**
* @property
* @type {Y.Node}
*/
repeat_permcheck_icon : null,
/**
* @property
* @type {Object}
*/
config : null
};
}, '@VERSION@', {
requires:['node', 'event', 'io-base']
});