mirror of
https://github.com/moodle/moodle.git
synced 2025-08-06 09:26:35 +02:00
MDL-38509 Check for writable plugin type location in install from ZIP form
Standard mform validation is implemented as well as progressively enhanced AJAX version.
This commit is contained in:
parent
2459758b30
commit
ddab904ba8
6 changed files with 245 additions and 2 deletions
|
@ -34,6 +34,9 @@ defined('MOODLE_INTERNAL') || die();
|
||||||
*/
|
*/
|
||||||
class tool_installaddon_installer {
|
class tool_installaddon_installer {
|
||||||
|
|
||||||
|
/** @var tool_installaddon_installfromzip */
|
||||||
|
protected $installfromzipform = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Factory method returning an instance of this class.
|
* Factory method returning an instance of this class.
|
||||||
*
|
*
|
||||||
|
@ -80,10 +83,16 @@ class tool_installaddon_installer {
|
||||||
global $CFG;
|
global $CFG;
|
||||||
require_once(dirname(__FILE__).'/installfromzip_form.php');
|
require_once(dirname(__FILE__).'/installfromzip_form.php');
|
||||||
|
|
||||||
|
if (!is_null($this->installfromzipform)) {
|
||||||
|
return $this->installfromzipform;
|
||||||
|
}
|
||||||
|
|
||||||
$action = new moodle_url('/admin/tool/installaddon/index.php');
|
$action = new moodle_url('/admin/tool/installaddon/index.php');
|
||||||
$customdata = array('installer' => $this);
|
$customdata = array('installer' => $this);
|
||||||
|
|
||||||
return new tool_installaddon_installfromzip($action, $customdata);
|
$this->installfromzipform = new tool_installaddon_installfromzip($action, $customdata);
|
||||||
|
|
||||||
|
return $this->installfromzipform;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -105,6 +114,33 @@ class tool_installaddon_installer {
|
||||||
return $menu;
|
return $menu;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is it possible to create a new plugin directory for the given plugin type?
|
||||||
|
*
|
||||||
|
* @throws coding_exception for invalid plugin types or non-existing plugin type locations
|
||||||
|
* @param string $plugintype
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
public function is_plugintype_writable($plugintype) {
|
||||||
|
|
||||||
|
$plugintypepath = null;
|
||||||
|
foreach (get_plugin_types() as $type => $fullpath) {
|
||||||
|
if ($type === $plugintype) {
|
||||||
|
$plugintypepath = $fullpath;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (is_null($plugintypepath)) {
|
||||||
|
throw new coding_exception('Unknown plugin type!');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_dir($plugintypepath)) {
|
||||||
|
throw new coding_exception('Plugin type location does not exist!');
|
||||||
|
}
|
||||||
|
|
||||||
|
return is_writable($plugintypepath);
|
||||||
|
}
|
||||||
|
|
||||||
//// End of external API ///////////////////////////////////////////////////
|
//// End of external API ///////////////////////////////////////////////////
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -44,10 +44,15 @@ class tool_installaddon_installfromzip extends moodleform {
|
||||||
$installer = $this->_customdata['installer'];
|
$installer = $this->_customdata['installer'];
|
||||||
|
|
||||||
$options = $installer->get_plugin_types_menu();
|
$options = $installer->get_plugin_types_menu();
|
||||||
$mform->addElement('select', 'plugintype', get_string('installfromziptype', 'tool_installaddon'), $options);
|
$mform->addElement('select', 'plugintype', get_string('installfromziptype', 'tool_installaddon'), $options,
|
||||||
|
array('id' => 'tool_installaddon_installfromzip_plugintype'));
|
||||||
$mform->addHelpButton('plugintype', 'installfromziptype', 'tool_installaddon');
|
$mform->addHelpButton('plugintype', 'installfromziptype', 'tool_installaddon');
|
||||||
$mform->addRule('plugintype', null, 'required', null, 'client');
|
$mform->addRule('plugintype', null, 'required', null, 'client');
|
||||||
|
|
||||||
|
$mform->addElement('static', 'permcheck', '',
|
||||||
|
html_writer::span(get_string('permcheck', 'tool_installaddon'), '',
|
||||||
|
array('id' => 'tool_installaddon_installfromzip_permcheck')));
|
||||||
|
|
||||||
$mform->addElement('filepicker', 'zipfile', get_string('installfromzipfile', 'tool_installaddon'),
|
$mform->addElement('filepicker', 'zipfile', get_string('installfromzipfile', 'tool_installaddon'),
|
||||||
null, array('accepted_types' => '.zip'));
|
null, array('accepted_types' => '.zip'));
|
||||||
$mform->addHelpButton('zipfile', 'installfromzipfile', 'tool_installaddon');
|
$mform->addHelpButton('zipfile', 'installfromzipfile', 'tool_installaddon');
|
||||||
|
@ -69,8 +74,15 @@ class tool_installaddon_installfromzip extends moodleform {
|
||||||
*/
|
*/
|
||||||
public function validation($data, $files) {
|
public function validation($data, $files) {
|
||||||
|
|
||||||
|
$installer = $this->_customdata['installer'];
|
||||||
$errors = parent::validation($data, $files);
|
$errors = parent::validation($data, $files);
|
||||||
|
|
||||||
|
if (!$installer->is_plugintype_writable($data['plugintype'])) {
|
||||||
|
$paths = get_plugin_types(true);
|
||||||
|
$path = $paths[$data['plugintype']];
|
||||||
|
$errors['plugintype'] = get_string('permcheckresultno', 'tool_installaddon', array('path' => $path));
|
||||||
|
}
|
||||||
|
|
||||||
return $errors;
|
return $errors;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,4 +38,9 @@ $string['installfromzipfile_help'] = 'The plugin ZIP package must contain just o
|
||||||
$string['installfromzipsubmit'] = 'Install add-on from the ZIP file';
|
$string['installfromzipsubmit'] = 'Install add-on from the ZIP file';
|
||||||
$string['installfromziptype'] = 'Plugin type';
|
$string['installfromziptype'] = 'Plugin type';
|
||||||
$string['installfromziptype_help'] = 'Choose the correct type of plugin you are about to install. The installation procedure may fail badly when incorrect plugin type is provided.';
|
$string['installfromziptype_help'] = 'Choose the correct type of plugin you are about to install. The installation procedure may fail badly when incorrect plugin type is provided.';
|
||||||
|
$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> not writable';
|
||||||
|
$string['permcheckresultyes'] = 'Plugin type location <em>{$a->path}</em> is writable';
|
||||||
$string['pluginname'] = 'Add-on installer';
|
$string['pluginname'] = 'Add-on installer';
|
||||||
|
|
79
admin/tool/installaddon/permcheck.php
Normal file
79
admin/tool/installaddon/permcheck.php
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
<?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(dirname(__FILE__) . '/../../../config.php');
|
||||||
|
require_once($CFG->libdir.'/adminlib.php');
|
||||||
|
require_once(dirname(__FILE__).'/classes/installer.php');
|
||||||
|
|
||||||
|
require_login();
|
||||||
|
|
||||||
|
if (!has_capability('moodle/site:config', context_system::instance())) {
|
||||||
|
header('HTTP/1.1 403 Forbidden');
|
||||||
|
die();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($CFG->disableonclickaddoninstall)) {
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
$plugintypepath = null;
|
||||||
|
foreach (get_plugin_types() as $type => $fullpath) {
|
||||||
|
if ($type === $plugintype) {
|
||||||
|
$plugintypepath = $fullpath;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (is_null($plugintypepath)) {
|
||||||
|
header('HTTP/1.1 400 Bad Request');
|
||||||
|
die();
|
||||||
|
}
|
||||||
|
|
||||||
|
$installer = tool_installaddon_installer::instance();
|
||||||
|
|
||||||
|
$response = array('path' => $plugintypepath);
|
||||||
|
|
||||||
|
if ($installer->is_plugintype_writable($plugintype)) {
|
||||||
|
$response['writable'] = 1;
|
||||||
|
} else {
|
||||||
|
$response['writable'] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
header('Content-Type: application/json; charset: utf-8');
|
||||||
|
echo json_encode($response);
|
|
@ -58,6 +58,12 @@ class tool_installaddon_renderer extends plugin_renderer_base {
|
||||||
*/
|
*/
|
||||||
public function index_page() {
|
public function index_page() {
|
||||||
|
|
||||||
|
$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'), 'tool_installaddon');
|
||||||
|
|
||||||
$out = $this->output->header();
|
$out = $this->output->header();
|
||||||
$out .= $this->index_page_heading();
|
$out .= $this->index_page_heading();
|
||||||
$out .= $this->index_page_repository();
|
$out .= $this->index_page_repository();
|
||||||
|
|
105
admin/tool/installaddon/yui/permcheck/permcheck.js
vendored
Normal file
105
admin/tool/installaddon/yui/permcheck/permcheck.js
vendored
Normal file
|
@ -0,0 +1,105 @@
|
||||||
|
/**
|
||||||
|
* 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', this.check_for_permission, this);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @method check_for_permission
|
||||||
|
* @param {Event} e
|
||||||
|
*/
|
||||||
|
check_for_permission : function(e) {
|
||||||
|
var plugintype = e.currentTarget.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
|
||||||
|
},
|
||||||
|
'arguments' : {
|
||||||
|
'plugintypeselector' : e.currentTarget,
|
||||||
|
'showresult' : function(msg, status) {
|
||||||
|
var resultline = Y.one('#tool_installaddon_installfromzip_permcheck');
|
||||||
|
if (resultline) {
|
||||||
|
if (status === 'success') {
|
||||||
|
resultline.setContent('<span class="success"><img src="' + M.util.image_url('i/tick_green_big') + '" /> ' +
|
||||||
|
msg + '</span>');
|
||||||
|
} else if (status === 'progress') {
|
||||||
|
resultline.setContent('<span class="progress"><img src="' + M.cfg.loadingicon + '" /> ' +
|
||||||
|
msg + '</span>');
|
||||||
|
} else {
|
||||||
|
resultline.setContent('<span class="error"><img src="' + M.util.image_url('i/cross_red_big') + '" /> ' +
|
||||||
|
msg + '</span>');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'on' : {
|
||||||
|
'start' : function(transid, args) {
|
||||||
|
args.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');
|
||||||
|
args.showresult(M.util.get_string('permcheckerror', 'tool_installaddon', response), 'error');
|
||||||
|
} else if (response.path && response.writable == 1) {
|
||||||
|
args.showresult(M.util.get_string('permcheckresultyes', 'tool_installaddon', response), 'success');
|
||||||
|
} else if (response.path && response.writable == 0) {
|
||||||
|
args.showresult(M.util.get_string('permcheckresultno', 'tool_installaddon', response), 'error');
|
||||||
|
} else {
|
||||||
|
Y.log(response, 'debug', 'moodle-tool_installaddon-permcheck');
|
||||||
|
args.showresult(M.util.get_string('permcheckerror', 'tool_installaddon', response), 'error');
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (e) {
|
||||||
|
Y.log(e, 'error', 'moodle-tool_installaddon-permcheck');
|
||||||
|
args.showresult(M.util.get_string('permcheckerror', 'tool_installaddon'), 'error');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'failure': function(transid, outcome, args) {
|
||||||
|
Y.log(outcome.statusText, 'error', 'moodle-tool_installaddon-permcheck');
|
||||||
|
args.showresult(M.util.get_string('permcheckerror', 'tool_installaddon'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @property
|
||||||
|
* @type {Object}
|
||||||
|
*/
|
||||||
|
config : null
|
||||||
|
};
|
||||||
|
|
||||||
|
}, '@VERSION@', {
|
||||||
|
requires:['node', 'event', 'io-base']
|
||||||
|
});
|
Loading…
Add table
Add a link
Reference in a new issue