2009-05-25 17:44:05 +00:00
|
|
|
<?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/>.
|
2009-01-29 21:17:52 +00:00
|
|
|
|
|
|
|
/**
|
2009-05-26 09:52:38 +00:00
|
|
|
* Various upgrade/install related functions and classes.
|
2009-01-29 21:17:52 +00:00
|
|
|
*
|
2010-07-25 13:35:05 +00:00
|
|
|
* @package core
|
2009-05-25 17:44:05 +00:00
|
|
|
* @subpackage upgrade
|
|
|
|
* @copyright 1999 onwards Martin Dougiamas (http://dougiamas.com)
|
|
|
|
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
2009-01-29 21:17:52 +00:00
|
|
|
*/
|
|
|
|
|
2010-07-25 13:35:05 +00:00
|
|
|
defined('MOODLE_INTERNAL') || die();
|
|
|
|
|
2009-05-26 05:18:52 +00:00
|
|
|
/** UPGRADE_LOG_NORMAL = 0 */
|
2009-01-29 21:17:52 +00:00
|
|
|
define('UPGRADE_LOG_NORMAL', 0);
|
2009-05-26 05:18:52 +00:00
|
|
|
/** UPGRADE_LOG_NOTICE = 1 */
|
2009-01-29 21:17:52 +00:00
|
|
|
define('UPGRADE_LOG_NOTICE', 1);
|
2009-05-26 05:18:52 +00:00
|
|
|
/** UPGRADE_LOG_ERROR = 2 */
|
2009-01-31 20:07:32 +00:00
|
|
|
define('UPGRADE_LOG_ERROR', 2);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Exception indicating unknown error during upgrade.
|
2009-05-26 05:18:52 +00:00
|
|
|
*
|
2010-09-05 20:15:41 +00:00
|
|
|
* @package core
|
2009-05-26 05:18:52 +00:00
|
|
|
* @subpackage upgrade
|
2010-09-05 20:15:41 +00:00
|
|
|
* @copyright 2009 Petr Skoda {@link http://skodak.org}
|
2009-05-26 05:18:52 +00:00
|
|
|
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
2009-01-31 20:07:32 +00:00
|
|
|
*/
|
|
|
|
class upgrade_exception extends moodle_exception {
|
2010-03-31 07:41:31 +00:00
|
|
|
function __construct($plugin, $version, $debuginfo=NULL) {
|
2009-01-31 20:07:32 +00:00
|
|
|
global $CFG;
|
|
|
|
$a = (object)array('plugin'=>$plugin, 'version'=>$version);
|
2010-03-31 07:41:31 +00:00
|
|
|
parent::__construct('upgradeerror', 'admin', "$CFG->wwwroot/$CFG->admin/index.php", $a, $debuginfo);
|
2009-01-31 20:07:32 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Exception indicating downgrade error during upgrade.
|
2009-05-26 05:18:52 +00:00
|
|
|
*
|
2010-09-05 20:15:41 +00:00
|
|
|
* @package core
|
2009-05-26 05:18:52 +00:00
|
|
|
* @subpackage upgrade
|
2010-09-05 20:15:41 +00:00
|
|
|
* @copyright 2009 Petr Skoda {@link http://skodak.org}
|
2009-05-26 05:18:52 +00:00
|
|
|
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
2009-01-31 20:07:32 +00:00
|
|
|
*/
|
|
|
|
class downgrade_exception extends moodle_exception {
|
|
|
|
function __construct($plugin, $oldversion, $newversion) {
|
|
|
|
global $CFG;
|
|
|
|
$plugin = is_null($plugin) ? 'moodle' : $plugin;
|
|
|
|
$a = (object)array('plugin'=>$plugin, 'oldversion'=>$oldversion, 'newversion'=>$newversion);
|
|
|
|
parent::__construct('cannotdowngrade', 'debug', "$CFG->wwwroot/$CFG->admin/index.php", $a);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-05-26 05:18:52 +00:00
|
|
|
/**
|
2010-09-05 20:15:41 +00:00
|
|
|
* @package core
|
2009-05-26 05:18:52 +00:00
|
|
|
* @subpackage upgrade
|
2010-09-05 20:15:41 +00:00
|
|
|
* @copyright 2009 Petr Skoda {@link http://skodak.org}
|
2009-05-26 05:18:52 +00:00
|
|
|
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
|
|
|
*/
|
2009-01-31 20:07:32 +00:00
|
|
|
class upgrade_requires_exception extends moodle_exception {
|
|
|
|
function __construct($plugin, $pluginversion, $currentmoodle, $requiremoodle) {
|
|
|
|
global $CFG;
|
2010-09-21 08:07:44 +00:00
|
|
|
$a = new stdClass();
|
2009-01-31 20:07:32 +00:00
|
|
|
$a->pluginname = $plugin;
|
|
|
|
$a->pluginversion = $pluginversion;
|
|
|
|
$a->currentmoodle = $currentmoodle;
|
2009-06-19 14:25:56 +00:00
|
|
|
$a->requiremoodle = $requiremoodle;
|
2009-01-31 20:07:32 +00:00
|
|
|
parent::__construct('pluginrequirementsnotmet', 'error', "$CFG->wwwroot/$CFG->admin/index.php", $a);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-05-26 05:18:52 +00:00
|
|
|
/**
|
2010-09-05 20:15:41 +00:00
|
|
|
* @package core
|
2009-05-26 05:18:52 +00:00
|
|
|
* @subpackage upgrade
|
2010-09-05 20:15:41 +00:00
|
|
|
* @copyright 2009 Petr Skoda {@link http://skodak.org}
|
2009-05-26 05:18:52 +00:00
|
|
|
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
|
|
|
*/
|
2009-01-31 20:07:32 +00:00
|
|
|
class plugin_defective_exception extends moodle_exception {
|
|
|
|
function __construct($plugin, $details) {
|
|
|
|
global $CFG;
|
|
|
|
parent::__construct('detectedbrokenplugin', 'error', "$CFG->wwwroot/$CFG->admin/index.php", $plugin, $details);
|
|
|
|
}
|
|
|
|
}
|
2009-01-29 21:17:52 +00:00
|
|
|
|
2013-02-23 18:16:42 +01:00
|
|
|
/**
|
2014-03-05 16:33:41 +08:00
|
|
|
* Misplaced plugin exception.
|
|
|
|
*
|
|
|
|
* Note: this should be used only from the upgrade/admin code.
|
|
|
|
*
|
2013-02-23 18:16:42 +01:00
|
|
|
* @package core
|
|
|
|
* @subpackage upgrade
|
|
|
|
* @copyright 2009 Petr Skoda {@link http://skodak.org}
|
|
|
|
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
|
|
|
*/
|
|
|
|
class plugin_misplaced_exception extends moodle_exception {
|
2014-03-05 16:33:41 +08:00
|
|
|
/**
|
|
|
|
* Constructor.
|
|
|
|
* @param string $component the component from version.php
|
|
|
|
* @param string $expected expected directory, null means calculate
|
|
|
|
* @param string $current plugin directory path
|
|
|
|
*/
|
|
|
|
public function __construct($component, $expected, $current) {
|
2013-02-23 18:16:42 +01:00
|
|
|
global $CFG;
|
2014-03-05 16:33:41 +08:00
|
|
|
if (empty($expected)) {
|
|
|
|
list($type, $plugin) = core_component::normalize_component($component);
|
|
|
|
$plugintypes = core_component::get_plugin_types();
|
|
|
|
if (isset($plugintypes[$type])) {
|
|
|
|
$expected = $plugintypes[$type] . '/' . $plugin;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (strpos($expected, '$CFG->dirroot') !== 0) {
|
|
|
|
$expected = str_replace($CFG->dirroot, '$CFG->dirroot', $expected);
|
|
|
|
}
|
|
|
|
if (strpos($current, '$CFG->dirroot') !== 0) {
|
|
|
|
$current = str_replace($CFG->dirroot, '$CFG->dirroot', $current);
|
|
|
|
}
|
2013-02-23 18:16:42 +01:00
|
|
|
$a = new stdClass();
|
|
|
|
$a->component = $component;
|
|
|
|
$a->expected = $expected;
|
|
|
|
$a->current = $current;
|
|
|
|
parent::__construct('detectedmisplacedplugin', 'core_plugin', "$CFG->wwwroot/$CFG->admin/index.php", $a);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-04-09 18:14:27 +02:00
|
|
|
/**
|
|
|
|
* Sets maximum expected time needed for upgrade task.
|
|
|
|
* Please always make sure that upgrade will not run longer!
|
|
|
|
*
|
|
|
|
* The script may be automatically aborted if upgrade times out.
|
|
|
|
*
|
|
|
|
* @category upgrade
|
|
|
|
* @param int $max_execution_time in seconds (can not be less than 60 s)
|
|
|
|
*/
|
|
|
|
function upgrade_set_timeout($max_execution_time=300) {
|
|
|
|
global $CFG;
|
|
|
|
|
|
|
|
if (!isset($CFG->upgraderunning) or $CFG->upgraderunning < time()) {
|
|
|
|
$upgraderunning = get_config(null, 'upgraderunning');
|
|
|
|
} else {
|
|
|
|
$upgraderunning = $CFG->upgraderunning;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!$upgraderunning) {
|
2012-04-26 19:23:43 +02:00
|
|
|
if (CLI_SCRIPT) {
|
|
|
|
// never stop CLI upgrades
|
|
|
|
$upgraderunning = 0;
|
|
|
|
} else {
|
|
|
|
// web upgrade not running or aborted
|
|
|
|
print_error('upgradetimedout', 'admin', "$CFG->wwwroot/$CFG->admin/");
|
|
|
|
}
|
2012-04-09 18:14:27 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if ($max_execution_time < 60) {
|
|
|
|
// protection against 0 here
|
|
|
|
$max_execution_time = 60;
|
|
|
|
}
|
|
|
|
|
|
|
|
$expected_end = time() + $max_execution_time;
|
|
|
|
|
|
|
|
if ($expected_end < $upgraderunning + 10 and $expected_end > $upgraderunning - 10) {
|
|
|
|
// no need to store new end, it is nearly the same ;-)
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2012-04-22 17:51:06 +02:00
|
|
|
if (CLI_SCRIPT) {
|
|
|
|
// there is no point in timing out of CLI scripts, admins can stop them if necessary
|
2013-10-15 13:22:19 +01:00
|
|
|
core_php_time_limit::raise();
|
2012-04-22 17:51:06 +02:00
|
|
|
} else {
|
2013-10-15 13:22:19 +01:00
|
|
|
core_php_time_limit::raise($max_execution_time);
|
2012-04-22 17:51:06 +02:00
|
|
|
}
|
2012-04-09 18:14:27 +02:00
|
|
|
set_config('upgraderunning', $expected_end); // keep upgrade locked until this time
|
|
|
|
}
|
|
|
|
|
2009-01-29 21:17:52 +00:00
|
|
|
/**
|
|
|
|
* Upgrade savepoint, marks end of each upgrade block.
|
|
|
|
* It stores new main version, resets upgrade timeout
|
|
|
|
* and abort upgrade if user cancels page loading.
|
|
|
|
*
|
|
|
|
* Please do not make large upgrade blocks with lots of operations,
|
|
|
|
* for example when adding tables keep only one table operation per block.
|
|
|
|
*
|
2012-04-01 22:48:17 +02:00
|
|
|
* @category upgrade
|
2009-01-29 21:17:52 +00:00
|
|
|
* @param bool $result false if upgrade step failed, true if completed
|
|
|
|
* @param string or float $version main version
|
|
|
|
* @param bool $allowabort allow user to abort script execution here
|
|
|
|
* @return void
|
|
|
|
*/
|
|
|
|
function upgrade_main_savepoint($result, $version, $allowabort=true) {
|
|
|
|
global $CFG;
|
|
|
|
|
2011-08-03 13:09:08 +08:00
|
|
|
//sanity check to avoid confusion with upgrade_mod_savepoint usage.
|
|
|
|
if (!is_bool($allowabort)) {
|
|
|
|
$errormessage = 'Parameter type mismatch. Are you mixing up upgrade_main_savepoint() and upgrade_mod_savepoint()?';
|
|
|
|
throw new coding_exception($errormessage);
|
|
|
|
}
|
|
|
|
|
2009-01-31 20:07:32 +00:00
|
|
|
if (!$result) {
|
2009-06-26 09:02:05 +00:00
|
|
|
throw new upgrade_exception(null, $version);
|
2009-01-31 20:07:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if ($CFG->version >= $version) {
|
|
|
|
// something really wrong is going on in main upgrade script
|
|
|
|
throw new downgrade_exception(null, $CFG->version, $version);
|
2009-01-29 21:17:52 +00:00
|
|
|
}
|
|
|
|
|
2009-01-31 20:07:32 +00:00
|
|
|
set_config('version', $version);
|
|
|
|
upgrade_log(UPGRADE_LOG_NORMAL, null, 'Upgrade savepoint reached');
|
|
|
|
|
2009-01-29 21:17:52 +00:00
|
|
|
// reset upgrade timeout to default
|
|
|
|
upgrade_set_timeout();
|
|
|
|
|
|
|
|
// this is a safe place to stop upgrades if user aborts page loading
|
|
|
|
if ($allowabort and connection_aborted()) {
|
|
|
|
die;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Module upgrade savepoint, marks end of module upgrade blocks
|
|
|
|
* It stores module version, resets upgrade timeout
|
|
|
|
* and abort upgrade if user cancels page loading.
|
|
|
|
*
|
2012-04-01 22:48:17 +02:00
|
|
|
* @category upgrade
|
2009-01-29 21:17:52 +00:00
|
|
|
* @param bool $result false if upgrade step failed, true if completed
|
|
|
|
* @param string or float $version main version
|
|
|
|
* @param string $modname name of module
|
|
|
|
* @param bool $allowabort allow user to abort script execution here
|
|
|
|
* @return void
|
|
|
|
*/
|
|
|
|
function upgrade_mod_savepoint($result, $version, $modname, $allowabort=true) {
|
|
|
|
global $DB;
|
|
|
|
|
2013-09-14 23:57:21 +02:00
|
|
|
$component = 'mod_'.$modname;
|
|
|
|
|
2009-01-31 20:07:32 +00:00
|
|
|
if (!$result) {
|
2013-09-14 23:57:21 +02:00
|
|
|
throw new upgrade_exception($component, $version);
|
2009-01-31 20:07:32 +00:00
|
|
|
}
|
|
|
|
|
2013-09-14 23:57:21 +02:00
|
|
|
$dbversion = $DB->get_field('config_plugins', 'value', array('plugin'=>$component, 'name'=>'version'));
|
|
|
|
|
2009-01-29 21:17:52 +00:00
|
|
|
if (!$module = $DB->get_record('modules', array('name'=>$modname))) {
|
|
|
|
print_error('modulenotexist', 'debug', '', $modname);
|
|
|
|
}
|
|
|
|
|
2013-09-14 23:57:21 +02:00
|
|
|
if ($dbversion >= $version) {
|
2009-01-31 20:07:32 +00:00
|
|
|
// something really wrong is going on in upgrade script
|
2013-09-14 23:57:21 +02:00
|
|
|
throw new downgrade_exception($component, $dbversion, $version);
|
2009-01-29 21:17:52 +00:00
|
|
|
}
|
2013-09-14 23:57:21 +02:00
|
|
|
set_config('version', $version, $component);
|
|
|
|
|
|
|
|
upgrade_log(UPGRADE_LOG_NORMAL, $component, 'Upgrade savepoint reached');
|
2009-01-29 21:17:52 +00:00
|
|
|
|
|
|
|
// reset upgrade timeout to default
|
|
|
|
upgrade_set_timeout();
|
|
|
|
|
|
|
|
// this is a safe place to stop upgrades if user aborts page loading
|
|
|
|
if ($allowabort and connection_aborted()) {
|
|
|
|
die;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Blocks upgrade savepoint, marks end of blocks upgrade blocks
|
|
|
|
* It stores block version, resets upgrade timeout
|
|
|
|
* and abort upgrade if user cancels page loading.
|
|
|
|
*
|
2012-04-01 22:48:17 +02:00
|
|
|
* @category upgrade
|
2009-01-29 21:17:52 +00:00
|
|
|
* @param bool $result false if upgrade step failed, true if completed
|
|
|
|
* @param string or float $version main version
|
|
|
|
* @param string $blockname name of block
|
|
|
|
* @param bool $allowabort allow user to abort script execution here
|
|
|
|
* @return void
|
|
|
|
*/
|
2009-01-31 20:07:32 +00:00
|
|
|
function upgrade_block_savepoint($result, $version, $blockname, $allowabort=true) {
|
2009-01-29 21:17:52 +00:00
|
|
|
global $DB;
|
|
|
|
|
2013-09-14 23:57:21 +02:00
|
|
|
$component = 'block_'.$blockname;
|
|
|
|
|
2009-01-31 20:07:32 +00:00
|
|
|
if (!$result) {
|
2013-09-14 23:57:21 +02:00
|
|
|
throw new upgrade_exception($component, $version);
|
2009-01-31 20:07:32 +00:00
|
|
|
}
|
|
|
|
|
2013-09-14 23:57:21 +02:00
|
|
|
$dbversion = $DB->get_field('config_plugins', 'value', array('plugin'=>$component, 'name'=>'version'));
|
|
|
|
|
2009-01-29 21:17:52 +00:00
|
|
|
if (!$block = $DB->get_record('block', array('name'=>$blockname))) {
|
|
|
|
print_error('blocknotexist', 'debug', '', $blockname);
|
|
|
|
}
|
|
|
|
|
2013-09-14 23:57:21 +02:00
|
|
|
if ($dbversion >= $version) {
|
2009-01-31 20:07:32 +00:00
|
|
|
// something really wrong is going on in upgrade script
|
2013-09-14 23:57:21 +02:00
|
|
|
throw new downgrade_exception($component, $dbversion, $version);
|
2009-01-29 21:17:52 +00:00
|
|
|
}
|
2013-09-14 23:57:21 +02:00
|
|
|
set_config('version', $version, $component);
|
|
|
|
|
|
|
|
upgrade_log(UPGRADE_LOG_NORMAL, $component, 'Upgrade savepoint reached');
|
2009-01-29 21:17:52 +00:00
|
|
|
|
|
|
|
// reset upgrade timeout to default
|
|
|
|
upgrade_set_timeout();
|
|
|
|
|
|
|
|
// this is a safe place to stop upgrades if user aborts page loading
|
|
|
|
if ($allowabort and connection_aborted()) {
|
|
|
|
die;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Plugins upgrade savepoint, marks end of blocks upgrade blocks
|
|
|
|
* It stores plugin version, resets upgrade timeout
|
|
|
|
* and abort upgrade if user cancels page loading.
|
|
|
|
*
|
2012-04-01 22:48:17 +02:00
|
|
|
* @category upgrade
|
2009-01-29 21:17:52 +00:00
|
|
|
* @param bool $result false if upgrade step failed, true if completed
|
|
|
|
* @param string or float $version main version
|
|
|
|
* @param string $type name of plugin
|
|
|
|
* @param string $dir location of plugin
|
|
|
|
* @param bool $allowabort allow user to abort script execution here
|
|
|
|
* @return void
|
|
|
|
*/
|
2009-06-19 14:25:56 +00:00
|
|
|
function upgrade_plugin_savepoint($result, $version, $type, $plugin, $allowabort=true) {
|
2013-09-14 23:57:21 +02:00
|
|
|
global $DB;
|
|
|
|
|
2009-06-19 14:25:56 +00:00
|
|
|
$component = $type.'_'.$plugin;
|
|
|
|
|
2009-01-31 20:07:32 +00:00
|
|
|
if (!$result) {
|
2009-06-19 14:25:56 +00:00
|
|
|
throw new upgrade_exception($component, $version);
|
2009-01-29 21:17:52 +00:00
|
|
|
}
|
|
|
|
|
2013-09-14 23:57:21 +02:00
|
|
|
$dbversion = $DB->get_field('config_plugins', 'value', array('plugin'=>$component, 'name'=>'version'));
|
|
|
|
|
|
|
|
if ($dbversion >= $version) {
|
2009-01-31 20:07:32 +00:00
|
|
|
// Something really wrong is going on in the upgrade script
|
2013-09-14 23:57:21 +02:00
|
|
|
throw new downgrade_exception($component, $dbversion, $version);
|
2009-01-31 20:07:32 +00:00
|
|
|
}
|
2009-06-19 14:25:56 +00:00
|
|
|
set_config('version', $version, $component);
|
2009-01-31 20:07:32 +00:00
|
|
|
upgrade_log(UPGRADE_LOG_NORMAL, $component, 'Upgrade savepoint reached');
|
|
|
|
|
2009-01-29 21:17:52 +00:00
|
|
|
// Reset upgrade timeout to default
|
|
|
|
upgrade_set_timeout();
|
|
|
|
|
|
|
|
// This is a safe place to stop upgrades if user aborts page loading
|
|
|
|
if ($allowabort and connection_aborted()) {
|
|
|
|
die;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-01-01 17:24:36 +01:00
|
|
|
/**
|
|
|
|
* Detect if there are leftovers in PHP source files.
|
|
|
|
*
|
|
|
|
* During main version upgrades administrators MUST move away
|
|
|
|
* old PHP source files and start from scratch (or better
|
|
|
|
* use git).
|
|
|
|
*
|
|
|
|
* @return bool true means borked upgrade, false means previous PHP files were properly removed
|
|
|
|
*/
|
|
|
|
function upgrade_stale_php_files_present() {
|
|
|
|
global $CFG;
|
|
|
|
|
|
|
|
$someexamplesofremovedfiles = array(
|
2016-02-19 18:09:43 +08:00
|
|
|
// Removed in 3.1.
|
2016-03-23 18:19:36 +01:00
|
|
|
'/lib/classes/log/sql_internal_reader.php',
|
|
|
|
'/lib/zend/',
|
|
|
|
'/mod/forum/pix/icon.gif',
|
|
|
|
'/tag/templates/tagname.mustache',
|
2015-08-11 10:42:08 -06:00
|
|
|
// Removed in 3.0.
|
|
|
|
'/mod/lti/grade.php',
|
2015-08-22 20:55:37 +08:00
|
|
|
'/tag/coursetagslib.php',
|
2015-05-04 12:25:58 +08:00
|
|
|
// Removed in 2.9.
|
|
|
|
'/lib/timezone.txt',
|
|
|
|
// Removed in 2.8.
|
|
|
|
'/course/delete_category_form.php',
|
2014-02-13 12:35:30 +00:00
|
|
|
// Removed in 2.7.
|
|
|
|
'/admin/tool/qeupgradehelper/version.php',
|
|
|
|
// Removed in 2.6.
|
2013-09-14 23:57:21 +02:00
|
|
|
'/admin/block.php',
|
2013-07-09 10:14:37 +02:00
|
|
|
'/admin/oacleanup.php',
|
2014-02-13 12:35:30 +00:00
|
|
|
// Removed in 2.5.
|
2013-04-07 13:05:07 +02:00
|
|
|
'/backup/lib.php',
|
|
|
|
'/backup/bb/README.txt',
|
2012-12-15 14:50:16 +01:00
|
|
|
'/lib/excel/test.php',
|
2014-02-13 12:35:30 +00:00
|
|
|
// Removed in 2.4.
|
2012-07-21 10:11:50 +02:00
|
|
|
'/admin/tool/unittest/simpletestlib.php',
|
2014-02-13 12:35:30 +00:00
|
|
|
// Removed in 2.3.
|
2012-03-16 20:03:03 +01:00
|
|
|
'/lib/minify/builder/',
|
2014-02-13 12:35:30 +00:00
|
|
|
// Removed in 2.2.
|
2012-01-01 17:24:36 +01:00
|
|
|
'/lib/yui/3.4.1pr1/',
|
2014-02-13 12:35:30 +00:00
|
|
|
// Removed in 2.2.
|
2012-01-01 17:24:36 +01:00
|
|
|
'/search/cron_php5.php',
|
|
|
|
'/course/report/log/indexlive.php',
|
|
|
|
'/admin/report/backups/index.php',
|
|
|
|
'/admin/generator.php',
|
2014-02-13 12:35:30 +00:00
|
|
|
// Removed in 2.1.
|
2012-01-01 17:24:36 +01:00
|
|
|
'/lib/yui/2.8.0r4/',
|
2014-02-13 12:35:30 +00:00
|
|
|
// Removed in 2.0.
|
2012-01-01 17:24:36 +01:00
|
|
|
'/blocks/admin/block_admin.php',
|
|
|
|
'/blocks/admin_tree/block_admin_tree.php',
|
|
|
|
);
|
|
|
|
|
|
|
|
foreach ($someexamplesofremovedfiles as $file) {
|
|
|
|
if (file_exists($CFG->dirroot.$file)) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
2009-01-29 21:17:52 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Upgrade plugins
|
|
|
|
* @param string $type The type of plugins that should be updated (e.g. 'enrol', 'qtype')
|
2009-06-19 14:25:56 +00:00
|
|
|
* return void
|
2009-01-29 21:17:52 +00:00
|
|
|
*/
|
2009-06-19 14:25:56 +00:00
|
|
|
function upgrade_plugins($type, $startcallback, $endcallback, $verbose) {
|
2009-01-29 21:17:52 +00:00
|
|
|
global $CFG, $DB;
|
|
|
|
|
|
|
|
/// special cases
|
|
|
|
if ($type === 'mod') {
|
2009-05-26 19:02:11 +00:00
|
|
|
return upgrade_plugins_modules($startcallback, $endcallback, $verbose);
|
2009-01-31 20:07:32 +00:00
|
|
|
} else if ($type === 'block') {
|
2009-05-26 19:02:11 +00:00
|
|
|
return upgrade_plugins_blocks($startcallback, $endcallback, $verbose);
|
2009-01-29 21:17:52 +00:00
|
|
|
}
|
|
|
|
|
2013-07-16 22:36:11 +02:00
|
|
|
$plugs = core_component::get_plugin_list($type);
|
2009-01-29 21:17:52 +00:00
|
|
|
|
2009-06-19 14:25:56 +00:00
|
|
|
foreach ($plugs as $plug=>$fullplug) {
|
2012-04-05 17:14:39 +01:00
|
|
|
// Reset time so that it works when installing a large number of plugins
|
2013-10-15 13:22:19 +01:00
|
|
|
core_php_time_limit::raise(600);
|
2011-09-24 15:07:27 +02:00
|
|
|
$component = clean_param($type.'_'.$plug, PARAM_COMPONENT); // standardised plugin name
|
2009-01-29 21:17:52 +00:00
|
|
|
|
2011-01-23 14:27:51 +01:00
|
|
|
// check plugin dir is valid name
|
2011-09-24 15:07:27 +02:00
|
|
|
if (empty($component)) {
|
|
|
|
throw new plugin_defective_exception($type.'_'.$plug, 'Invalid plugin directory name.');
|
2011-01-23 14:27:51 +01:00
|
|
|
}
|
|
|
|
|
2009-01-31 20:07:32 +00:00
|
|
|
if (!is_readable($fullplug.'/version.php')) {
|
|
|
|
continue;
|
2009-01-29 21:17:52 +00:00
|
|
|
}
|
|
|
|
|
2010-09-21 08:07:44 +00:00
|
|
|
$plugin = new stdClass();
|
2013-09-14 23:57:21 +02:00
|
|
|
$plugin->version = null;
|
|
|
|
$module = $plugin; // Prevent some notices when plugin placed in wrong directory.
|
2009-01-31 20:07:32 +00:00
|
|
|
require($fullplug.'/version.php'); // defines $plugin with version etc
|
2013-09-14 23:57:21 +02:00
|
|
|
unset($module);
|
2013-02-23 18:16:42 +01:00
|
|
|
|
2015-08-06 14:19:58 +02:00
|
|
|
if (empty($plugin->version)) {
|
|
|
|
throw new plugin_defective_exception($component, 'Missing $plugin->version number in version.php.');
|
2011-01-23 14:27:51 +01:00
|
|
|
}
|
|
|
|
|
2015-08-06 14:19:58 +02:00
|
|
|
if (empty($plugin->component)) {
|
|
|
|
throw new plugin_defective_exception($component, 'Missing $plugin->component declaration in version.php.');
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($plugin->component !== $component) {
|
|
|
|
throw new plugin_misplaced_exception($plugin->component, null, $fullplug);
|
2009-01-29 21:17:52 +00:00
|
|
|
}
|
|
|
|
|
2009-06-19 14:25:56 +00:00
|
|
|
$plugin->name = $plug;
|
|
|
|
$plugin->fullname = $component;
|
2009-01-31 20:07:32 +00:00
|
|
|
|
2009-01-29 21:17:52 +00:00
|
|
|
if (!empty($plugin->requires)) {
|
|
|
|
if ($plugin->requires > $CFG->version) {
|
2009-01-31 20:07:32 +00:00
|
|
|
throw new upgrade_requires_exception($component, $plugin->version, $CFG->version, $plugin->requires);
|
2010-09-05 20:36:18 +00:00
|
|
|
} else if ($plugin->requires < 2010000000) {
|
|
|
|
throw new plugin_defective_exception($component, 'Plugin is not compatible with Moodle 2.x or later.');
|
2009-01-29 21:17:52 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-08-06 19:59:16 +00:00
|
|
|
// try to recover from interrupted install.php if needed
|
|
|
|
if (file_exists($fullplug.'/db/install.php')) {
|
|
|
|
if (get_config($plugin->fullname, 'installrunning')) {
|
|
|
|
require_once($fullplug.'/db/install.php');
|
|
|
|
$recover_install_function = 'xmldb_'.$plugin->fullname.'_install_recovery';
|
|
|
|
if (function_exists($recover_install_function)) {
|
|
|
|
$startcallback($component, true, $verbose);
|
|
|
|
$recover_install_function();
|
2010-10-26 14:37:23 +00:00
|
|
|
unset_config('installrunning', $plugin->fullname);
|
2009-08-06 19:59:16 +00:00
|
|
|
update_capabilities($component);
|
2010-08-03 10:07:18 +00:00
|
|
|
log_update_descriptions($component);
|
2009-09-13 21:26:51 +00:00
|
|
|
external_update_descriptions($component);
|
2009-08-06 19:59:16 +00:00
|
|
|
events_update_definition($component);
|
2014-02-25 09:47:39 +08:00
|
|
|
\core\task\manager::reset_scheduled_tasks_for_component($component);
|
2009-08-06 19:59:16 +00:00
|
|
|
message_update_providers($component);
|
2014-07-09 13:22:36 +08:00
|
|
|
\core\message\inbound\manager::update_handlers_for_component($component);
|
2011-06-01 11:44:36 +01:00
|
|
|
if ($type === 'message') {
|
|
|
|
message_update_processors($plug);
|
|
|
|
}
|
mnet MDL-21261 large overhaul. This commit changes:
- The way that mnet rpc functions are registered. Plugins must now
create db/mnet.php which is an array, similar to services.php. This
*replaces* the old mnet_publishes() functions. version.php must be
bumped to trigger this.
- More information about each rpc-available function is stored in the
database, including the class it belongs to, the file it is found in,
and whether or not it is static. Methods that are not static must be
in a class with a constructor that takes no arguments (this can easily
be achieved with a small wrapper if necessary)
- The xmlrpc dispatcher has been rewritten to remove all the
dependencies on hardcoded information about auth,mnet,portfolio and
repository, and just use the information in the database.
- The old hardcoded hidden mnet/testclient.php has been moved to the
Admin menu under "Development" and rewritten.
- The xmlrpc introspection method profiling is now using php and zend
reflection - which is a lot nicer than the old way, which was using a
php-based php parser. This fixes some inconsistent handling of
methods without arguments that were advertising their return value as
the only method parameter. While this is a *fix*, it breaks BC
slightly - the old 1.9 broken mnet/testclient.php will now not work
properly with 2.0
- Dangerous mode is still supported, but old mod/*/rpclib.php is
now unsupported, due to the fact that any plugin can export mnet
functions with db/mnet.php. This is a slight BC break.
Still TODO:
- TEST TEST TEST
- Document the two small BC breaks in release notes
- Document the contract for db/mnet.php
2010-01-28 05:25:50 +00:00
|
|
|
upgrade_plugin_mnet_functions($component);
|
2015-10-02 23:13:44 +08:00
|
|
|
core_tag_area::reset_definitions_for_component($component);
|
2009-08-06 19:59:16 +00:00
|
|
|
$endcallback($component, true, $verbose);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2009-01-29 21:17:52 +00:00
|
|
|
|
2013-09-14 23:57:21 +02:00
|
|
|
$installedversion = $DB->get_field('config_plugins', 'value', array('name'=>'version', 'plugin'=>$component)); // No caching!
|
2009-01-31 20:07:32 +00:00
|
|
|
if (empty($installedversion)) { // new installation
|
2009-05-26 19:02:11 +00:00
|
|
|
$startcallback($component, true, $verbose);
|
2009-01-29 21:17:52 +00:00
|
|
|
|
2009-01-31 20:07:32 +00:00
|
|
|
/// Install tables if defined
|
|
|
|
if (file_exists($fullplug.'/db/install.xml')) {
|
|
|
|
$DB->get_manager()->install_from_xmldb_file($fullplug.'/db/install.xml');
|
2009-01-29 21:17:52 +00:00
|
|
|
}
|
2009-08-06 19:59:16 +00:00
|
|
|
|
|
|
|
/// store version
|
|
|
|
upgrade_plugin_savepoint(true, $plugin->version, $type, $plug, false);
|
|
|
|
|
2009-01-31 20:07:32 +00:00
|
|
|
/// execute post install file
|
|
|
|
if (file_exists($fullplug.'/db/install.php')) {
|
|
|
|
require_once($fullplug.'/db/install.php');
|
2010-10-26 14:37:23 +00:00
|
|
|
set_config('installrunning', 1, $plugin->fullname);
|
|
|
|
$post_install_function = 'xmldb_'.$plugin->fullname.'_install';
|
2009-01-31 20:07:32 +00:00
|
|
|
$post_install_function();
|
2010-10-26 14:37:23 +00:00
|
|
|
unset_config('installrunning', $plugin->fullname);
|
2009-01-31 20:07:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Install various components
|
|
|
|
update_capabilities($component);
|
2010-08-03 10:07:18 +00:00
|
|
|
log_update_descriptions($component);
|
2009-09-13 21:26:51 +00:00
|
|
|
external_update_descriptions($component);
|
2009-01-31 20:07:32 +00:00
|
|
|
events_update_definition($component);
|
2014-02-25 09:47:39 +08:00
|
|
|
\core\task\manager::reset_scheduled_tasks_for_component($component);
|
2009-01-31 20:07:32 +00:00
|
|
|
message_update_providers($component);
|
2014-07-09 13:22:36 +08:00
|
|
|
\core\message\inbound\manager::update_handlers_for_component($component);
|
2011-06-01 11:44:36 +01:00
|
|
|
if ($type === 'message') {
|
|
|
|
message_update_processors($plug);
|
|
|
|
}
|
mnet MDL-21261 large overhaul. This commit changes:
- The way that mnet rpc functions are registered. Plugins must now
create db/mnet.php which is an array, similar to services.php. This
*replaces* the old mnet_publishes() functions. version.php must be
bumped to trigger this.
- More information about each rpc-available function is stored in the
database, including the class it belongs to, the file it is found in,
and whether or not it is static. Methods that are not static must be
in a class with a constructor that takes no arguments (this can easily
be achieved with a small wrapper if necessary)
- The xmlrpc dispatcher has been rewritten to remove all the
dependencies on hardcoded information about auth,mnet,portfolio and
repository, and just use the information in the database.
- The old hardcoded hidden mnet/testclient.php has been moved to the
Admin menu under "Development" and rewritten.
- The xmlrpc introspection method profiling is now using php and zend
reflection - which is a lot nicer than the old way, which was using a
php-based php parser. This fixes some inconsistent handling of
methods without arguments that were advertising their return value as
the only method parameter. While this is a *fix*, it breaks BC
slightly - the old 1.9 broken mnet/testclient.php will now not work
properly with 2.0
- Dangerous mode is still supported, but old mod/*/rpclib.php is
now unsupported, due to the fact that any plugin can export mnet
functions with db/mnet.php. This is a slight BC break.
Still TODO:
- TEST TEST TEST
- Document the two small BC breaks in release notes
- Document the contract for db/mnet.php
2010-01-28 05:25:50 +00:00
|
|
|
upgrade_plugin_mnet_functions($component);
|
2015-10-02 23:13:44 +08:00
|
|
|
core_tag_area::reset_definitions_for_component($component);
|
2009-05-26 19:02:11 +00:00
|
|
|
$endcallback($component, true, $verbose);
|
2009-01-31 20:07:32 +00:00
|
|
|
|
|
|
|
} else if ($installedversion < $plugin->version) { // upgrade
|
|
|
|
/// Run the upgrade function for the plugin.
|
2009-05-26 19:02:11 +00:00
|
|
|
$startcallback($component, false, $verbose);
|
2009-01-31 20:07:32 +00:00
|
|
|
|
|
|
|
if (is_readable($fullplug.'/db/upgrade.php')) {
|
|
|
|
require_once($fullplug.'/db/upgrade.php'); // defines upgrading function
|
|
|
|
|
|
|
|
$newupgrade_function = 'xmldb_'.$plugin->fullname.'_upgrade';
|
|
|
|
$result = $newupgrade_function($installedversion);
|
|
|
|
} else {
|
|
|
|
$result = true;
|
|
|
|
}
|
|
|
|
|
2013-09-14 23:57:21 +02:00
|
|
|
$installedversion = $DB->get_field('config_plugins', 'value', array('name'=>'version', 'plugin'=>$component)); // No caching!
|
2009-01-31 20:07:32 +00:00
|
|
|
if ($installedversion < $plugin->version) {
|
|
|
|
// store version if not already there
|
|
|
|
upgrade_plugin_savepoint($result, $plugin->version, $type, $plug, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Upgrade various components
|
|
|
|
update_capabilities($component);
|
2010-08-03 10:07:18 +00:00
|
|
|
log_update_descriptions($component);
|
2009-09-13 21:26:51 +00:00
|
|
|
external_update_descriptions($component);
|
2009-01-31 20:07:32 +00:00
|
|
|
events_update_definition($component);
|
2014-02-25 09:47:39 +08:00
|
|
|
\core\task\manager::reset_scheduled_tasks_for_component($component);
|
2009-01-31 20:07:32 +00:00
|
|
|
message_update_providers($component);
|
2014-07-09 13:22:36 +08:00
|
|
|
\core\message\inbound\manager::update_handlers_for_component($component);
|
2011-06-01 11:44:36 +01:00
|
|
|
if ($type === 'message') {
|
2013-09-14 23:57:21 +02:00
|
|
|
// Ugly hack!
|
2011-06-01 11:44:36 +01:00
|
|
|
message_update_processors($plug);
|
|
|
|
}
|
mnet MDL-21261 large overhaul. This commit changes:
- The way that mnet rpc functions are registered. Plugins must now
create db/mnet.php which is an array, similar to services.php. This
*replaces* the old mnet_publishes() functions. version.php must be
bumped to trigger this.
- More information about each rpc-available function is stored in the
database, including the class it belongs to, the file it is found in,
and whether or not it is static. Methods that are not static must be
in a class with a constructor that takes no arguments (this can easily
be achieved with a small wrapper if necessary)
- The xmlrpc dispatcher has been rewritten to remove all the
dependencies on hardcoded information about auth,mnet,portfolio and
repository, and just use the information in the database.
- The old hardcoded hidden mnet/testclient.php has been moved to the
Admin menu under "Development" and rewritten.
- The xmlrpc introspection method profiling is now using php and zend
reflection - which is a lot nicer than the old way, which was using a
php-based php parser. This fixes some inconsistent handling of
methods without arguments that were advertising their return value as
the only method parameter. While this is a *fix*, it breaks BC
slightly - the old 1.9 broken mnet/testclient.php will now not work
properly with 2.0
- Dangerous mode is still supported, but old mod/*/rpclib.php is
now unsupported, due to the fact that any plugin can export mnet
functions with db/mnet.php. This is a slight BC break.
Still TODO:
- TEST TEST TEST
- Document the two small BC breaks in release notes
- Document the contract for db/mnet.php
2010-01-28 05:25:50 +00:00
|
|
|
upgrade_plugin_mnet_functions($component);
|
2015-10-02 23:13:44 +08:00
|
|
|
core_tag_area::reset_definitions_for_component($component);
|
2009-05-26 19:02:11 +00:00
|
|
|
$endcallback($component, false, $verbose);
|
2009-01-31 20:07:32 +00:00
|
|
|
|
|
|
|
} else if ($installedversion > $plugin->version) {
|
|
|
|
throw new downgrade_exception($component, $installedversion, $plugin->version);
|
2009-01-29 21:17:52 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Find and check all modules and load them up or upgrade them if necessary
|
2009-05-26 05:18:52 +00:00
|
|
|
*
|
|
|
|
* @global object
|
|
|
|
* @global object
|
2009-01-29 21:17:52 +00:00
|
|
|
*/
|
2009-05-26 19:02:11 +00:00
|
|
|
function upgrade_plugins_modules($startcallback, $endcallback, $verbose) {
|
2009-01-29 21:17:52 +00:00
|
|
|
global $CFG, $DB;
|
|
|
|
|
2013-07-16 22:36:11 +02:00
|
|
|
$mods = core_component::get_plugin_list('mod');
|
2009-01-29 21:17:52 +00:00
|
|
|
|
2009-06-19 14:25:56 +00:00
|
|
|
foreach ($mods as $mod=>$fullmod) {
|
2009-01-29 21:17:52 +00:00
|
|
|
|
2011-01-23 14:27:51 +01:00
|
|
|
if ($mod === 'NEWMODULE') { // Someone has unzipped the template, ignore it
|
2009-01-29 21:17:52 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2011-09-24 15:07:27 +02:00
|
|
|
$component = clean_param('mod_'.$mod, PARAM_COMPONENT);
|
2009-01-29 21:17:52 +00:00
|
|
|
|
2011-01-23 14:27:51 +01:00
|
|
|
// check module dir is valid name
|
2011-09-24 15:07:27 +02:00
|
|
|
if (empty($component)) {
|
|
|
|
throw new plugin_defective_exception('mod_'.$mod, 'Invalid plugin directory name.');
|
2011-01-23 14:27:51 +01:00
|
|
|
}
|
|
|
|
|
2009-01-31 20:07:32 +00:00
|
|
|
if (!is_readable($fullmod.'/version.php')) {
|
|
|
|
throw new plugin_defective_exception($component, 'Missing version.php');
|
2009-01-29 21:17:52 +00:00
|
|
|
}
|
|
|
|
|
2015-08-06 12:33:56 +02:00
|
|
|
$module = new stdClass();
|
2013-09-14 23:57:21 +02:00
|
|
|
$plugin = new stdClass();
|
|
|
|
$plugin->version = null;
|
2014-01-29 01:40:30 +01:00
|
|
|
require($fullmod .'/version.php'); // Defines $plugin with version etc.
|
2015-08-06 12:33:56 +02:00
|
|
|
|
|
|
|
// Check if the legacy $module syntax is still used.
|
2015-09-02 01:20:09 +02:00
|
|
|
if (!is_object($module) or (count((array)$module) > 0)) {
|
2015-08-06 12:33:56 +02:00
|
|
|
throw new plugin_defective_exception($component, 'Unsupported $module syntax detected in version.php');
|
|
|
|
}
|
|
|
|
|
|
|
|
// Prepare the record for the {modules} table.
|
|
|
|
$module = clone($plugin);
|
2013-09-14 23:57:21 +02:00
|
|
|
unset($module->version);
|
|
|
|
unset($module->component);
|
|
|
|
unset($module->dependencies);
|
|
|
|
unset($module->release);
|
2013-02-23 18:16:42 +01:00
|
|
|
|
2015-08-06 14:19:58 +02:00
|
|
|
if (empty($plugin->version)) {
|
|
|
|
throw new plugin_defective_exception($component, 'Missing $plugin->version number in version.php.');
|
2011-01-23 14:27:51 +01:00
|
|
|
}
|
|
|
|
|
2015-08-06 14:19:58 +02:00
|
|
|
if (empty($plugin->component)) {
|
|
|
|
throw new plugin_defective_exception($component, 'Missing $plugin->component declaration in version.php.');
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($plugin->component !== $component) {
|
|
|
|
throw new plugin_misplaced_exception($plugin->component, null, $fullmod);
|
2009-01-29 21:17:52 +00:00
|
|
|
}
|
|
|
|
|
2013-09-14 23:57:21 +02:00
|
|
|
if (!empty($plugin->requires)) {
|
|
|
|
if ($plugin->requires > $CFG->version) {
|
|
|
|
throw new upgrade_requires_exception($component, $plugin->version, $CFG->version, $plugin->requires);
|
|
|
|
} else if ($plugin->requires < 2010000000) {
|
2010-09-05 20:36:18 +00:00
|
|
|
throw new plugin_defective_exception($component, 'Plugin is not compatible with Moodle 2.x or later.');
|
2009-01-29 21:17:52 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-01-11 15:42:23 +00:00
|
|
|
if (empty($module->cron)) {
|
|
|
|
$module->cron = 0;
|
|
|
|
}
|
|
|
|
|
2011-01-23 14:27:51 +01:00
|
|
|
// all modules must have en lang pack
|
|
|
|
if (!is_readable("$fullmod/lang/en/$mod.php")) {
|
|
|
|
throw new plugin_defective_exception($component, 'Missing mandatory en language pack.');
|
|
|
|
}
|
|
|
|
|
2009-01-29 21:17:52 +00:00
|
|
|
$module->name = $mod; // The name MUST match the directory
|
|
|
|
|
2013-09-14 23:57:21 +02:00
|
|
|
$installedversion = $DB->get_field('config_plugins', 'value', array('name'=>'version', 'plugin'=>$component)); // No caching!
|
2009-01-29 21:17:52 +00:00
|
|
|
|
2009-08-06 19:59:16 +00:00
|
|
|
if (file_exists($fullmod.'/db/install.php')) {
|
|
|
|
if (get_config($module->name, 'installrunning')) {
|
|
|
|
require_once($fullmod.'/db/install.php');
|
|
|
|
$recover_install_function = 'xmldb_'.$module->name.'_install_recovery';
|
|
|
|
if (function_exists($recover_install_function)) {
|
|
|
|
$startcallback($component, true, $verbose);
|
|
|
|
$recover_install_function();
|
|
|
|
unset_config('installrunning', $module->name);
|
|
|
|
// Install various components too
|
|
|
|
update_capabilities($component);
|
2010-08-03 10:07:18 +00:00
|
|
|
log_update_descriptions($component);
|
2009-09-13 21:26:51 +00:00
|
|
|
external_update_descriptions($component);
|
2009-08-06 19:59:16 +00:00
|
|
|
events_update_definition($component);
|
2014-02-25 09:47:39 +08:00
|
|
|
\core\task\manager::reset_scheduled_tasks_for_component($component);
|
2009-08-06 19:59:16 +00:00
|
|
|
message_update_providers($component);
|
2014-07-09 13:22:36 +08:00
|
|
|
\core\message\inbound\manager::update_handlers_for_component($component);
|
mnet MDL-21261 large overhaul. This commit changes:
- The way that mnet rpc functions are registered. Plugins must now
create db/mnet.php which is an array, similar to services.php. This
*replaces* the old mnet_publishes() functions. version.php must be
bumped to trigger this.
- More information about each rpc-available function is stored in the
database, including the class it belongs to, the file it is found in,
and whether or not it is static. Methods that are not static must be
in a class with a constructor that takes no arguments (this can easily
be achieved with a small wrapper if necessary)
- The xmlrpc dispatcher has been rewritten to remove all the
dependencies on hardcoded information about auth,mnet,portfolio and
repository, and just use the information in the database.
- The old hardcoded hidden mnet/testclient.php has been moved to the
Admin menu under "Development" and rewritten.
- The xmlrpc introspection method profiling is now using php and zend
reflection - which is a lot nicer than the old way, which was using a
php-based php parser. This fixes some inconsistent handling of
methods without arguments that were advertising their return value as
the only method parameter. While this is a *fix*, it breaks BC
slightly - the old 1.9 broken mnet/testclient.php will now not work
properly with 2.0
- Dangerous mode is still supported, but old mod/*/rpclib.php is
now unsupported, due to the fact that any plugin can export mnet
functions with db/mnet.php. This is a slight BC break.
Still TODO:
- TEST TEST TEST
- Document the two small BC breaks in release notes
- Document the contract for db/mnet.php
2010-01-28 05:25:50 +00:00
|
|
|
upgrade_plugin_mnet_functions($component);
|
2015-10-02 23:13:44 +08:00
|
|
|
core_tag_area::reset_definitions_for_component($component);
|
2009-08-06 19:59:16 +00:00
|
|
|
$endcallback($component, true, $verbose);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-09-14 23:57:21 +02:00
|
|
|
if (empty($installedversion)) {
|
2009-05-26 19:02:11 +00:00
|
|
|
$startcallback($component, true, $verbose);
|
2009-01-29 21:17:52 +00:00
|
|
|
|
2009-01-31 20:07:32 +00:00
|
|
|
/// Execute install.xml (XMLDB) - must be present in all modules
|
|
|
|
$DB->get_manager()->install_from_xmldb_file($fullmod.'/db/install.xml');
|
2009-01-29 21:17:52 +00:00
|
|
|
|
2009-07-03 13:35:36 +00:00
|
|
|
/// Add record into modules table - may be needed in install.php already
|
|
|
|
$module->id = $DB->insert_record('modules', $module);
|
2013-09-14 23:57:21 +02:00
|
|
|
upgrade_mod_savepoint(true, $plugin->version, $module->name, false);
|
2009-07-03 13:35:36 +00:00
|
|
|
|
2009-01-29 21:17:52 +00:00
|
|
|
/// Post installation hook - optional
|
|
|
|
if (file_exists("$fullmod/db/install.php")) {
|
|
|
|
require_once("$fullmod/db/install.php");
|
2009-08-06 19:59:16 +00:00
|
|
|
// Set installation running flag, we need to recover after exception or error
|
|
|
|
set_config('installrunning', 1, $module->name);
|
2012-01-11 14:04:09 +00:00
|
|
|
$post_install_function = 'xmldb_'.$module->name.'_install';
|
2009-01-29 21:17:52 +00:00
|
|
|
$post_install_function();
|
2009-08-06 19:59:16 +00:00
|
|
|
unset_config('installrunning', $module->name);
|
2009-01-29 21:17:52 +00:00
|
|
|
}
|
|
|
|
|
2009-01-31 20:07:32 +00:00
|
|
|
/// Install various components
|
|
|
|
update_capabilities($component);
|
2010-08-03 10:07:18 +00:00
|
|
|
log_update_descriptions($component);
|
2009-09-13 21:26:51 +00:00
|
|
|
external_update_descriptions($component);
|
2009-01-31 20:07:32 +00:00
|
|
|
events_update_definition($component);
|
2014-02-25 09:47:39 +08:00
|
|
|
\core\task\manager::reset_scheduled_tasks_for_component($component);
|
2009-01-31 20:07:32 +00:00
|
|
|
message_update_providers($component);
|
2014-07-09 13:22:36 +08:00
|
|
|
\core\message\inbound\manager::update_handlers_for_component($component);
|
mnet MDL-21261 large overhaul. This commit changes:
- The way that mnet rpc functions are registered. Plugins must now
create db/mnet.php which is an array, similar to services.php. This
*replaces* the old mnet_publishes() functions. version.php must be
bumped to trigger this.
- More information about each rpc-available function is stored in the
database, including the class it belongs to, the file it is found in,
and whether or not it is static. Methods that are not static must be
in a class with a constructor that takes no arguments (this can easily
be achieved with a small wrapper if necessary)
- The xmlrpc dispatcher has been rewritten to remove all the
dependencies on hardcoded information about auth,mnet,portfolio and
repository, and just use the information in the database.
- The old hardcoded hidden mnet/testclient.php has been moved to the
Admin menu under "Development" and rewritten.
- The xmlrpc introspection method profiling is now using php and zend
reflection - which is a lot nicer than the old way, which was using a
php-based php parser. This fixes some inconsistent handling of
methods without arguments that were advertising their return value as
the only method parameter. While this is a *fix*, it breaks BC
slightly - the old 1.9 broken mnet/testclient.php will now not work
properly with 2.0
- Dangerous mode is still supported, but old mod/*/rpclib.php is
now unsupported, due to the fact that any plugin can export mnet
functions with db/mnet.php. This is a slight BC break.
Still TODO:
- TEST TEST TEST
- Document the two small BC breaks in release notes
- Document the contract for db/mnet.php
2010-01-28 05:25:50 +00:00
|
|
|
upgrade_plugin_mnet_functions($component);
|
2015-10-02 23:13:44 +08:00
|
|
|
core_tag_area::reset_definitions_for_component($component);
|
2009-01-31 20:07:32 +00:00
|
|
|
|
2009-05-26 19:02:11 +00:00
|
|
|
$endcallback($component, true, $verbose);
|
2009-01-29 21:17:52 +00:00
|
|
|
|
2013-09-14 23:57:21 +02:00
|
|
|
} else if ($installedversion < $plugin->version) {
|
2009-01-31 20:07:32 +00:00
|
|
|
/// If versions say that we need to upgrade but no upgrade files are available, notify and continue
|
2009-05-26 19:02:11 +00:00
|
|
|
$startcallback($component, false, $verbose);
|
2009-01-31 20:07:32 +00:00
|
|
|
|
|
|
|
if (is_readable($fullmod.'/db/upgrade.php')) {
|
|
|
|
require_once($fullmod.'/db/upgrade.php'); // defines new upgrading function
|
|
|
|
$newupgrade_function = 'xmldb_'.$module->name.'_upgrade';
|
2013-09-14 23:57:21 +02:00
|
|
|
$result = $newupgrade_function($installedversion, $module);
|
2009-01-31 20:07:32 +00:00
|
|
|
} else {
|
|
|
|
$result = true;
|
|
|
|
}
|
|
|
|
|
2013-09-14 23:57:21 +02:00
|
|
|
$installedversion = $DB->get_field('config_plugins', 'value', array('name'=>'version', 'plugin'=>$component)); // No caching!
|
2009-01-31 20:07:32 +00:00
|
|
|
$currmodule = $DB->get_record('modules', array('name'=>$module->name));
|
2013-09-14 23:57:21 +02:00
|
|
|
if ($installedversion < $plugin->version) {
|
2009-01-31 20:07:32 +00:00
|
|
|
// store version if not already there
|
2013-09-14 23:57:21 +02:00
|
|
|
upgrade_mod_savepoint($result, $plugin->version, $mod, false);
|
2009-01-31 20:07:32 +00:00
|
|
|
}
|
|
|
|
|
2012-01-11 14:04:09 +00:00
|
|
|
// update cron flag if needed
|
|
|
|
if ($currmodule->cron != $module->cron) {
|
|
|
|
$DB->set_field('modules', 'cron', $module->cron, array('name' => $module->name));
|
|
|
|
}
|
|
|
|
|
|
|
|
// Upgrade various components
|
2009-01-31 20:07:32 +00:00
|
|
|
update_capabilities($component);
|
2010-08-03 10:07:18 +00:00
|
|
|
log_update_descriptions($component);
|
2009-09-13 21:26:51 +00:00
|
|
|
external_update_descriptions($component);
|
2009-01-31 20:07:32 +00:00
|
|
|
events_update_definition($component);
|
2014-02-25 09:47:39 +08:00
|
|
|
\core\task\manager::reset_scheduled_tasks_for_component($component);
|
2009-01-31 20:07:32 +00:00
|
|
|
message_update_providers($component);
|
2014-07-09 13:22:36 +08:00
|
|
|
\core\message\inbound\manager::update_handlers_for_component($component);
|
mnet MDL-21261 large overhaul. This commit changes:
- The way that mnet rpc functions are registered. Plugins must now
create db/mnet.php which is an array, similar to services.php. This
*replaces* the old mnet_publishes() functions. version.php must be
bumped to trigger this.
- More information about each rpc-available function is stored in the
database, including the class it belongs to, the file it is found in,
and whether or not it is static. Methods that are not static must be
in a class with a constructor that takes no arguments (this can easily
be achieved with a small wrapper if necessary)
- The xmlrpc dispatcher has been rewritten to remove all the
dependencies on hardcoded information about auth,mnet,portfolio and
repository, and just use the information in the database.
- The old hardcoded hidden mnet/testclient.php has been moved to the
Admin menu under "Development" and rewritten.
- The xmlrpc introspection method profiling is now using php and zend
reflection - which is a lot nicer than the old way, which was using a
php-based php parser. This fixes some inconsistent handling of
methods without arguments that were advertising their return value as
the only method parameter. While this is a *fix*, it breaks BC
slightly - the old 1.9 broken mnet/testclient.php will now not work
properly with 2.0
- Dangerous mode is still supported, but old mod/*/rpclib.php is
now unsupported, due to the fact that any plugin can export mnet
functions with db/mnet.php. This is a slight BC break.
Still TODO:
- TEST TEST TEST
- Document the two small BC breaks in release notes
- Document the contract for db/mnet.php
2010-01-28 05:25:50 +00:00
|
|
|
upgrade_plugin_mnet_functions($component);
|
2015-10-02 23:13:44 +08:00
|
|
|
core_tag_area::reset_definitions_for_component($component);
|
2009-01-31 20:07:32 +00:00
|
|
|
|
2009-05-26 19:02:11 +00:00
|
|
|
$endcallback($component, false, $verbose);
|
2009-01-31 20:07:32 +00:00
|
|
|
|
2013-09-14 23:57:21 +02:00
|
|
|
} else if ($installedversion > $plugin->version) {
|
|
|
|
throw new downgrade_exception($component, $installedversion, $plugin->version);
|
2009-01-31 20:07:32 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2009-01-29 21:17:52 +00:00
|
|
|
|
|
|
|
|
2009-01-31 20:07:32 +00:00
|
|
|
/**
|
|
|
|
* This function finds all available blocks and install them
|
|
|
|
* into blocks table or do all the upgrade process if newer.
|
2009-05-26 05:18:52 +00:00
|
|
|
*
|
|
|
|
* @global object
|
|
|
|
* @global object
|
2009-01-31 20:07:32 +00:00
|
|
|
*/
|
2009-05-26 19:02:11 +00:00
|
|
|
function upgrade_plugins_blocks($startcallback, $endcallback, $verbose) {
|
2009-01-31 20:07:32 +00:00
|
|
|
global $CFG, $DB;
|
|
|
|
|
|
|
|
require_once($CFG->dirroot.'/blocks/moodleblock.class.php');
|
|
|
|
|
|
|
|
$blocktitles = array(); // we do not want duplicate titles
|
|
|
|
|
|
|
|
//Is this a first install
|
|
|
|
$first_install = null;
|
|
|
|
|
2013-07-16 22:36:11 +02:00
|
|
|
$blocks = core_component::get_plugin_list('block');
|
2009-01-31 20:07:32 +00:00
|
|
|
|
2009-06-19 14:25:56 +00:00
|
|
|
foreach ($blocks as $blockname=>$fullblock) {
|
2009-01-31 20:07:32 +00:00
|
|
|
|
|
|
|
if (is_null($first_install)) {
|
2010-04-06 19:52:45 +00:00
|
|
|
$first_install = ($DB->count_records('block_instances') == 0);
|
2009-01-31 20:07:32 +00:00
|
|
|
}
|
|
|
|
|
2011-09-24 15:07:27 +02:00
|
|
|
if ($blockname === 'NEWBLOCK') { // Someone has unzipped the template, ignore it
|
2009-01-31 20:07:32 +00:00
|
|
|
continue;
|
2009-01-29 21:17:52 +00:00
|
|
|
}
|
|
|
|
|
2011-09-24 15:07:27 +02:00
|
|
|
$component = clean_param('block_'.$blockname, PARAM_COMPONENT);
|
2009-01-29 21:17:52 +00:00
|
|
|
|
2011-01-23 14:27:51 +01:00
|
|
|
// check block dir is valid name
|
2011-09-24 15:07:27 +02:00
|
|
|
if (empty($component)) {
|
|
|
|
throw new plugin_defective_exception('block_'.$blockname, 'Invalid plugin directory name.');
|
2011-01-23 14:27:51 +01:00
|
|
|
}
|
|
|
|
|
2010-07-04 12:18:22 +00:00
|
|
|
if (!is_readable($fullblock.'/version.php')) {
|
|
|
|
throw new plugin_defective_exception('block/'.$blockname, 'Missing version.php file.');
|
|
|
|
}
|
2010-09-21 08:07:44 +00:00
|
|
|
$plugin = new stdClass();
|
2013-09-14 23:57:21 +02:00
|
|
|
$plugin->version = null;
|
2010-07-04 12:18:22 +00:00
|
|
|
$plugin->cron = 0;
|
2013-09-14 23:57:21 +02:00
|
|
|
$module = $plugin; // Prevent some notices when module placed in wrong directory.
|
2010-07-04 12:18:22 +00:00
|
|
|
include($fullblock.'/version.php');
|
2013-09-14 23:57:21 +02:00
|
|
|
unset($module);
|
|
|
|
$block = clone($plugin);
|
|
|
|
unset($block->version);
|
|
|
|
unset($block->component);
|
|
|
|
unset($block->dependencies);
|
|
|
|
unset($block->release);
|
2010-07-04 12:18:22 +00:00
|
|
|
|
2015-08-06 14:19:58 +02:00
|
|
|
if (empty($plugin->version)) {
|
|
|
|
throw new plugin_defective_exception($component, 'Missing block version number in version.php.');
|
2011-01-23 14:27:51 +01:00
|
|
|
}
|
|
|
|
|
2015-08-06 14:19:58 +02:00
|
|
|
if (empty($plugin->component)) {
|
|
|
|
throw new plugin_defective_exception($component, 'Missing $plugin->component declaration in version.php.');
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($plugin->component !== $component) {
|
|
|
|
throw new plugin_misplaced_exception($plugin->component, null, $fullblock);
|
2013-09-14 23:57:21 +02:00
|
|
|
}
|
|
|
|
|
2010-09-05 20:36:18 +00:00
|
|
|
if (!empty($plugin->requires)) {
|
|
|
|
if ($plugin->requires > $CFG->version) {
|
|
|
|
throw new upgrade_requires_exception($component, $plugin->version, $CFG->version, $plugin->requires);
|
|
|
|
} else if ($plugin->requires < 2010000000) {
|
|
|
|
throw new plugin_defective_exception($component, 'Plugin is not compatible with Moodle 2.x or later.');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-01-31 20:07:32 +00:00
|
|
|
if (!is_readable($fullblock.'/block_'.$blockname.'.php')) {
|
|
|
|
throw new plugin_defective_exception('block/'.$blockname, 'Missing main block class file.');
|
2009-01-29 21:17:52 +00:00
|
|
|
}
|
2010-07-04 12:18:22 +00:00
|
|
|
include_once($fullblock.'/block_'.$blockname.'.php');
|
2009-01-29 21:17:52 +00:00
|
|
|
|
2009-01-31 20:07:32 +00:00
|
|
|
$classname = 'block_'.$blockname;
|
|
|
|
|
|
|
|
if (!class_exists($classname)) {
|
|
|
|
throw new plugin_defective_exception($component, 'Can not load main class.');
|
|
|
|
}
|
|
|
|
|
2010-05-22 20:24:28 +00:00
|
|
|
$blockobj = new $classname; // This is what we'll be testing
|
2009-01-31 20:07:32 +00:00
|
|
|
$blocktitle = $blockobj->get_title();
|
|
|
|
|
|
|
|
// OK, it's as we all hoped. For further tests, the object will do them itself.
|
|
|
|
if (!$blockobj->_self_test()) {
|
|
|
|
throw new plugin_defective_exception($component, 'Self test failed.');
|
|
|
|
}
|
|
|
|
|
|
|
|
$block->name = $blockname; // The name MUST match the directory
|
|
|
|
|
2013-09-14 23:57:21 +02:00
|
|
|
$installedversion = $DB->get_field('config_plugins', 'value', array('name'=>'version', 'plugin'=>$component)); // No caching!
|
2009-01-31 20:07:32 +00:00
|
|
|
|
2009-08-06 19:59:16 +00:00
|
|
|
if (file_exists($fullblock.'/db/install.php')) {
|
|
|
|
if (get_config('block_'.$blockname, 'installrunning')) {
|
|
|
|
require_once($fullblock.'/db/install.php');
|
|
|
|
$recover_install_function = 'xmldb_block_'.$blockname.'_install_recovery';
|
|
|
|
if (function_exists($recover_install_function)) {
|
|
|
|
$startcallback($component, true, $verbose);
|
|
|
|
$recover_install_function();
|
|
|
|
unset_config('installrunning', 'block_'.$blockname);
|
|
|
|
// Install various components
|
|
|
|
update_capabilities($component);
|
2010-08-03 10:07:18 +00:00
|
|
|
log_update_descriptions($component);
|
2009-09-13 21:26:51 +00:00
|
|
|
external_update_descriptions($component);
|
2009-08-06 19:59:16 +00:00
|
|
|
events_update_definition($component);
|
2014-02-25 09:47:39 +08:00
|
|
|
\core\task\manager::reset_scheduled_tasks_for_component($component);
|
2009-08-06 19:59:16 +00:00
|
|
|
message_update_providers($component);
|
2014-07-09 13:22:36 +08:00
|
|
|
\core\message\inbound\manager::update_handlers_for_component($component);
|
mnet MDL-21261 large overhaul. This commit changes:
- The way that mnet rpc functions are registered. Plugins must now
create db/mnet.php which is an array, similar to services.php. This
*replaces* the old mnet_publishes() functions. version.php must be
bumped to trigger this.
- More information about each rpc-available function is stored in the
database, including the class it belongs to, the file it is found in,
and whether or not it is static. Methods that are not static must be
in a class with a constructor that takes no arguments (this can easily
be achieved with a small wrapper if necessary)
- The xmlrpc dispatcher has been rewritten to remove all the
dependencies on hardcoded information about auth,mnet,portfolio and
repository, and just use the information in the database.
- The old hardcoded hidden mnet/testclient.php has been moved to the
Admin menu under "Development" and rewritten.
- The xmlrpc introspection method profiling is now using php and zend
reflection - which is a lot nicer than the old way, which was using a
php-based php parser. This fixes some inconsistent handling of
methods without arguments that were advertising their return value as
the only method parameter. While this is a *fix*, it breaks BC
slightly - the old 1.9 broken mnet/testclient.php will now not work
properly with 2.0
- Dangerous mode is still supported, but old mod/*/rpclib.php is
now unsupported, due to the fact that any plugin can export mnet
functions with db/mnet.php. This is a slight BC break.
Still TODO:
- TEST TEST TEST
- Document the two small BC breaks in release notes
- Document the contract for db/mnet.php
2010-01-28 05:25:50 +00:00
|
|
|
upgrade_plugin_mnet_functions($component);
|
2015-10-02 23:13:44 +08:00
|
|
|
core_tag_area::reset_definitions_for_component($component);
|
2009-08-06 19:59:16 +00:00
|
|
|
$endcallback($component, true, $verbose);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-09-14 23:57:21 +02:00
|
|
|
if (empty($installedversion)) { // block not installed yet, so install it
|
2009-01-31 20:07:32 +00:00
|
|
|
$conflictblock = array_search($blocktitle, $blocktitles);
|
|
|
|
if ($conflictblock !== false) {
|
|
|
|
// Duplicate block titles are not allowed, they confuse people
|
|
|
|
// AND PHP's associative arrays ;)
|
2011-01-29 19:37:56 +01:00
|
|
|
throw new plugin_defective_exception($component, get_string('blocknameconflict', 'error', (object)array('name'=>$block->name, 'conflict'=>$conflictblock)));
|
2009-01-31 20:07:32 +00:00
|
|
|
}
|
2009-05-26 19:02:11 +00:00
|
|
|
$startcallback($component, true, $verbose);
|
2009-01-31 20:07:32 +00:00
|
|
|
|
|
|
|
if (file_exists($fullblock.'/db/install.xml')) {
|
|
|
|
$DB->get_manager()->install_from_xmldb_file($fullblock.'/db/install.xml');
|
|
|
|
}
|
|
|
|
$block->id = $DB->insert_record('block', $block);
|
2013-09-14 23:57:21 +02:00
|
|
|
upgrade_block_savepoint(true, $plugin->version, $block->name, false);
|
2009-01-31 20:07:32 +00:00
|
|
|
|
|
|
|
if (file_exists($fullblock.'/db/install.php')) {
|
|
|
|
require_once($fullblock.'/db/install.php');
|
2009-08-06 19:59:16 +00:00
|
|
|
// Set installation running flag, we need to recover after exception or error
|
|
|
|
set_config('installrunning', 1, 'block_'.$blockname);
|
2012-11-15 09:51:26 +08:00
|
|
|
$post_install_function = 'xmldb_block_'.$blockname.'_install';
|
2009-01-31 20:07:32 +00:00
|
|
|
$post_install_function();
|
2009-08-06 19:59:16 +00:00
|
|
|
unset_config('installrunning', 'block_'.$blockname);
|
2009-01-31 20:07:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
$blocktitles[$block->name] = $blocktitle;
|
|
|
|
|
|
|
|
// Install various components
|
|
|
|
update_capabilities($component);
|
2010-08-03 10:07:18 +00:00
|
|
|
log_update_descriptions($component);
|
2009-09-13 21:26:51 +00:00
|
|
|
external_update_descriptions($component);
|
2009-01-31 20:07:32 +00:00
|
|
|
events_update_definition($component);
|
2014-02-25 09:47:39 +08:00
|
|
|
\core\task\manager::reset_scheduled_tasks_for_component($component);
|
2009-01-31 20:07:32 +00:00
|
|
|
message_update_providers($component);
|
2014-07-09 13:22:36 +08:00
|
|
|
\core\message\inbound\manager::update_handlers_for_component($component);
|
2015-10-02 23:13:44 +08:00
|
|
|
core_tag_area::reset_definitions_for_component($component);
|
mnet MDL-21261 large overhaul. This commit changes:
- The way that mnet rpc functions are registered. Plugins must now
create db/mnet.php which is an array, similar to services.php. This
*replaces* the old mnet_publishes() functions. version.php must be
bumped to trigger this.
- More information about each rpc-available function is stored in the
database, including the class it belongs to, the file it is found in,
and whether or not it is static. Methods that are not static must be
in a class with a constructor that takes no arguments (this can easily
be achieved with a small wrapper if necessary)
- The xmlrpc dispatcher has been rewritten to remove all the
dependencies on hardcoded information about auth,mnet,portfolio and
repository, and just use the information in the database.
- The old hardcoded hidden mnet/testclient.php has been moved to the
Admin menu under "Development" and rewritten.
- The xmlrpc introspection method profiling is now using php and zend
reflection - which is a lot nicer than the old way, which was using a
php-based php parser. This fixes some inconsistent handling of
methods without arguments that were advertising their return value as
the only method parameter. While this is a *fix*, it breaks BC
slightly - the old 1.9 broken mnet/testclient.php will now not work
properly with 2.0
- Dangerous mode is still supported, but old mod/*/rpclib.php is
now unsupported, due to the fact that any plugin can export mnet
functions with db/mnet.php. This is a slight BC break.
Still TODO:
- TEST TEST TEST
- Document the two small BC breaks in release notes
- Document the contract for db/mnet.php
2010-01-28 05:25:50 +00:00
|
|
|
upgrade_plugin_mnet_functions($component);
|
2009-01-31 20:07:32 +00:00
|
|
|
|
2009-05-26 19:02:11 +00:00
|
|
|
$endcallback($component, true, $verbose);
|
2009-01-31 20:07:32 +00:00
|
|
|
|
2013-09-14 23:57:21 +02:00
|
|
|
} else if ($installedversion < $plugin->version) {
|
2009-05-26 19:02:11 +00:00
|
|
|
$startcallback($component, false, $verbose);
|
2009-01-31 20:07:32 +00:00
|
|
|
|
|
|
|
if (is_readable($fullblock.'/db/upgrade.php')) {
|
|
|
|
require_once($fullblock.'/db/upgrade.php'); // defines new upgrading function
|
|
|
|
$newupgrade_function = 'xmldb_block_'.$blockname.'_upgrade';
|
2013-09-14 23:57:21 +02:00
|
|
|
$result = $newupgrade_function($installedversion, $block);
|
2009-01-31 20:07:32 +00:00
|
|
|
} else {
|
|
|
|
$result = true;
|
|
|
|
}
|
|
|
|
|
2013-09-14 23:57:21 +02:00
|
|
|
$installedversion = $DB->get_field('config_plugins', 'value', array('name'=>'version', 'plugin'=>$component)); // No caching!
|
2009-01-31 20:07:32 +00:00
|
|
|
$currblock = $DB->get_record('block', array('name'=>$block->name));
|
2013-09-14 23:57:21 +02:00
|
|
|
if ($installedversion < $plugin->version) {
|
2009-01-31 20:07:32 +00:00
|
|
|
// store version if not already there
|
2013-09-14 23:57:21 +02:00
|
|
|
upgrade_block_savepoint($result, $plugin->version, $block->name, false);
|
2009-01-31 20:07:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if ($currblock->cron != $block->cron) {
|
|
|
|
// update cron flag if needed
|
2013-02-08 12:40:49 +00:00
|
|
|
$DB->set_field('block', 'cron', $block->cron, array('id' => $currblock->id));
|
2009-01-31 20:07:32 +00:00
|
|
|
}
|
|
|
|
|
2010-05-22 20:24:28 +00:00
|
|
|
// Upgrade various components
|
2009-01-31 20:07:32 +00:00
|
|
|
update_capabilities($component);
|
2010-08-03 10:07:18 +00:00
|
|
|
log_update_descriptions($component);
|
2009-09-13 21:26:51 +00:00
|
|
|
external_update_descriptions($component);
|
2009-06-19 14:25:56 +00:00
|
|
|
events_update_definition($component);
|
2014-02-25 09:47:39 +08:00
|
|
|
\core\task\manager::reset_scheduled_tasks_for_component($component);
|
2009-01-31 20:07:32 +00:00
|
|
|
message_update_providers($component);
|
2014-07-09 13:22:36 +08:00
|
|
|
\core\message\inbound\manager::update_handlers_for_component($component);
|
mnet MDL-21261 large overhaul. This commit changes:
- The way that mnet rpc functions are registered. Plugins must now
create db/mnet.php which is an array, similar to services.php. This
*replaces* the old mnet_publishes() functions. version.php must be
bumped to trigger this.
- More information about each rpc-available function is stored in the
database, including the class it belongs to, the file it is found in,
and whether or not it is static. Methods that are not static must be
in a class with a constructor that takes no arguments (this can easily
be achieved with a small wrapper if necessary)
- The xmlrpc dispatcher has been rewritten to remove all the
dependencies on hardcoded information about auth,mnet,portfolio and
repository, and just use the information in the database.
- The old hardcoded hidden mnet/testclient.php has been moved to the
Admin menu under "Development" and rewritten.
- The xmlrpc introspection method profiling is now using php and zend
reflection - which is a lot nicer than the old way, which was using a
php-based php parser. This fixes some inconsistent handling of
methods without arguments that were advertising their return value as
the only method parameter. While this is a *fix*, it breaks BC
slightly - the old 1.9 broken mnet/testclient.php will now not work
properly with 2.0
- Dangerous mode is still supported, but old mod/*/rpclib.php is
now unsupported, due to the fact that any plugin can export mnet
functions with db/mnet.php. This is a slight BC break.
Still TODO:
- TEST TEST TEST
- Document the two small BC breaks in release notes
- Document the contract for db/mnet.php
2010-01-28 05:25:50 +00:00
|
|
|
upgrade_plugin_mnet_functions($component);
|
2015-10-02 23:13:44 +08:00
|
|
|
core_tag_area::reset_definitions_for_component($component);
|
2009-01-31 20:07:32 +00:00
|
|
|
|
2009-05-26 19:02:11 +00:00
|
|
|
$endcallback($component, false, $verbose);
|
2009-01-31 20:07:32 +00:00
|
|
|
|
2013-09-14 23:57:21 +02:00
|
|
|
} else if ($installedversion > $plugin->version) {
|
|
|
|
throw new downgrade_exception($component, $installedversion, $plugin->version);
|
2009-01-31 20:07:32 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Finally, if we are in the first_install of BLOCKS setup frontpage and admin page blocks
|
|
|
|
if ($first_install) {
|
|
|
|
//Iterate over each course - there should be only site course here now
|
|
|
|
if ($courses = $DB->get_records('course')) {
|
|
|
|
foreach ($courses as $course) {
|
2009-05-07 07:05:22 +00:00
|
|
|
blocks_add_default_course_blocks($course);
|
2009-01-29 21:17:52 +00:00
|
|
|
}
|
|
|
|
}
|
2009-01-31 20:07:32 +00:00
|
|
|
|
2009-05-07 07:05:22 +00:00
|
|
|
blocks_add_default_system_blocks();
|
2009-01-31 20:07:32 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-08-03 10:07:18 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Log_display description function used during install and upgrade.
|
|
|
|
*
|
|
|
|
* @param string $component name of component (moodle, mod_assignment, etc.)
|
|
|
|
* @return void
|
|
|
|
*/
|
|
|
|
function log_update_descriptions($component) {
|
|
|
|
global $DB;
|
|
|
|
|
2013-07-16 22:42:37 +02:00
|
|
|
$defpath = core_component::get_component_directory($component).'/db/log.php';
|
2010-08-03 10:07:18 +00:00
|
|
|
|
|
|
|
if (!file_exists($defpath)) {
|
|
|
|
$DB->delete_records('log_display', array('component'=>$component));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// load new info
|
|
|
|
$logs = array();
|
|
|
|
include($defpath);
|
|
|
|
$newlogs = array();
|
|
|
|
foreach ($logs as $log) {
|
|
|
|
$newlogs[$log['module'].'-'.$log['action']] = $log; // kind of unique name
|
|
|
|
}
|
|
|
|
unset($logs);
|
|
|
|
$logs = $newlogs;
|
|
|
|
|
|
|
|
$fields = array('module', 'action', 'mtable', 'field');
|
|
|
|
// update all log fist
|
|
|
|
$dblogs = $DB->get_records('log_display', array('component'=>$component));
|
|
|
|
foreach ($dblogs as $dblog) {
|
|
|
|
$name = $dblog->module.'-'.$dblog->action;
|
|
|
|
|
|
|
|
if (empty($logs[$name])) {
|
|
|
|
$DB->delete_records('log_display', array('id'=>$dblog->id));
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
$log = $logs[$name];
|
|
|
|
unset($logs[$name]);
|
|
|
|
|
|
|
|
$update = false;
|
|
|
|
foreach ($fields as $field) {
|
|
|
|
if ($dblog->$field != $log[$field]) {
|
|
|
|
$dblog->$field = $log[$field];
|
|
|
|
$update = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ($update) {
|
|
|
|
$DB->update_record('log_display', $dblog);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
foreach ($logs as $log) {
|
|
|
|
$dblog = (object)$log;
|
|
|
|
$dblog->component = $component;
|
|
|
|
$DB->insert_record('log_display', $dblog);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-09-13 21:26:51 +00:00
|
|
|
/**
|
|
|
|
* Web service discovery function used during install and upgrade.
|
|
|
|
* @param string $component name of component (moodle, mod_assignment, etc.)
|
|
|
|
* @return void
|
|
|
|
*/
|
|
|
|
function external_update_descriptions($component) {
|
2012-04-11 14:48:14 +08:00
|
|
|
global $DB, $CFG;
|
2009-09-13 21:26:51 +00:00
|
|
|
|
2013-07-16 22:42:37 +02:00
|
|
|
$defpath = core_component::get_component_directory($component).'/db/services.php';
|
2009-09-13 21:26:51 +00:00
|
|
|
|
|
|
|
if (!file_exists($defpath)) {
|
2012-04-11 14:48:14 +08:00
|
|
|
require_once($CFG->dirroot.'/lib/externallib.php');
|
2009-09-13 21:26:51 +00:00
|
|
|
external_delete_descriptions($component);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// load new info
|
|
|
|
$functions = array();
|
|
|
|
$services = array();
|
|
|
|
include($defpath);
|
|
|
|
|
|
|
|
// update all function fist
|
|
|
|
$dbfunctions = $DB->get_records('external_functions', array('component'=>$component));
|
|
|
|
foreach ($dbfunctions as $dbfunction) {
|
|
|
|
if (empty($functions[$dbfunction->name])) {
|
|
|
|
$DB->delete_records('external_functions', array('id'=>$dbfunction->id));
|
|
|
|
// do not delete functions from external_services_functions, beacuse
|
|
|
|
// we want to notify admins when functions used in custom services disappear
|
2010-08-03 10:07:18 +00:00
|
|
|
|
|
|
|
//TODO: this looks wrong, we have to delete it eventually (skodak)
|
2009-09-13 21:26:51 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
$function = $functions[$dbfunction->name];
|
|
|
|
unset($functions[$dbfunction->name]);
|
|
|
|
$function['classpath'] = empty($function['classpath']) ? null : $function['classpath'];
|
|
|
|
|
|
|
|
$update = false;
|
|
|
|
if ($dbfunction->classname != $function['classname']) {
|
|
|
|
$dbfunction->classname = $function['classname'];
|
|
|
|
$update = true;
|
|
|
|
}
|
|
|
|
if ($dbfunction->methodname != $function['methodname']) {
|
|
|
|
$dbfunction->methodname = $function['methodname'];
|
|
|
|
$update = true;
|
|
|
|
}
|
|
|
|
if ($dbfunction->classpath != $function['classpath']) {
|
|
|
|
$dbfunction->classpath = $function['classpath'];
|
|
|
|
$update = true;
|
|
|
|
}
|
2012-09-26 15:20:18 +08:00
|
|
|
$functioncapabilities = array_key_exists('capabilities', $function)?$function['capabilities']:'';
|
2010-07-23 06:17:06 +00:00
|
|
|
if ($dbfunction->capabilities != $functioncapabilities) {
|
|
|
|
$dbfunction->capabilities = $functioncapabilities;
|
|
|
|
$update = true;
|
|
|
|
}
|
2016-03-03 09:42:27 +01:00
|
|
|
|
|
|
|
if (isset($function['services']) and is_array($function['services'])) {
|
|
|
|
sort($function['services']);
|
|
|
|
$functionservices = implode(',', $function['services']);
|
|
|
|
} else {
|
|
|
|
// Force null values in the DB.
|
|
|
|
$functionservices = null;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($dbfunction->services != $functionservices) {
|
|
|
|
// Now, we need to check if services were removed, in that case we need to remove the function from them.
|
|
|
|
$servicesremoved = array_diff(explode(",", $dbfunction->services), explode(",", $functionservices));
|
|
|
|
foreach ($servicesremoved as $removedshortname) {
|
|
|
|
if ($externalserviceid = $DB->get_field('external_services', 'id', array("shortname" => $removedshortname))) {
|
|
|
|
$DB->delete_records('external_services_functions', array('functionname' => $dbfunction->name,
|
|
|
|
'externalserviceid' => $externalserviceid));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
$dbfunction->services = $functionservices;
|
|
|
|
$update = true;
|
|
|
|
}
|
2009-09-13 21:26:51 +00:00
|
|
|
if ($update) {
|
|
|
|
$DB->update_record('external_functions', $dbfunction);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
foreach ($functions as $fname => $function) {
|
2010-09-21 08:07:44 +00:00
|
|
|
$dbfunction = new stdClass();
|
2009-09-13 21:26:51 +00:00
|
|
|
$dbfunction->name = $fname;
|
|
|
|
$dbfunction->classname = $function['classname'];
|
|
|
|
$dbfunction->methodname = $function['methodname'];
|
|
|
|
$dbfunction->classpath = empty($function['classpath']) ? null : $function['classpath'];
|
|
|
|
$dbfunction->component = $component;
|
2012-09-26 15:20:18 +08:00
|
|
|
$dbfunction->capabilities = array_key_exists('capabilities', $function)?$function['capabilities']:'';
|
2016-03-03 09:42:27 +01:00
|
|
|
|
|
|
|
if (isset($function['services']) and is_array($function['services'])) {
|
|
|
|
sort($function['services']);
|
|
|
|
$dbfunction->services = implode(',', $function['services']);
|
|
|
|
} else {
|
|
|
|
// Force null values in the DB.
|
|
|
|
$dbfunction->services = null;
|
|
|
|
}
|
|
|
|
|
2009-09-13 21:26:51 +00:00
|
|
|
$dbfunction->id = $DB->insert_record('external_functions', $dbfunction);
|
|
|
|
}
|
|
|
|
unset($functions);
|
|
|
|
|
|
|
|
// now deal with services
|
|
|
|
$dbservices = $DB->get_records('external_services', array('component'=>$component));
|
|
|
|
foreach ($dbservices as $dbservice) {
|
|
|
|
if (empty($services[$dbservice->name])) {
|
2012-04-11 14:48:14 +08:00
|
|
|
$DB->delete_records('external_tokens', array('externalserviceid'=>$dbservice->id));
|
2009-09-13 21:26:51 +00:00
|
|
|
$DB->delete_records('external_services_functions', array('externalserviceid'=>$dbservice->id));
|
|
|
|
$DB->delete_records('external_services_users', array('externalserviceid'=>$dbservice->id));
|
|
|
|
$DB->delete_records('external_services', array('id'=>$dbservice->id));
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
$service = $services[$dbservice->name];
|
|
|
|
unset($services[$dbservice->name]);
|
|
|
|
$service['enabled'] = empty($service['enabled']) ? 0 : $service['enabled'];
|
|
|
|
$service['requiredcapability'] = empty($service['requiredcapability']) ? null : $service['requiredcapability'];
|
|
|
|
$service['restrictedusers'] = !isset($service['restrictedusers']) ? 1 : $service['restrictedusers'];
|
2011-11-16 11:51:03 +08:00
|
|
|
$service['downloadfiles'] = !isset($service['downloadfiles']) ? 0 : $service['downloadfiles'];
|
2013-01-17 15:26:29 +08:00
|
|
|
$service['uploadfiles'] = !isset($service['uploadfiles']) ? 0 : $service['uploadfiles'];
|
2011-06-08 15:10:26 +08:00
|
|
|
$service['shortname'] = !isset($service['shortname']) ? null : $service['shortname'];
|
2009-09-13 21:26:51 +00:00
|
|
|
|
|
|
|
$update = false;
|
|
|
|
if ($dbservice->requiredcapability != $service['requiredcapability']) {
|
|
|
|
$dbservice->requiredcapability = $service['requiredcapability'];
|
|
|
|
$update = true;
|
|
|
|
}
|
|
|
|
if ($dbservice->restrictedusers != $service['restrictedusers']) {
|
|
|
|
$dbservice->restrictedusers = $service['restrictedusers'];
|
|
|
|
$update = true;
|
|
|
|
}
|
2011-11-16 11:51:03 +08:00
|
|
|
if ($dbservice->downloadfiles != $service['downloadfiles']) {
|
|
|
|
$dbservice->downloadfiles = $service['downloadfiles'];
|
|
|
|
$update = true;
|
|
|
|
}
|
2013-01-17 15:26:29 +08:00
|
|
|
if ($dbservice->uploadfiles != $service['uploadfiles']) {
|
|
|
|
$dbservice->uploadfiles = $service['uploadfiles'];
|
|
|
|
$update = true;
|
|
|
|
}
|
2011-06-08 15:10:26 +08:00
|
|
|
//if shortname is not a PARAM_ALPHANUMEXT, fail (tested here for service update and creation)
|
|
|
|
if (isset($service['shortname']) and
|
|
|
|
(clean_param($service['shortname'], PARAM_ALPHANUMEXT) != $service['shortname'])) {
|
|
|
|
throw new moodle_exception('installserviceshortnameerror', 'webservice', '', $service['shortname']);
|
|
|
|
}
|
|
|
|
if ($dbservice->shortname != $service['shortname']) {
|
|
|
|
//check that shortname is unique
|
|
|
|
if (isset($service['shortname'])) { //we currently accepts multiple shortname == null
|
|
|
|
$existingservice = $DB->get_record('external_services',
|
|
|
|
array('shortname' => $service['shortname']));
|
|
|
|
if (!empty($existingservice)) {
|
|
|
|
throw new moodle_exception('installexistingserviceshortnameerror', 'webservice', '', $service['shortname']);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
$dbservice->shortname = $service['shortname'];
|
|
|
|
$update = true;
|
|
|
|
}
|
2009-09-13 21:26:51 +00:00
|
|
|
if ($update) {
|
|
|
|
$DB->update_record('external_services', $dbservice);
|
|
|
|
}
|
|
|
|
|
|
|
|
$functions = $DB->get_records('external_services_functions', array('externalserviceid'=>$dbservice->id));
|
|
|
|
foreach ($functions as $function) {
|
|
|
|
$key = array_search($function->functionname, $service['functions']);
|
|
|
|
if ($key === false) {
|
|
|
|
$DB->delete_records('external_services_functions', array('id'=>$function->id));
|
|
|
|
} else {
|
|
|
|
unset($service['functions'][$key]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
foreach ($service['functions'] as $fname) {
|
2010-09-21 08:07:44 +00:00
|
|
|
$newf = new stdClass();
|
2009-09-13 21:26:51 +00:00
|
|
|
$newf->externalserviceid = $dbservice->id;
|
|
|
|
$newf->functionname = $fname;
|
|
|
|
$DB->insert_record('external_services_functions', $newf);
|
|
|
|
}
|
|
|
|
unset($functions);
|
|
|
|
}
|
|
|
|
foreach ($services as $name => $service) {
|
2011-06-08 15:10:26 +08:00
|
|
|
//check that shortname is unique
|
|
|
|
if (isset($service['shortname'])) { //we currently accepts multiple shortname == null
|
|
|
|
$existingservice = $DB->get_record('external_services',
|
|
|
|
array('shortname' => $service['shortname']));
|
|
|
|
if (!empty($existingservice)) {
|
|
|
|
throw new moodle_exception('installserviceshortnameerror', 'webservice');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-09-21 08:07:44 +00:00
|
|
|
$dbservice = new stdClass();
|
2009-09-13 21:26:51 +00:00
|
|
|
$dbservice->name = $name;
|
|
|
|
$dbservice->enabled = empty($service['enabled']) ? 0 : $service['enabled'];
|
|
|
|
$dbservice->requiredcapability = empty($service['requiredcapability']) ? null : $service['requiredcapability'];
|
|
|
|
$dbservice->restrictedusers = !isset($service['restrictedusers']) ? 1 : $service['restrictedusers'];
|
2011-11-16 11:51:03 +08:00
|
|
|
$dbservice->downloadfiles = !isset($service['downloadfiles']) ? 0 : $service['downloadfiles'];
|
2013-01-17 15:26:29 +08:00
|
|
|
$dbservice->uploadfiles = !isset($service['uploadfiles']) ? 0 : $service['uploadfiles'];
|
2011-06-08 15:10:26 +08:00
|
|
|
$dbservice->shortname = !isset($service['shortname']) ? null : $service['shortname'];
|
2009-09-13 21:26:51 +00:00
|
|
|
$dbservice->component = $component;
|
2009-11-08 22:12:36 +00:00
|
|
|
$dbservice->timecreated = time();
|
2009-09-13 21:26:51 +00:00
|
|
|
$dbservice->id = $DB->insert_record('external_services', $dbservice);
|
|
|
|
foreach ($service['functions'] as $fname) {
|
2010-09-21 08:07:44 +00:00
|
|
|
$newf = new stdClass();
|
2009-09-13 21:26:51 +00:00
|
|
|
$newf->externalserviceid = $dbservice->id;
|
|
|
|
$newf->functionname = $fname;
|
|
|
|
$DB->insert_record('external_services_functions', $newf);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-03-03 09:42:27 +01:00
|
|
|
/**
|
2016-05-03 12:42:29 +02:00
|
|
|
* Allow plugins and subsystems to add external functions to other plugins or built-in services.
|
2016-03-03 09:42:27 +01:00
|
|
|
* This function is executed just after all the plugins have been updated.
|
|
|
|
*/
|
|
|
|
function external_update_services() {
|
|
|
|
global $DB;
|
|
|
|
|
|
|
|
// Look for external functions that want to be added in existing services.
|
|
|
|
$functions = $DB->get_records_select('external_functions', 'services IS NOT NULL');
|
|
|
|
|
|
|
|
$servicescache = array();
|
|
|
|
foreach ($functions as $function) {
|
|
|
|
// Prevent edge cases.
|
|
|
|
if (empty($function->services)) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
$services = explode(',', $function->services);
|
|
|
|
|
|
|
|
foreach ($services as $serviceshortname) {
|
|
|
|
// Get the service id by shortname.
|
|
|
|
if (!empty($servicescache[$serviceshortname])) {
|
|
|
|
$serviceid = $servicescache[$serviceshortname];
|
|
|
|
} else if ($service = $DB->get_record('external_services', array('shortname' => $serviceshortname))) {
|
|
|
|
// If the component is empty, it means that is not a built-in service.
|
|
|
|
// We don't allow functions to inject themselves in services created by an user in Moodle.
|
|
|
|
if (empty($service->component)) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
$serviceid = $service->id;
|
|
|
|
$servicescache[$serviceshortname] = $serviceid;
|
|
|
|
} else {
|
|
|
|
// Service not found.
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
// Finally add the function to the service.
|
|
|
|
$newf = new stdClass();
|
|
|
|
$newf->externalserviceid = $serviceid;
|
|
|
|
$newf->functionname = $function->name;
|
|
|
|
|
|
|
|
if (!$DB->record_exists('external_services_functions', (array)$newf)) {
|
|
|
|
$DB->insert_record('external_services_functions', $newf);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-05-26 05:18:52 +00:00
|
|
|
/**
|
|
|
|
* upgrade logging functions
|
|
|
|
*/
|
2009-06-29 00:34:49 +00:00
|
|
|
function upgrade_handle_exception($ex, $plugin = null) {
|
2010-09-17 08:14:29 +00:00
|
|
|
global $CFG;
|
|
|
|
|
2009-11-01 10:00:30 +00:00
|
|
|
// rollback everything, we need to log all upgrade problems
|
|
|
|
abort_all_db_transactions();
|
|
|
|
|
2009-10-31 13:52:39 +00:00
|
|
|
$info = get_exception_info($ex);
|
|
|
|
|
|
|
|
// First log upgrade error
|
|
|
|
upgrade_log(UPGRADE_LOG_ERROR, $plugin, 'Exception: ' . get_class($ex), $info->message, $info->backtrace);
|
|
|
|
|
|
|
|
// Always turn on debugging - admins need to know what is going on
|
2013-08-10 22:46:49 +02:00
|
|
|
set_debugging(DEBUG_DEVELOPER, true);
|
2009-10-31 13:52:39 +00:00
|
|
|
|
2009-06-29 00:34:49 +00:00
|
|
|
default_exception_handler($ex, true, $plugin);
|
2009-01-29 21:17:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Adds log entry into upgrade_log table
|
|
|
|
*
|
|
|
|
* @param int $type UPGRADE_LOG_NORMAL, UPGRADE_LOG_NOTICE or UPGRADE_LOG_ERROR
|
2011-02-03 10:07:13 +01:00
|
|
|
* @param string $plugin frankenstyle component name
|
2009-01-29 21:17:52 +00:00
|
|
|
* @param string $info short description text of log entry
|
|
|
|
* @param string $details long problem description
|
|
|
|
* @param string $backtrace string used for errors only
|
|
|
|
* @return void
|
|
|
|
*/
|
|
|
|
function upgrade_log($type, $plugin, $info, $details=null, $backtrace=null) {
|
|
|
|
global $DB, $USER, $CFG;
|
|
|
|
|
2011-02-03 10:07:13 +01:00
|
|
|
if (empty($plugin)) {
|
|
|
|
$plugin = 'core';
|
|
|
|
}
|
|
|
|
|
2013-07-16 22:41:00 +02:00
|
|
|
list($plugintype, $pluginname) = core_component::normalize_component($plugin);
|
2011-02-03 10:07:13 +01:00
|
|
|
$component = is_null($pluginname) ? $plugintype : $plugintype . '_' . $pluginname;
|
2009-01-31 20:07:32 +00:00
|
|
|
|
2009-06-26 09:06:16 +00:00
|
|
|
$backtrace = format_backtrace($backtrace, true);
|
2009-01-29 21:17:52 +00:00
|
|
|
|
2011-02-03 10:07:13 +01:00
|
|
|
$currentversion = null;
|
|
|
|
$targetversion = null;
|
2009-01-29 21:17:52 +00:00
|
|
|
|
|
|
|
//first try to find out current version number
|
2011-02-03 10:07:13 +01:00
|
|
|
if ($plugintype === 'core') {
|
2009-01-29 21:17:52 +00:00
|
|
|
//main
|
2011-02-03 10:07:13 +01:00
|
|
|
$currentversion = $CFG->version;
|
2009-01-29 21:17:52 +00:00
|
|
|
|
2011-02-03 10:07:13 +01:00
|
|
|
$version = null;
|
|
|
|
include("$CFG->dirroot/version.php");
|
|
|
|
$targetversion = $version;
|
2009-01-31 20:07:32 +00:00
|
|
|
|
|
|
|
} else {
|
2011-02-03 10:07:13 +01:00
|
|
|
$pluginversion = get_config($component, 'version');
|
2009-01-31 20:07:32 +00:00
|
|
|
if (!empty($pluginversion)) {
|
2011-02-03 10:07:13 +01:00
|
|
|
$currentversion = $pluginversion;
|
|
|
|
}
|
2013-07-16 22:42:37 +02:00
|
|
|
$cd = core_component::get_component_directory($component);
|
2011-02-03 10:07:13 +01:00
|
|
|
if (file_exists("$cd/version.php")) {
|
|
|
|
$plugin = new stdClass();
|
|
|
|
$plugin->version = null;
|
2013-09-14 23:57:21 +02:00
|
|
|
$module = $plugin;
|
2011-02-03 10:07:13 +01:00
|
|
|
include("$cd/version.php");
|
|
|
|
$targetversion = $plugin->version;
|
2009-01-31 20:07:32 +00:00
|
|
|
}
|
2009-01-29 21:17:52 +00:00
|
|
|
}
|
|
|
|
|
2010-09-21 08:07:44 +00:00
|
|
|
$log = new stdClass();
|
2011-02-03 10:07:13 +01:00
|
|
|
$log->type = $type;
|
|
|
|
$log->plugin = $component;
|
|
|
|
$log->version = $currentversion;
|
|
|
|
$log->targetversion = $targetversion;
|
|
|
|
$log->info = $info;
|
|
|
|
$log->details = $details;
|
|
|
|
$log->backtrace = $backtrace;
|
|
|
|
$log->userid = $USER->id;
|
|
|
|
$log->timemodified = time();
|
2009-01-29 21:17:52 +00:00
|
|
|
try {
|
|
|
|
$DB->insert_record('upgrade_log', $log);
|
|
|
|
} catch (Exception $ignored) {
|
2009-01-31 20:07:32 +00:00
|
|
|
// possible during install or 2.0 upgrade
|
2009-01-29 21:17:52 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Marks start of upgrade, blocks any other access to site.
|
|
|
|
* The upgrade is finished at the end of script or after timeout.
|
2009-05-26 05:18:52 +00:00
|
|
|
*
|
|
|
|
* @global object
|
|
|
|
* @global object
|
|
|
|
* @global object
|
2009-01-29 21:17:52 +00:00
|
|
|
*/
|
|
|
|
function upgrade_started($preinstall=false) {
|
2009-09-03 06:59:25 +00:00
|
|
|
global $CFG, $DB, $PAGE, $OUTPUT;
|
2009-01-29 21:17:52 +00:00
|
|
|
|
|
|
|
static $started = false;
|
|
|
|
|
|
|
|
if ($preinstall) {
|
|
|
|
ignore_user_abort(true);
|
|
|
|
upgrade_setup_debug(true);
|
|
|
|
|
|
|
|
} else if ($started) {
|
|
|
|
upgrade_set_timeout(120);
|
|
|
|
|
|
|
|
} else {
|
2009-05-06 08:29:22 +00:00
|
|
|
if (!CLI_SCRIPT and !$PAGE->headerprinted) {
|
2009-01-29 21:17:52 +00:00
|
|
|
$strupgrade = get_string('upgradingversion', 'admin');
|
2009-12-16 18:00:58 +00:00
|
|
|
$PAGE->set_pagelayout('maintenance');
|
2010-01-20 18:07:49 +00:00
|
|
|
upgrade_init_javascript();
|
2009-09-03 06:59:25 +00:00
|
|
|
$PAGE->set_title($strupgrade.' - Moodle '.$CFG->target_release);
|
|
|
|
$PAGE->set_heading($strupgrade);
|
|
|
|
$PAGE->navbar->add($strupgrade);
|
|
|
|
$PAGE->set_cacheable(false);
|
|
|
|
echo $OUTPUT->header();
|
2009-01-29 21:17:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
ignore_user_abort(true);
|
2013-09-27 22:41:08 +02:00
|
|
|
core_shutdown_manager::register_function('upgrade_finished_handler');
|
2009-01-29 21:17:52 +00:00
|
|
|
upgrade_setup_debug(true);
|
|
|
|
set_config('upgraderunning', time()+300);
|
|
|
|
$started = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2010-05-22 20:24:28 +00:00
|
|
|
* Internal function - executed if upgrade interrupted.
|
2009-01-29 21:17:52 +00:00
|
|
|
*/
|
|
|
|
function upgrade_finished_handler() {
|
|
|
|
upgrade_finished();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Indicates upgrade is finished.
|
|
|
|
*
|
|
|
|
* This function may be called repeatedly.
|
2009-05-26 05:18:52 +00:00
|
|
|
*
|
|
|
|
* @global object
|
|
|
|
* @global object
|
2009-01-29 21:17:52 +00:00
|
|
|
*/
|
|
|
|
function upgrade_finished($continueurl=null) {
|
2009-08-06 14:21:34 +00:00
|
|
|
global $CFG, $DB, $OUTPUT;
|
2009-01-29 21:17:52 +00:00
|
|
|
|
|
|
|
if (!empty($CFG->upgraderunning)) {
|
|
|
|
unset_config('upgraderunning');
|
2013-05-13 10:17:04 +12:00
|
|
|
// We have to forcefully purge the caches using the writer here.
|
|
|
|
// This has to be done after we unset the config var. If someone hits the site while this is set they will
|
|
|
|
// cause the config values to propogate to the caches.
|
|
|
|
// Caches are purged after the last step in an upgrade but there is several code routines that exceute between
|
|
|
|
// then and now that leaving a window for things to fall out of sync.
|
|
|
|
cache_helper::purge_all(true);
|
2009-01-29 21:17:52 +00:00
|
|
|
upgrade_setup_debug(false);
|
|
|
|
ignore_user_abort(false);
|
|
|
|
if ($continueurl) {
|
2009-08-18 05:20:12 +00:00
|
|
|
echo $OUTPUT->continue_button($continueurl);
|
2009-08-06 14:21:34 +00:00
|
|
|
echo $OUTPUT->footer();
|
2009-01-29 21:17:52 +00:00
|
|
|
die;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-05-26 05:18:52 +00:00
|
|
|
/**
|
|
|
|
* @global object
|
|
|
|
* @global object
|
|
|
|
*/
|
2009-01-29 21:17:52 +00:00
|
|
|
function upgrade_setup_debug($starting) {
|
|
|
|
global $CFG, $DB;
|
|
|
|
|
|
|
|
static $originaldebug = null;
|
|
|
|
|
|
|
|
if ($starting) {
|
|
|
|
if ($originaldebug === null) {
|
|
|
|
$originaldebug = $DB->get_debug();
|
|
|
|
}
|
|
|
|
if (!empty($CFG->upgradeshowsql)) {
|
|
|
|
$DB->set_debug(true);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
$DB->set_debug($originaldebug);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function print_upgrade_separator() {
|
|
|
|
if (!CLI_SCRIPT) {
|
|
|
|
echo '<hr />';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-01-31 20:07:32 +00:00
|
|
|
/**
|
|
|
|
* Default start upgrade callback
|
|
|
|
* @param string $plugin
|
2010-05-22 20:24:28 +00:00
|
|
|
* @param bool $installation true if installation, false means upgrade
|
2009-01-31 20:07:32 +00:00
|
|
|
*/
|
2009-05-26 19:02:11 +00:00
|
|
|
function print_upgrade_part_start($plugin, $installation, $verbose) {
|
2009-08-06 08:19:21 +00:00
|
|
|
global $OUTPUT;
|
2009-01-31 20:07:32 +00:00
|
|
|
if (empty($plugin) or $plugin == 'moodle') {
|
|
|
|
upgrade_started($installation); // does not store upgrade running flag yet
|
2009-05-26 19:02:11 +00:00
|
|
|
if ($verbose) {
|
2009-08-06 08:19:21 +00:00
|
|
|
echo $OUTPUT->heading(get_string('coresystem'));
|
2009-05-26 19:02:11 +00:00
|
|
|
}
|
2009-01-31 20:07:32 +00:00
|
|
|
} else {
|
|
|
|
upgrade_started();
|
2009-05-26 19:02:11 +00:00
|
|
|
if ($verbose) {
|
2009-08-06 08:19:21 +00:00
|
|
|
echo $OUTPUT->heading($plugin);
|
2009-05-26 19:02:11 +00:00
|
|
|
}
|
2009-01-31 20:07:32 +00:00
|
|
|
}
|
|
|
|
if ($installation) {
|
|
|
|
if (empty($plugin) or $plugin == 'moodle') {
|
|
|
|
// no need to log - log table not yet there ;-)
|
|
|
|
} else {
|
|
|
|
upgrade_log(UPGRADE_LOG_NORMAL, $plugin, 'Starting plugin installation');
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (empty($plugin) or $plugin == 'moodle') {
|
|
|
|
upgrade_log(UPGRADE_LOG_NORMAL, $plugin, 'Starting core upgrade');
|
|
|
|
} else {
|
|
|
|
upgrade_log(UPGRADE_LOG_NORMAL, $plugin, 'Starting plugin upgrade');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Default end upgrade callback
|
|
|
|
* @param string $plugin
|
2010-05-22 20:24:28 +00:00
|
|
|
* @param bool $installation true if installation, false means upgrade
|
2009-01-31 20:07:32 +00:00
|
|
|
*/
|
2009-05-26 19:02:11 +00:00
|
|
|
function print_upgrade_part_end($plugin, $installation, $verbose) {
|
2009-08-18 05:20:12 +00:00
|
|
|
global $OUTPUT;
|
2009-01-31 20:07:32 +00:00
|
|
|
upgrade_started();
|
|
|
|
if ($installation) {
|
|
|
|
if (empty($plugin) or $plugin == 'moodle') {
|
|
|
|
upgrade_log(UPGRADE_LOG_NORMAL, $plugin, 'Core installed');
|
|
|
|
} else {
|
|
|
|
upgrade_log(UPGRADE_LOG_NORMAL, $plugin, 'Plugin installed');
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (empty($plugin) or $plugin == 'moodle') {
|
|
|
|
upgrade_log(UPGRADE_LOG_NORMAL, $plugin, 'Core upgraded');
|
|
|
|
} else {
|
|
|
|
upgrade_log(UPGRADE_LOG_NORMAL, $plugin, 'Plugin upgraded');
|
|
|
|
}
|
|
|
|
}
|
2009-05-26 19:02:11 +00:00
|
|
|
if ($verbose) {
|
2016-05-17 03:55:46 +00:00
|
|
|
$notification = new \core\output\notification(get_string('success'), \core\output\notification::NOTIFY_SUCCESS);
|
|
|
|
$notification->set_show_closebutton(false);
|
|
|
|
echo $OUTPUT->render($notification);
|
2009-05-26 19:02:11 +00:00
|
|
|
print_upgrade_separator();
|
2009-05-25 17:44:05 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-05-26 05:18:52 +00:00
|
|
|
/**
|
2010-05-22 20:24:28 +00:00
|
|
|
* Sets up JS code required for all upgrade scripts.
|
2009-05-26 05:18:52 +00:00
|
|
|
* @global object
|
|
|
|
*/
|
2010-01-20 18:07:49 +00:00
|
|
|
function upgrade_init_javascript() {
|
2009-06-26 09:38:14 +00:00
|
|
|
global $PAGE;
|
2010-01-20 18:07:49 +00:00
|
|
|
// scroll to the end of each upgrade page so that ppl see either error or continue button,
|
|
|
|
// no need to scroll continuously any more, it is enough to jump to end once the footer is printed ;-)
|
|
|
|
$js = "window.scrollTo(0, 5000000);";
|
|
|
|
$PAGE->requires->js_init_code($js);
|
2009-01-29 21:17:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Try to upgrade the given language pack (or current language)
|
2010-05-26 00:29:33 +00:00
|
|
|
*
|
2011-03-29 21:09:59 +02:00
|
|
|
* @param string $lang the code of the language to update, defaults to the current language
|
2009-01-29 21:17:52 +00:00
|
|
|
*/
|
MDL-29029 move lang pack import to admin tools
Includes lang related language pack cleanup.
AMOS BEGIN
MOV [langpacks,core_admin],[pluginname,tool_langimport]
MOV [install,core_admin],[install,tool_langimport]
MOV [installedlangs,core_admin],[installedlangs,tool_langimport]
MOV [langimport,core_admin],[langimport,tool_langimport]
MOV [langimportdisabled,core_admin],[langimportdisabled,tool_langimport]
MOV [langpackinstalled,core_admin],[langpackinstalled,tool_langimport]
MOV [langpackremoved,core_admin],[langpackremoved,tool_langimport]
MOV [langpackupdateskipped,core_admin],[langpackupdateskipped,tool_langimport]
MOV [langpackuptodate,core_admin],[langpackuptodate,tool_langimport]
MOV [langupdatecomplete,core_admin],[langupdatecomplete,tool_langimport]
MOV [missinglangparent,core_admin],[missinglangparent,tool_langimport]
MOV [nolangupdateneeded,core_admin],[nolangupdateneeded,tool_langimport]
MOV [remotelangnotavailable,core_admin],[remotelangnotavailable,tool_langimport]
MOV [uninstall,core_admin],[uninstall,tool_langimport]
MOV [uninstallconfirm,core_admin],[uninstallconfirm,tool_langimport]
MOV [updatelangs,core_admin],[updatelangs,tool_langimport]
AMOS END
2011-09-17 20:58:26 +02:00
|
|
|
function upgrade_language_pack($lang = null) {
|
|
|
|
global $CFG;
|
2009-01-29 21:17:52 +00:00
|
|
|
|
MDL-29029 move lang pack import to admin tools
Includes lang related language pack cleanup.
AMOS BEGIN
MOV [langpacks,core_admin],[pluginname,tool_langimport]
MOV [install,core_admin],[install,tool_langimport]
MOV [installedlangs,core_admin],[installedlangs,tool_langimport]
MOV [langimport,core_admin],[langimport,tool_langimport]
MOV [langimportdisabled,core_admin],[langimportdisabled,tool_langimport]
MOV [langpackinstalled,core_admin],[langpackinstalled,tool_langimport]
MOV [langpackremoved,core_admin],[langpackremoved,tool_langimport]
MOV [langpackupdateskipped,core_admin],[langpackupdateskipped,tool_langimport]
MOV [langpackuptodate,core_admin],[langpackuptodate,tool_langimport]
MOV [langupdatecomplete,core_admin],[langupdatecomplete,tool_langimport]
MOV [missinglangparent,core_admin],[missinglangparent,tool_langimport]
MOV [nolangupdateneeded,core_admin],[nolangupdateneeded,tool_langimport]
MOV [remotelangnotavailable,core_admin],[remotelangnotavailable,tool_langimport]
MOV [uninstall,core_admin],[uninstall,tool_langimport]
MOV [uninstallconfirm,core_admin],[uninstallconfirm,tool_langimport]
MOV [updatelangs,core_admin],[updatelangs,tool_langimport]
AMOS END
2011-09-17 20:58:26 +02:00
|
|
|
if (!empty($CFG->skiplangupgrade)) {
|
|
|
|
return;
|
|
|
|
}
|
2010-05-26 00:29:33 +00:00
|
|
|
|
MDL-29029 move lang pack import to admin tools
Includes lang related language pack cleanup.
AMOS BEGIN
MOV [langpacks,core_admin],[pluginname,tool_langimport]
MOV [install,core_admin],[install,tool_langimport]
MOV [installedlangs,core_admin],[installedlangs,tool_langimport]
MOV [langimport,core_admin],[langimport,tool_langimport]
MOV [langimportdisabled,core_admin],[langimportdisabled,tool_langimport]
MOV [langpackinstalled,core_admin],[langpackinstalled,tool_langimport]
MOV [langpackremoved,core_admin],[langpackremoved,tool_langimport]
MOV [langpackupdateskipped,core_admin],[langpackupdateskipped,tool_langimport]
MOV [langpackuptodate,core_admin],[langpackuptodate,tool_langimport]
MOV [langupdatecomplete,core_admin],[langupdatecomplete,tool_langimport]
MOV [missinglangparent,core_admin],[missinglangparent,tool_langimport]
MOV [nolangupdateneeded,core_admin],[nolangupdateneeded,tool_langimport]
MOV [remotelangnotavailable,core_admin],[remotelangnotavailable,tool_langimport]
MOV [uninstall,core_admin],[uninstall,tool_langimport]
MOV [uninstallconfirm,core_admin],[uninstallconfirm,tool_langimport]
MOV [updatelangs,core_admin],[updatelangs,tool_langimport]
AMOS END
2011-09-17 20:58:26 +02:00
|
|
|
if (!file_exists("$CFG->dirroot/$CFG->admin/tool/langimport/lib.php")) {
|
|
|
|
// weird, somebody uninstalled the import utility
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!$lang) {
|
2009-01-29 21:17:52 +00:00
|
|
|
$lang = current_language();
|
|
|
|
}
|
|
|
|
|
MDL-29029 move lang pack import to admin tools
Includes lang related language pack cleanup.
AMOS BEGIN
MOV [langpacks,core_admin],[pluginname,tool_langimport]
MOV [install,core_admin],[install,tool_langimport]
MOV [installedlangs,core_admin],[installedlangs,tool_langimport]
MOV [langimport,core_admin],[langimport,tool_langimport]
MOV [langimportdisabled,core_admin],[langimportdisabled,tool_langimport]
MOV [langpackinstalled,core_admin],[langpackinstalled,tool_langimport]
MOV [langpackremoved,core_admin],[langpackremoved,tool_langimport]
MOV [langpackupdateskipped,core_admin],[langpackupdateskipped,tool_langimport]
MOV [langpackuptodate,core_admin],[langpackuptodate,tool_langimport]
MOV [langupdatecomplete,core_admin],[langupdatecomplete,tool_langimport]
MOV [missinglangparent,core_admin],[missinglangparent,tool_langimport]
MOV [nolangupdateneeded,core_admin],[nolangupdateneeded,tool_langimport]
MOV [remotelangnotavailable,core_admin],[remotelangnotavailable,tool_langimport]
MOV [uninstall,core_admin],[uninstall,tool_langimport]
MOV [uninstallconfirm,core_admin],[uninstallconfirm,tool_langimport]
MOV [updatelangs,core_admin],[updatelangs,tool_langimport]
AMOS END
2011-09-17 20:58:26 +02:00
|
|
|
if (!get_string_manager()->translation_exists($lang)) {
|
|
|
|
return;
|
2009-01-29 21:17:52 +00:00
|
|
|
}
|
|
|
|
|
MDL-29029 move lang pack import to admin tools
Includes lang related language pack cleanup.
AMOS BEGIN
MOV [langpacks,core_admin],[pluginname,tool_langimport]
MOV [install,core_admin],[install,tool_langimport]
MOV [installedlangs,core_admin],[installedlangs,tool_langimport]
MOV [langimport,core_admin],[langimport,tool_langimport]
MOV [langimportdisabled,core_admin],[langimportdisabled,tool_langimport]
MOV [langpackinstalled,core_admin],[langpackinstalled,tool_langimport]
MOV [langpackremoved,core_admin],[langpackremoved,tool_langimport]
MOV [langpackupdateskipped,core_admin],[langpackupdateskipped,tool_langimport]
MOV [langpackuptodate,core_admin],[langpackuptodate,tool_langimport]
MOV [langupdatecomplete,core_admin],[langupdatecomplete,tool_langimport]
MOV [missinglangparent,core_admin],[missinglangparent,tool_langimport]
MOV [nolangupdateneeded,core_admin],[nolangupdateneeded,tool_langimport]
MOV [remotelangnotavailable,core_admin],[remotelangnotavailable,tool_langimport]
MOV [uninstall,core_admin],[uninstall,tool_langimport]
MOV [uninstallconfirm,core_admin],[uninstallconfirm,tool_langimport]
MOV [updatelangs,core_admin],[updatelangs,tool_langimport]
AMOS END
2011-09-17 20:58:26 +02:00
|
|
|
get_string_manager()->reset_caches();
|
|
|
|
|
|
|
|
if ($lang === 'en') {
|
|
|
|
return; // Nothing to do
|
2009-01-29 21:17:52 +00:00
|
|
|
}
|
2010-05-26 00:29:33 +00:00
|
|
|
|
MDL-29029 move lang pack import to admin tools
Includes lang related language pack cleanup.
AMOS BEGIN
MOV [langpacks,core_admin],[pluginname,tool_langimport]
MOV [install,core_admin],[install,tool_langimport]
MOV [installedlangs,core_admin],[installedlangs,tool_langimport]
MOV [langimport,core_admin],[langimport,tool_langimport]
MOV [langimportdisabled,core_admin],[langimportdisabled,tool_langimport]
MOV [langpackinstalled,core_admin],[langpackinstalled,tool_langimport]
MOV [langpackremoved,core_admin],[langpackremoved,tool_langimport]
MOV [langpackupdateskipped,core_admin],[langpackupdateskipped,tool_langimport]
MOV [langpackuptodate,core_admin],[langpackuptodate,tool_langimport]
MOV [langupdatecomplete,core_admin],[langupdatecomplete,tool_langimport]
MOV [missinglangparent,core_admin],[missinglangparent,tool_langimport]
MOV [nolangupdateneeded,core_admin],[nolangupdateneeded,tool_langimport]
MOV [remotelangnotavailable,core_admin],[remotelangnotavailable,tool_langimport]
MOV [uninstall,core_admin],[uninstall,tool_langimport]
MOV [uninstallconfirm,core_admin],[uninstallconfirm,tool_langimport]
MOV [updatelangs,core_admin],[updatelangs,tool_langimport]
AMOS END
2011-09-17 20:58:26 +02:00
|
|
|
upgrade_started(false);
|
|
|
|
|
|
|
|
require_once("$CFG->dirroot/$CFG->admin/tool/langimport/lib.php");
|
|
|
|
tool_langimport_preupgrade_update($lang);
|
|
|
|
|
2010-05-26 00:29:33 +00:00
|
|
|
get_string_manager()->reset_caches();
|
|
|
|
|
2009-02-08 23:14:13 +00:00
|
|
|
print_upgrade_separator();
|
2009-01-29 21:17:52 +00:00
|
|
|
}
|
2009-05-26 09:52:38 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Install core moodle tables and initialize
|
|
|
|
* @param float $version target version
|
|
|
|
* @param bool $verbose
|
|
|
|
* @return void, may throw exception
|
|
|
|
*/
|
|
|
|
function install_core($version, $verbose) {
|
|
|
|
global $CFG, $DB;
|
|
|
|
|
2013-04-27 21:54:06 +02:00
|
|
|
// We can not call purge_all_caches() yet, make sure the temp and cache dirs exist and are empty.
|
|
|
|
remove_dir($CFG->cachedir.'', true);
|
2013-07-07 21:42:03 +02:00
|
|
|
make_cache_directory('', true);
|
|
|
|
|
|
|
|
remove_dir($CFG->localcachedir.'', true);
|
|
|
|
make_localcache_directory('', true);
|
|
|
|
|
2013-04-27 21:54:06 +02:00
|
|
|
remove_dir($CFG->tempdir.'', true);
|
2013-07-07 21:42:03 +02:00
|
|
|
make_temp_directory('', true);
|
|
|
|
|
2013-04-27 21:54:06 +02:00
|
|
|
remove_dir($CFG->dataroot.'/muc', true);
|
2013-07-07 21:42:03 +02:00
|
|
|
make_writable_directory($CFG->dataroot.'/muc', true);
|
2013-04-27 21:54:06 +02:00
|
|
|
|
2009-05-26 09:52:38 +00:00
|
|
|
try {
|
2013-10-15 13:22:19 +01:00
|
|
|
core_php_time_limit::raise(600);
|
2009-05-26 19:02:11 +00:00
|
|
|
print_upgrade_part_start('moodle', true, $verbose); // does not store upgrade running flag
|
2009-05-26 09:52:38 +00:00
|
|
|
|
|
|
|
$DB->get_manager()->install_from_xmldb_file("$CFG->libdir/db/install.xml");
|
|
|
|
upgrade_started(); // we want the flag to be stored in config table ;-)
|
|
|
|
|
|
|
|
// set all core default records and default settings
|
|
|
|
require_once("$CFG->libdir/db/install.php");
|
2010-08-03 10:07:18 +00:00
|
|
|
xmldb_main_install(); // installs the capabilities too
|
2009-05-26 09:52:38 +00:00
|
|
|
|
|
|
|
// store version
|
|
|
|
upgrade_main_savepoint(true, $version, false);
|
|
|
|
|
MDL-21782 reworked enrolment framework, the core infrastructure is in place, the basic plugins are all implemented; see the tracker issue for list of unfinished bits, expect more changes and improvements during the next week
AMOS START
MOV [sendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage,enrol_self]
MOV [configsendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage_desc,enrol_self]
MOV [enrolstartdate,core],[enrolstartdate,enrol_self]
MOV [enrolenddate,core],[enrolenddate,enrol_self]
CPY [welcometocourse,core],[welcometocourse,enrol_self]
CPY [welcometocoursetext,core],[welcometocoursetext,enrol_self]
MOV [notenrollable,core],[notenrollable,core_enrol]
MOV [enrolenddaterror,core],[enrolenddaterror,enrol_self]
MOV [enrolmentkeyhint,core],[passwordinvalidhint,enrol_self]
MOV [coursemanager,core_admin],[coursecontact,core_admin]
MOV [configcoursemanager,core_admin],[coursecontact_desc,core_admin]
MOV [enrolledincourserole,core],[enrolledincourserole,enrol_manual]
MOV [enrolme,core],[enrolme,core_enrol]
MOV [unenrol,core],[unenrol,core_enrol]
MOV [unenrolme,core],[unenrolme,core_enrol]
MOV [enrolmentnew,core],[enrolmentnew,core_enrol]
MOV [enrolmentnewuser,core],[enrolmentnewuser,core_enrol]
MOV [enrolments,core],[enrolments,core_enrol]
MOV [enrolperiod,core],[enrolperiod,core_enrol]
MOV [unenrolroleusers,core],[unenrolroleusers,core_enrol]
AMOS END
2010-06-21 15:30:49 +00:00
|
|
|
// Continue with the installation
|
2010-08-03 10:07:18 +00:00
|
|
|
log_update_descriptions('moodle');
|
|
|
|
external_update_descriptions('moodle');
|
2009-05-26 09:52:38 +00:00
|
|
|
events_update_definition('moodle');
|
2014-02-25 09:47:39 +08:00
|
|
|
\core\task\manager::reset_scheduled_tasks_for_component('moodle');
|
2009-05-26 09:52:38 +00:00
|
|
|
message_update_providers('moodle');
|
2014-07-09 13:22:36 +08:00
|
|
|
\core\message\inbound\manager::update_handlers_for_component('moodle');
|
2015-10-02 23:13:44 +08:00
|
|
|
core_tag_area::reset_definitions_for_component('moodle');
|
2009-05-26 09:52:38 +00:00
|
|
|
|
MDL-21782 reworked enrolment framework, the core infrastructure is in place, the basic plugins are all implemented; see the tracker issue for list of unfinished bits, expect more changes and improvements during the next week
AMOS START
MOV [sendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage,enrol_self]
MOV [configsendcoursewelcomemessage,core_admin],[sendcoursewelcomemessage_desc,enrol_self]
MOV [enrolstartdate,core],[enrolstartdate,enrol_self]
MOV [enrolenddate,core],[enrolenddate,enrol_self]
CPY [welcometocourse,core],[welcometocourse,enrol_self]
CPY [welcometocoursetext,core],[welcometocoursetext,enrol_self]
MOV [notenrollable,core],[notenrollable,core_enrol]
MOV [enrolenddaterror,core],[enrolenddaterror,enrol_self]
MOV [enrolmentkeyhint,core],[passwordinvalidhint,enrol_self]
MOV [coursemanager,core_admin],[coursecontact,core_admin]
MOV [configcoursemanager,core_admin],[coursecontact_desc,core_admin]
MOV [enrolledincourserole,core],[enrolledincourserole,enrol_manual]
MOV [enrolme,core],[enrolme,core_enrol]
MOV [unenrol,core],[unenrol,core_enrol]
MOV [unenrolme,core],[unenrolme,core_enrol]
MOV [enrolmentnew,core],[enrolmentnew,core_enrol]
MOV [enrolmentnewuser,core],[enrolmentnewuser,core_enrol]
MOV [enrolments,core],[enrolments,core_enrol]
MOV [enrolperiod,core],[enrolperiod,core_enrol]
MOV [unenrolroleusers,core],[unenrolroleusers,core_enrol]
AMOS END
2010-06-21 15:30:49 +00:00
|
|
|
// Write default settings unconditionally
|
2009-05-26 09:52:38 +00:00
|
|
|
admin_apply_default_settings(NULL, true);
|
|
|
|
|
2009-05-26 19:02:11 +00:00
|
|
|
print_upgrade_part_end(null, true, $verbose);
|
2012-11-22 10:33:57 +13:00
|
|
|
|
2013-02-06 13:45:17 +13:00
|
|
|
// Purge all caches. They're disabled but this ensures that we don't have any persistent data just in case something
|
|
|
|
// during installation didn't use APIs.
|
|
|
|
cache_helper::purge_all();
|
2009-05-26 09:52:38 +00:00
|
|
|
} catch (exception $ex) {
|
|
|
|
upgrade_handle_exception($ex);
|
2015-12-09 11:55:58 +08:00
|
|
|
} catch (Throwable $ex) {
|
|
|
|
// Engine errors in PHP7 throw exceptions of type Throwable (this "catch" will be ignored in PHP5).
|
|
|
|
upgrade_handle_exception($ex);
|
2009-05-26 09:52:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Upgrade moodle core
|
|
|
|
* @param float $version target version
|
|
|
|
* @param bool $verbose
|
|
|
|
* @return void, may throw exception
|
|
|
|
*/
|
|
|
|
function upgrade_core($version, $verbose) {
|
2014-01-10 15:16:35 +08:00
|
|
|
global $CFG, $SITE, $DB, $COURSE;
|
2009-05-26 09:52:38 +00:00
|
|
|
|
2010-10-19 10:17:48 +00:00
|
|
|
raise_memory_limit(MEMORY_EXTRA);
|
|
|
|
|
2009-05-26 17:44:25 +00:00
|
|
|
require_once($CFG->libdir.'/db/upgrade.php'); // Defines upgrades
|
|
|
|
|
2009-05-26 09:52:38 +00:00
|
|
|
try {
|
2013-08-08 22:40:10 +02:00
|
|
|
// Reset caches before any output.
|
2013-05-08 17:42:55 +12:00
|
|
|
cache_helper::purge_all(true);
|
2013-08-08 22:40:10 +02:00
|
|
|
purge_all_caches();
|
2010-05-31 05:34:16 +00:00
|
|
|
|
2009-05-26 09:52:38 +00:00
|
|
|
// Upgrade current language pack if we can
|
MDL-29029 move lang pack import to admin tools
Includes lang related language pack cleanup.
AMOS BEGIN
MOV [langpacks,core_admin],[pluginname,tool_langimport]
MOV [install,core_admin],[install,tool_langimport]
MOV [installedlangs,core_admin],[installedlangs,tool_langimport]
MOV [langimport,core_admin],[langimport,tool_langimport]
MOV [langimportdisabled,core_admin],[langimportdisabled,tool_langimport]
MOV [langpackinstalled,core_admin],[langpackinstalled,tool_langimport]
MOV [langpackremoved,core_admin],[langpackremoved,tool_langimport]
MOV [langpackupdateskipped,core_admin],[langpackupdateskipped,tool_langimport]
MOV [langpackuptodate,core_admin],[langpackuptodate,tool_langimport]
MOV [langupdatecomplete,core_admin],[langupdatecomplete,tool_langimport]
MOV [missinglangparent,core_admin],[missinglangparent,tool_langimport]
MOV [nolangupdateneeded,core_admin],[nolangupdateneeded,tool_langimport]
MOV [remotelangnotavailable,core_admin],[remotelangnotavailable,tool_langimport]
MOV [uninstall,core_admin],[uninstall,tool_langimport]
MOV [uninstallconfirm,core_admin],[uninstallconfirm,tool_langimport]
MOV [updatelangs,core_admin],[updatelangs,tool_langimport]
AMOS END
2011-09-17 20:58:26 +02:00
|
|
|
upgrade_language_pack();
|
2009-05-26 09:52:38 +00:00
|
|
|
|
2009-05-26 19:02:11 +00:00
|
|
|
print_upgrade_part_start('moodle', false, $verbose);
|
2009-05-26 09:52:38 +00:00
|
|
|
|
2013-03-19 18:48:38 +01:00
|
|
|
// Pre-upgrade scripts for local hack workarounds.
|
|
|
|
$preupgradefile = "$CFG->dirroot/local/preupgrade.php";
|
|
|
|
if (file_exists($preupgradefile)) {
|
2013-10-15 13:22:19 +01:00
|
|
|
core_php_time_limit::raise();
|
2013-03-19 18:48:38 +01:00
|
|
|
require($preupgradefile);
|
|
|
|
// Reset upgrade timeout to default.
|
|
|
|
upgrade_set_timeout();
|
2009-06-19 14:25:56 +00:00
|
|
|
}
|
|
|
|
|
2009-05-26 09:52:38 +00:00
|
|
|
$result = xmldb_main_upgrade($CFG->version);
|
|
|
|
if ($version > $CFG->version) {
|
|
|
|
// store version if not already there
|
|
|
|
upgrade_main_savepoint($result, $version, false);
|
|
|
|
}
|
|
|
|
|
2014-01-10 15:16:35 +08:00
|
|
|
// In case structure of 'course' table has been changed and we forgot to update $SITE, re-read it from db.
|
|
|
|
$SITE = $DB->get_record('course', array('id' => $SITE->id));
|
|
|
|
$COURSE = clone($SITE);
|
|
|
|
|
2009-05-26 09:52:38 +00:00
|
|
|
// perform all other component upgrade routines
|
|
|
|
update_capabilities('moodle');
|
2010-08-03 10:07:18 +00:00
|
|
|
log_update_descriptions('moodle');
|
2009-09-13 21:26:51 +00:00
|
|
|
external_update_descriptions('moodle');
|
2009-05-26 09:52:38 +00:00
|
|
|
events_update_definition('moodle');
|
2014-02-25 09:47:39 +08:00
|
|
|
\core\task\manager::reset_scheduled_tasks_for_component('moodle');
|
2009-05-26 09:52:38 +00:00
|
|
|
message_update_providers('moodle');
|
2014-07-09 13:22:36 +08:00
|
|
|
\core\message\inbound\manager::update_handlers_for_component('moodle');
|
2015-10-02 23:13:44 +08:00
|
|
|
core_tag_area::reset_definitions_for_component('moodle');
|
2012-11-07 10:36:09 +13:00
|
|
|
// Update core definitions.
|
|
|
|
cache_helper::update_definitions(true);
|
2009-05-26 09:52:38 +00:00
|
|
|
|
2012-11-22 10:33:57 +13:00
|
|
|
// Purge caches again, just to be sure we arn't holding onto old stuff now.
|
2013-05-09 13:40:17 +08:00
|
|
|
cache_helper::purge_all(true);
|
2013-08-08 22:40:10 +02:00
|
|
|
purge_all_caches();
|
2010-07-06 17:14:36 +00:00
|
|
|
|
|
|
|
// Clean up contexts - more and more stuff depends on existence of paths and contexts
|
2011-10-14 12:48:00 +02:00
|
|
|
context_helper::cleanup_instances();
|
|
|
|
context_helper::create_instances(null, false);
|
|
|
|
context_helper::build_all_paths(false);
|
|
|
|
$syscontext = context_system::instance();
|
|
|
|
$syscontext->mark_dirty();
|
2009-05-26 09:52:38 +00:00
|
|
|
|
2009-05-26 19:02:11 +00:00
|
|
|
print_upgrade_part_end('moodle', false, $verbose);
|
2009-05-26 09:52:38 +00:00
|
|
|
} catch (Exception $ex) {
|
|
|
|
upgrade_handle_exception($ex);
|
2015-12-09 11:55:58 +08:00
|
|
|
} catch (Throwable $ex) {
|
|
|
|
// Engine errors in PHP7 throw exceptions of type Throwable (this "catch" will be ignored in PHP5).
|
|
|
|
upgrade_handle_exception($ex);
|
2009-05-26 09:52:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Upgrade/install other parts of moodle
|
|
|
|
* @param bool $verbose
|
|
|
|
* @return void, may throw exception
|
|
|
|
*/
|
|
|
|
function upgrade_noncore($verbose) {
|
|
|
|
global $CFG;
|
|
|
|
|
2010-10-19 10:17:48 +00:00
|
|
|
raise_memory_limit(MEMORY_EXTRA);
|
|
|
|
|
2009-05-26 09:52:38 +00:00
|
|
|
// upgrade all plugins types
|
|
|
|
try {
|
2013-08-08 22:40:10 +02:00
|
|
|
// Reset caches before any output.
|
|
|
|
cache_helper::purge_all(true);
|
|
|
|
purge_all_caches();
|
|
|
|
|
2013-07-16 22:31:48 +02:00
|
|
|
$plugintypes = core_component::get_plugin_types();
|
2009-05-26 09:52:38 +00:00
|
|
|
foreach ($plugintypes as $type=>$location) {
|
2009-06-19 14:25:56 +00:00
|
|
|
upgrade_plugins($type, 'print_upgrade_part_start', 'print_upgrade_part_end', $verbose);
|
2009-05-26 09:52:38 +00:00
|
|
|
}
|
2016-05-03 12:42:29 +02:00
|
|
|
// Upgrade services.
|
|
|
|
// This function gives plugins and subsystems a chance to add functions to existing built-in services.
|
2016-03-03 09:42:27 +01:00
|
|
|
external_update_services();
|
|
|
|
|
2012-11-22 10:33:57 +13:00
|
|
|
// Update cache definitions. Involves scanning each plugin for any changes.
|
2012-11-07 10:36:09 +13:00
|
|
|
cache_helper::update_definitions();
|
2013-08-08 21:11:18 +02:00
|
|
|
// Mark the site as upgraded.
|
|
|
|
set_config('allversionshash', core_component::get_all_versions_hash());
|
2013-08-08 22:40:10 +02:00
|
|
|
|
|
|
|
// Purge caches again, just to be sure we arn't holding onto old stuff now.
|
|
|
|
cache_helper::purge_all(true);
|
|
|
|
purge_all_caches();
|
|
|
|
|
2009-05-26 09:52:38 +00:00
|
|
|
} catch (Exception $ex) {
|
|
|
|
upgrade_handle_exception($ex);
|
2015-12-09 11:55:58 +08:00
|
|
|
} catch (Throwable $ex) {
|
|
|
|
// Engine errors in PHP7 throw exceptions of type Throwable (this "catch" will be ignored in PHP5).
|
|
|
|
upgrade_handle_exception($ex);
|
2009-05-26 09:52:38 +00:00
|
|
|
}
|
|
|
|
}
|
2009-05-26 17:44:25 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Checks if the main tables have been installed yet or not.
|
2013-04-27 21:54:06 +02:00
|
|
|
*
|
|
|
|
* Note: we can not use caches here because they might be stale,
|
|
|
|
* use with care!
|
|
|
|
*
|
2009-05-26 17:44:25 +00:00
|
|
|
* @return bool
|
|
|
|
*/
|
|
|
|
function core_tables_exist() {
|
|
|
|
global $DB;
|
|
|
|
|
2013-04-27 21:54:06 +02:00
|
|
|
if (!$tables = $DB->get_tables(false) ) { // No tables yet at all.
|
2009-05-26 17:44:25 +00:00
|
|
|
return false;
|
2009-08-06 19:59:16 +00:00
|
|
|
|
2009-05-26 17:44:25 +00:00
|
|
|
} else { // Check for missing main tables
|
|
|
|
$mtables = array('config', 'course', 'groupings'); // some tables used in 1.9 and 2.0, preferable something from the start and end of install.xml
|
|
|
|
foreach ($mtables as $mtable) {
|
|
|
|
if (!in_array($mtable, $tables)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true;
|
2009-08-06 19:59:16 +00:00
|
|
|
}
|
2009-05-30 18:51:47 +00:00
|
|
|
}
|
2010-02-02 21:16:56 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* upgrades the mnet rpc definitions for the given component.
|
|
|
|
* this method doesn't return status, an exception will be thrown in the case of an error
|
|
|
|
*
|
|
|
|
* @param string $component the plugin to upgrade, eg auth_mnet
|
|
|
|
*/
|
|
|
|
function upgrade_plugin_mnet_functions($component) {
|
|
|
|
global $DB, $CFG;
|
|
|
|
|
2013-11-19 11:51:20 +08:00
|
|
|
list($type, $plugin) = core_component::normalize_component($component);
|
2013-07-16 22:38:38 +02:00
|
|
|
$path = core_component::get_plugin_directory($type, $plugin);
|
2010-02-02 21:16:56 +00:00
|
|
|
|
2010-09-17 08:15:17 +00:00
|
|
|
$publishes = array();
|
|
|
|
$subscribes = array();
|
2010-02-02 21:16:56 +00:00
|
|
|
if (file_exists($path . '/db/mnet.php')) {
|
|
|
|
require_once($path . '/db/mnet.php'); // $publishes comes from this file
|
|
|
|
}
|
|
|
|
if (empty($publishes)) {
|
|
|
|
$publishes = array(); // still need this to be able to disable stuff later
|
|
|
|
}
|
|
|
|
if (empty($subscribes)) {
|
|
|
|
$subscribes = array(); // still need this to be able to disable stuff later
|
|
|
|
}
|
|
|
|
|
|
|
|
static $servicecache = array();
|
|
|
|
|
|
|
|
// rekey an array based on the rpc method for easy lookups later
|
|
|
|
$publishmethodservices = array();
|
|
|
|
$subscribemethodservices = array();
|
|
|
|
foreach($publishes as $servicename => $service) {
|
|
|
|
if (is_array($service['methods'])) {
|
|
|
|
foreach($service['methods'] as $methodname) {
|
|
|
|
$service['servicename'] = $servicename;
|
|
|
|
$publishmethodservices[$methodname][] = $service;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Disable functions that don't exist (any more) in the source
|
|
|
|
// Should these be deleted? What about their permissions records?
|
|
|
|
foreach ($DB->get_records('mnet_rpc', array('pluginname'=>$plugin, 'plugintype'=>$type), 'functionname ASC ') as $rpc) {
|
|
|
|
if (!array_key_exists($rpc->functionname, $publishmethodservices) && $rpc->enabled) {
|
|
|
|
$DB->set_field('mnet_rpc', 'enabled', 0, array('id' => $rpc->id));
|
|
|
|
} else if (array_key_exists($rpc->functionname, $publishmethodservices) && !$rpc->enabled) {
|
|
|
|
$DB->set_field('mnet_rpc', 'enabled', 1, array('id' => $rpc->id));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// reflect all the services we're publishing and save them
|
|
|
|
static $cachedclasses = array(); // to store reflection information in
|
|
|
|
foreach ($publishes as $service => $data) {
|
|
|
|
$f = $data['filename'];
|
|
|
|
$c = $data['classname'];
|
|
|
|
foreach ($data['methods'] as $method) {
|
2010-09-21 08:54:01 +00:00
|
|
|
$dataobject = new stdClass();
|
2010-02-02 21:16:56 +00:00
|
|
|
$dataobject->plugintype = $type;
|
|
|
|
$dataobject->pluginname = $plugin;
|
|
|
|
$dataobject->enabled = 1;
|
|
|
|
$dataobject->classname = $c;
|
|
|
|
$dataobject->filename = $f;
|
|
|
|
|
|
|
|
if (is_string($method)) {
|
|
|
|
$dataobject->functionname = $method;
|
|
|
|
|
|
|
|
} else if (is_array($method)) { // wants to override file or class
|
|
|
|
$dataobject->functionname = $method['method'];
|
|
|
|
$dataobject->classname = $method['classname'];
|
|
|
|
$dataobject->filename = $method['filename'];
|
|
|
|
}
|
|
|
|
$dataobject->xmlrpcpath = $type.'/'.$plugin.'/'.$dataobject->filename.'/'.$method;
|
|
|
|
$dataobject->static = false;
|
|
|
|
|
|
|
|
require_once($path . '/' . $dataobject->filename);
|
|
|
|
$functionreflect = null; // slightly different ways to get this depending on whether it's a class method or a function
|
|
|
|
if (!empty($dataobject->classname)) {
|
|
|
|
if (!class_exists($dataobject->classname)) {
|
|
|
|
throw new moodle_exception('installnosuchmethod', 'mnet', '', (object)array('method' => $dataobject->functionname, 'class' => $dataobject->classname));
|
|
|
|
}
|
|
|
|
$key = $dataobject->filename . '|' . $dataobject->classname;
|
|
|
|
if (!array_key_exists($key, $cachedclasses)) { // look to see if we've already got a reflection object
|
|
|
|
try {
|
2016-03-21 11:03:24 +08:00
|
|
|
$cachedclasses[$key] = new ReflectionClass($dataobject->classname);
|
|
|
|
} catch (ReflectionException $e) { // catch these and rethrow them to something more helpful
|
2010-02-02 21:16:56 +00:00
|
|
|
throw new moodle_exception('installreflectionclasserror', 'mnet', '', (object)array('method' => $dataobject->functionname, 'class' => $dataobject->classname, 'error' => $e->getMessage()));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
$r =& $cachedclasses[$key];
|
|
|
|
if (!$r->hasMethod($dataobject->functionname)) {
|
|
|
|
throw new moodle_exception('installnosuchmethod', 'mnet', '', (object)array('method' => $dataobject->functionname, 'class' => $dataobject->classname));
|
|
|
|
}
|
2016-03-21 11:03:24 +08:00
|
|
|
$functionreflect = $r->getMethod($dataobject->functionname);
|
2010-02-02 21:16:56 +00:00
|
|
|
$dataobject->static = (int)$functionreflect->isStatic();
|
|
|
|
} else {
|
|
|
|
if (!function_exists($dataobject->functionname)) {
|
|
|
|
throw new moodle_exception('installnosuchfunction', 'mnet', '', (object)array('method' => $dataobject->functionname, 'file' => $dataobject->filename));
|
|
|
|
}
|
|
|
|
try {
|
2016-03-21 11:03:24 +08:00
|
|
|
$functionreflect = new ReflectionFunction($dataobject->functionname);
|
|
|
|
} catch (ReflectionException $e) { // catch these and rethrow them to something more helpful
|
2010-02-02 21:16:56 +00:00
|
|
|
throw new moodle_exception('installreflectionfunctionerror', 'mnet', '', (object)array('method' => $dataobject->functionname, '' => $dataobject->filename, 'error' => $e->getMessage()));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
$dataobject->profile = serialize(admin_mnet_method_profile($functionreflect));
|
2016-03-21 11:03:24 +08:00
|
|
|
$dataobject->help = admin_mnet_method_get_help($functionreflect);
|
2010-02-02 21:16:56 +00:00
|
|
|
|
|
|
|
if ($record_exists = $DB->get_record('mnet_rpc', array('xmlrpcpath'=>$dataobject->xmlrpcpath))) {
|
|
|
|
$dataobject->id = $record_exists->id;
|
|
|
|
$dataobject->enabled = $record_exists->enabled;
|
|
|
|
$DB->update_record('mnet_rpc', $dataobject);
|
|
|
|
} else {
|
|
|
|
$dataobject->id = $DB->insert_record('mnet_rpc', $dataobject, true);
|
|
|
|
}
|
|
|
|
|
2010-07-17 22:29:28 +00:00
|
|
|
// TODO this API versioning must be reworked, here the recently processed method
|
|
|
|
// sets the service API which may not be correct
|
2010-02-18 04:55:34 +00:00
|
|
|
foreach ($publishmethodservices[$dataobject->functionname] as $service) {
|
|
|
|
if ($serviceobj = $DB->get_record('mnet_service', array('name'=>$service['servicename']))) {
|
|
|
|
$serviceobj->apiversion = $service['apiversion'];
|
|
|
|
$DB->update_record('mnet_service', $serviceobj);
|
|
|
|
} else {
|
|
|
|
$serviceobj = new stdClass();
|
|
|
|
$serviceobj->name = $service['servicename'];
|
2010-11-10 16:01:23 +00:00
|
|
|
$serviceobj->description = empty($service['description']) ? '' : $service['description'];
|
2010-02-18 04:55:34 +00:00
|
|
|
$serviceobj->apiversion = $service['apiversion'];
|
|
|
|
$serviceobj->offer = 1;
|
|
|
|
$serviceobj->id = $DB->insert_record('mnet_service', $serviceobj);
|
|
|
|
}
|
|
|
|
$servicecache[$service['servicename']] = $serviceobj;
|
|
|
|
if (!$DB->record_exists('mnet_service2rpc', array('rpcid'=>$dataobject->id, 'serviceid'=>$serviceobj->id))) {
|
|
|
|
$obj = new stdClass();
|
|
|
|
$obj->rpcid = $dataobject->id;
|
|
|
|
$obj->serviceid = $serviceobj->id;
|
|
|
|
$DB->insert_record('mnet_service2rpc', $obj, true);
|
|
|
|
}
|
2010-02-02 21:16:56 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// finished with methods we publish, now do subscribable methods
|
|
|
|
foreach($subscribes as $service => $methods) {
|
|
|
|
if (!array_key_exists($service, $servicecache)) {
|
|
|
|
if (!$serviceobj = $DB->get_record('mnet_service', array('name' => $service))) {
|
2010-03-30 19:51:34 +00:00
|
|
|
debugging("TODO: skipping unknown service $service - somebody needs to fix MDL-21993");
|
2010-02-02 21:16:56 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
$servicecache[$service] = $serviceobj;
|
|
|
|
} else {
|
|
|
|
$serviceobj = $servicecache[$service];
|
|
|
|
}
|
|
|
|
foreach ($methods as $method => $xmlrpcpath) {
|
|
|
|
if (!$rpcid = $DB->get_field('mnet_remote_rpc', 'id', array('xmlrpcpath'=>$xmlrpcpath))) {
|
|
|
|
$remoterpc = (object)array(
|
|
|
|
'functionname' => $method,
|
|
|
|
'xmlrpcpath' => $xmlrpcpath,
|
|
|
|
'plugintype' => $type,
|
|
|
|
'pluginname' => $plugin,
|
|
|
|
'enabled' => 1,
|
|
|
|
);
|
|
|
|
$rpcid = $remoterpc->id = $DB->insert_record('mnet_remote_rpc', $remoterpc, true);
|
|
|
|
}
|
|
|
|
if (!$DB->record_exists('mnet_remote_service2rpc', array('rpcid'=>$rpcid, 'serviceid'=>$serviceobj->id))) {
|
|
|
|
$obj = new stdClass();
|
|
|
|
$obj->rpcid = $rpcid;
|
|
|
|
$obj->serviceid = $serviceobj->id;
|
|
|
|
$DB->insert_record('mnet_remote_service2rpc', $obj, true);
|
|
|
|
}
|
2010-02-18 04:55:34 +00:00
|
|
|
$subscribemethodservices[$method][] = $service;
|
2010-02-02 21:16:56 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
foreach ($DB->get_records('mnet_remote_rpc', array('pluginname'=>$plugin, 'plugintype'=>$type), 'functionname ASC ') as $rpc) {
|
|
|
|
if (!array_key_exists($rpc->functionname, $subscribemethodservices) && $rpc->enabled) {
|
|
|
|
$DB->set_field('mnet_remote_rpc', 'enabled', 0, array('id' => $rpc->id));
|
|
|
|
} else if (array_key_exists($rpc->functionname, $subscribemethodservices) && !$rpc->enabled) {
|
|
|
|
$DB->set_field('mnet_remote_rpc', 'enabled', 1, array('id' => $rpc->id));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2016-03-21 11:03:24 +08:00
|
|
|
* Given some sort of reflection function/method object, return a profile array, ready to be serialized and stored
|
2010-02-02 21:16:56 +00:00
|
|
|
*
|
2016-03-21 11:03:24 +08:00
|
|
|
* @param ReflectionFunctionAbstract $function reflection function/method object from which to extract information
|
2010-02-02 21:16:56 +00:00
|
|
|
*
|
2016-03-21 11:03:24 +08:00
|
|
|
* @return array associative array with function/method information
|
2010-02-02 21:16:56 +00:00
|
|
|
*/
|
2016-03-21 11:03:24 +08:00
|
|
|
function admin_mnet_method_profile(ReflectionFunctionAbstract $function) {
|
|
|
|
$commentlines = admin_mnet_method_get_docblock($function);
|
|
|
|
$getkey = function($key) use ($commentlines) {
|
|
|
|
return array_values(array_filter($commentlines, function($line) use ($key) {
|
|
|
|
return $line[0] == $key;
|
|
|
|
}));
|
|
|
|
};
|
|
|
|
$returnline = $getkey('@return');
|
|
|
|
return array (
|
|
|
|
'parameters' => array_map(function($line) {
|
|
|
|
return array(
|
|
|
|
'name' => trim($line[2], " \t\n\r\0\x0B$"),
|
|
|
|
'type' => $line[1],
|
|
|
|
'description' => $line[3]
|
|
|
|
);
|
|
|
|
}, $getkey('@param')),
|
|
|
|
|
|
|
|
'return' => array(
|
|
|
|
'type' => !empty($returnline[0][1]) ? $returnline[0][1] : 'void',
|
|
|
|
'description' => !empty($returnline[0][2]) ? $returnline[0][2] : ''
|
|
|
|
)
|
2010-02-02 21:16:56 +00:00
|
|
|
);
|
2016-03-21 11:03:24 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Given some sort of reflection function/method object, return an array of docblock lines, where each line is an array of
|
|
|
|
* keywords/descriptions
|
|
|
|
*
|
|
|
|
* @param ReflectionFunctionAbstract $function reflection function/method object from which to extract information
|
|
|
|
*
|
|
|
|
* @return array docblock converted in to an array
|
|
|
|
*/
|
|
|
|
function admin_mnet_method_get_docblock(ReflectionFunctionAbstract $function) {
|
|
|
|
return array_map(function($line) {
|
|
|
|
$text = trim($line, " \t\n\r\0\x0B*/");
|
|
|
|
if (strpos($text, '@param') === 0) {
|
|
|
|
return preg_split('/\s+/', $text, 4);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (strpos($text, '@return') === 0) {
|
|
|
|
return preg_split('/\s+/', $text, 3);
|
|
|
|
}
|
|
|
|
|
|
|
|
return array($text);
|
|
|
|
}, explode("\n", $function->getDocComment()));
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Given some sort of reflection function/method object, return just the help text
|
|
|
|
*
|
|
|
|
* @param ReflectionFunctionAbstract $function reflection function/method object from which to extract information
|
|
|
|
*
|
|
|
|
* @return string docblock help text
|
|
|
|
*/
|
|
|
|
function admin_mnet_method_get_help(ReflectionFunctionAbstract $function) {
|
|
|
|
$helplines = array_map(function($line) {
|
|
|
|
return implode(' ', $line);
|
|
|
|
}, array_values(array_filter(admin_mnet_method_get_docblock($function), function($line) {
|
|
|
|
return strpos($line[0], '@') !== 0 && !empty($line[0]);
|
|
|
|
})));
|
|
|
|
|
|
|
|
return implode("\n", $helplines);
|
2010-02-02 21:16:56 +00:00
|
|
|
}
|
2012-05-28 15:14:28 +12:00
|
|
|
|
2014-10-16 17:10:51 +08:00
|
|
|
/**
|
|
|
|
* Detect draft file areas with missing root directory records and add them.
|
|
|
|
*/
|
|
|
|
function upgrade_fix_missing_root_folders_draft() {
|
|
|
|
global $DB;
|
|
|
|
|
|
|
|
$transaction = $DB->start_delegated_transaction();
|
|
|
|
|
|
|
|
$sql = "SELECT contextid, itemid, MAX(timecreated) AS timecreated, MAX(timemodified) AS timemodified
|
|
|
|
FROM {files}
|
|
|
|
WHERE (component = 'user' AND filearea = 'draft')
|
|
|
|
GROUP BY contextid, itemid
|
|
|
|
HAVING MAX(CASE WHEN filename = '.' AND filepath = '/' THEN 1 ELSE 0 END) = 0";
|
|
|
|
|
|
|
|
$rs = $DB->get_recordset_sql($sql);
|
|
|
|
$defaults = array('component' => 'user',
|
|
|
|
'filearea' => 'draft',
|
|
|
|
'filepath' => '/',
|
|
|
|
'filename' => '.',
|
|
|
|
'userid' => 0, // Don't rely on any particular user for these system records.
|
|
|
|
'filesize' => 0,
|
|
|
|
'contenthash' => sha1(''));
|
|
|
|
foreach ($rs as $r) {
|
|
|
|
$r->pathnamehash = sha1("/$r->contextid/user/draft/$r->itemid/.");
|
|
|
|
$DB->insert_record('files', (array)$r + $defaults);
|
|
|
|
}
|
|
|
|
$rs->close();
|
|
|
|
$transaction->allow_commit();
|
|
|
|
}
|
2015-02-26 19:01:37 -08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* This function verifies that the database is not using an unsupported storage engine.
|
|
|
|
*
|
|
|
|
* @param environment_results $result object to update, if relevant
|
|
|
|
* @return environment_results|null updated results object, or null if the storage engine is supported
|
|
|
|
*/
|
|
|
|
function check_database_storage_engine(environment_results $result) {
|
|
|
|
global $DB;
|
|
|
|
|
|
|
|
// Check if MySQL is the DB family (this will also be the same for MariaDB).
|
|
|
|
if ($DB->get_dbfamily() == 'mysql') {
|
|
|
|
// Get the database engine we will either be using to install the tables, or what we are currently using.
|
|
|
|
$engine = $DB->get_dbengine();
|
|
|
|
// Check if MyISAM is the storage engine that will be used, if so, do not proceed and display an error.
|
|
|
|
if ($engine == 'MyISAM') {
|
|
|
|
$result->setInfo('unsupported_db_storage_engine');
|
|
|
|
$result->setStatus(false);
|
|
|
|
return $result;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return null;
|
|
|
|
}
|
2015-03-26 16:06:08 +08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Method used to check the usage of slasharguments config and display a warning message.
|
|
|
|
*
|
|
|
|
* @param environment_results $result object to update, if relevant.
|
|
|
|
* @return environment_results|null updated results or null if slasharguments is disabled.
|
|
|
|
*/
|
|
|
|
function check_slasharguments(environment_results $result){
|
|
|
|
global $CFG;
|
|
|
|
|
2015-07-20 16:27:27 +08:00
|
|
|
if (!during_initial_install() && empty($CFG->slasharguments)) {
|
2015-03-26 16:06:08 +08:00
|
|
|
$result->setInfo('slasharguments');
|
|
|
|
$result->setStatus(false);
|
|
|
|
return $result;
|
|
|
|
}
|
|
|
|
|
|
|
|
return null;
|
|
|
|
}
|
2015-04-10 10:30:09 +08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* This function verifies if the database has tables using innoDB Antelope row format.
|
|
|
|
*
|
|
|
|
* @param environment_results $result
|
|
|
|
* @return environment_results|null updated results object, or null if no Antelope table has been found.
|
|
|
|
*/
|
|
|
|
function check_database_tables_row_format(environment_results $result) {
|
|
|
|
global $DB;
|
|
|
|
|
|
|
|
if ($DB->get_dbfamily() == 'mysql') {
|
|
|
|
$generator = $DB->get_manager()->generator;
|
|
|
|
|
|
|
|
foreach ($DB->get_tables(false) as $table) {
|
|
|
|
$columns = $DB->get_columns($table, false);
|
2015-04-15 14:57:44 +08:00
|
|
|
$size = $generator->guess_antelope_row_size($columns);
|
2015-04-10 10:30:09 +08:00
|
|
|
$format = $DB->get_row_format($table);
|
|
|
|
|
|
|
|
if ($size <= $generator::ANTELOPE_MAX_ROW_SIZE) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($format === 'Compact' or $format === 'Redundant') {
|
|
|
|
$result->setInfo('unsupported_db_table_row_format');
|
|
|
|
$result->setStatus(false);
|
|
|
|
return $result;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return null;
|
|
|
|
}
|
2015-06-04 17:56:37 +08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Upgrade the minmaxgrade setting.
|
|
|
|
*
|
|
|
|
* This step should only be run for sites running 2.8 or later. Sites using 2.7 will be fine
|
|
|
|
* using the new default system setting $CFG->grade_minmaxtouse.
|
|
|
|
*
|
|
|
|
* @return void
|
|
|
|
*/
|
|
|
|
function upgrade_minmaxgrade() {
|
|
|
|
global $CFG, $DB;
|
|
|
|
|
|
|
|
// 2 is a copy of GRADE_MIN_MAX_FROM_GRADE_GRADE.
|
|
|
|
$settingvalue = 2;
|
|
|
|
|
|
|
|
// Set the course setting when:
|
|
|
|
// - The system setting does not exist yet.
|
|
|
|
// - The system seeting is not set to what we'd set the course setting.
|
|
|
|
$setcoursesetting = !isset($CFG->grade_minmaxtouse) || $CFG->grade_minmaxtouse != $settingvalue;
|
|
|
|
|
|
|
|
// Identify the courses that have inconsistencies grade_item vs grade_grade.
|
|
|
|
$sql = "SELECT DISTINCT(gi.courseid)
|
2015-06-12 16:21:50 -04:00
|
|
|
FROM {grade_grades} gg
|
|
|
|
JOIN {grade_items} gi
|
2015-06-04 17:56:37 +08:00
|
|
|
ON gg.itemid = gi.id
|
2015-06-12 16:21:50 -04:00
|
|
|
WHERE gi.itemtype NOT IN (?, ?)
|
2015-06-04 17:56:37 +08:00
|
|
|
AND (gg.rawgrademax != gi.grademax OR gg.rawgrademin != gi.grademin)";
|
|
|
|
|
|
|
|
$rs = $DB->get_recordset_sql($sql, array('course', 'category'));
|
|
|
|
foreach ($rs as $record) {
|
|
|
|
// Flag the course to show a notice in the gradebook.
|
|
|
|
set_config('show_min_max_grades_changed_' . $record->courseid, 1);
|
|
|
|
|
|
|
|
// Set the appropriate course setting so that grades displayed are not changed.
|
|
|
|
$configname = 'minmaxtouse';
|
|
|
|
if ($setcoursesetting &&
|
|
|
|
!$DB->record_exists('grade_settings', array('courseid' => $record->courseid, 'name' => $configname))) {
|
|
|
|
// Do not set the setting when the course already defines it.
|
|
|
|
$data = new stdClass();
|
|
|
|
$data->courseid = $record->courseid;
|
|
|
|
$data->name = $configname;
|
|
|
|
$data->value = $settingvalue;
|
|
|
|
$DB->insert_record('grade_settings', $data);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Mark the grades to be regraded.
|
|
|
|
$DB->set_field('grade_items', 'needsupdate', 1, array('courseid' => $record->courseid));
|
|
|
|
}
|
|
|
|
$rs->close();
|
|
|
|
}
|
2015-09-10 00:39:43 +02:00
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Assert the upgrade key is provided, if it is defined.
|
|
|
|
*
|
|
|
|
* The upgrade key can be defined in the main config.php as $CFG->upgradekey. If
|
|
|
|
* it is defined there, then its value must be provided every time the site is
|
|
|
|
* being upgraded, regardless the administrator is logged in or not.
|
|
|
|
*
|
|
|
|
* This is supposed to be used at certain places in /admin/index.php only.
|
|
|
|
*
|
|
|
|
* @param string|null $upgradekeyhash the SHA-1 of the value provided by the user
|
|
|
|
*/
|
|
|
|
function check_upgrade_key($upgradekeyhash) {
|
|
|
|
global $CFG, $PAGE;
|
|
|
|
|
|
|
|
if (isset($CFG->config_php_settings['upgradekey'])) {
|
|
|
|
if ($upgradekeyhash === null or $upgradekeyhash !== sha1($CFG->config_php_settings['upgradekey'])) {
|
|
|
|
if (!$PAGE->headerprinted) {
|
|
|
|
$output = $PAGE->get_renderer('core', 'admin');
|
|
|
|
echo $output->upgradekey_form_page(new moodle_url('/admin/index.php', array('cache' => 0)));
|
|
|
|
die();
|
|
|
|
} else {
|
|
|
|
// This should not happen.
|
|
|
|
die('Upgrade locked');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2015-10-07 19:30:03 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Helper procedure/macro for installing remote plugins at admin/index.php
|
|
|
|
*
|
|
|
|
* Does not return, always redirects or exits.
|
|
|
|
*
|
|
|
|
* @param array $installable list of \core\update\remote_info
|
|
|
|
* @param bool $confirmed false: display the validation screen, true: proceed installation
|
|
|
|
* @param string $heading validation screen heading
|
|
|
|
* @param moodle_url|string|null $continue URL to proceed with installation at the validation screen
|
2015-10-07 21:25:44 +02:00
|
|
|
* @param moodle_url|string|null $return URL to go back on cancelling at the validation screen
|
2015-10-07 19:30:03 +02:00
|
|
|
*/
|
2015-10-08 21:21:15 +02:00
|
|
|
function upgrade_install_plugins(array $installable, $confirmed, $heading='', $continue=null, $return=null) {
|
2015-10-09 22:23:52 +02:00
|
|
|
global $CFG, $PAGE;
|
2015-10-07 19:30:03 +02:00
|
|
|
|
|
|
|
if (empty($return)) {
|
|
|
|
$return = $PAGE->url;
|
|
|
|
}
|
|
|
|
|
2015-10-09 22:23:52 +02:00
|
|
|
if (!empty($CFG->disableupdateautodeploy)) {
|
|
|
|
redirect($return);
|
|
|
|
}
|
|
|
|
|
2015-10-07 19:30:03 +02:00
|
|
|
if (empty($installable)) {
|
|
|
|
redirect($return);
|
|
|
|
}
|
|
|
|
|
|
|
|
$pluginman = core_plugin_manager::instance();
|
|
|
|
|
|
|
|
if ($confirmed) {
|
|
|
|
// Installation confirmed at the validation results page.
|
2015-10-08 21:21:15 +02:00
|
|
|
if (!$pluginman->install_plugins($installable, true, true)) {
|
|
|
|
throw new moodle_exception('install_plugins_failed', 'core_plugin', $return);
|
2015-10-07 19:30:03 +02:00
|
|
|
}
|
2015-10-09 18:46:01 +02:00
|
|
|
|
2015-10-07 21:25:44 +02:00
|
|
|
// Always redirect to admin/index.php to perform the database upgrade.
|
2015-10-09 18:46:01 +02:00
|
|
|
// Do not throw away the existing $PAGE->url parameters such as
|
|
|
|
// confirmupgrade or confirmrelease if $PAGE->url is a superset of the
|
|
|
|
// URL we must go to.
|
|
|
|
$mustgoto = new moodle_url('/admin/index.php', array('cache' => 0, 'confirmplugincheck' => 0));
|
|
|
|
if ($mustgoto->compare($PAGE->url, URL_MATCH_PARAMS)) {
|
|
|
|
redirect($PAGE->url);
|
|
|
|
} else {
|
|
|
|
redirect($mustgoto);
|
|
|
|
}
|
2015-10-07 19:30:03 +02:00
|
|
|
|
|
|
|
} else {
|
|
|
|
$output = $PAGE->get_renderer('core', 'admin');
|
|
|
|
echo $output->header();
|
|
|
|
if ($heading) {
|
|
|
|
echo $output->heading($heading, 3);
|
|
|
|
}
|
|
|
|
echo html_writer::start_tag('pre', array('class' => 'plugin-install-console'));
|
2015-10-08 21:21:15 +02:00
|
|
|
$validated = $pluginman->install_plugins($installable, false, false);
|
2015-10-07 19:30:03 +02:00
|
|
|
echo html_writer::end_tag('pre');
|
|
|
|
if ($validated) {
|
2015-10-08 23:28:43 +02:00
|
|
|
echo $output->plugins_management_confirm_buttons($continue, $return);
|
2015-10-07 19:30:03 +02:00
|
|
|
} else {
|
2015-10-08 23:28:43 +02:00
|
|
|
echo $output->plugins_management_confirm_buttons(null, $return);
|
2015-10-07 19:30:03 +02:00
|
|
|
}
|
|
|
|
echo $output->footer();
|
|
|
|
die();
|
|
|
|
}
|
|
|
|
}
|
2016-05-03 16:04:16 +08:00
|
|
|
/**
|
|
|
|
* Method used to check the installed unoconv version.
|
|
|
|
*
|
|
|
|
* @param environment_results $result object to update, if relevant.
|
|
|
|
* @return environment_results|null updated results or null if unoconv path is not executable.
|
|
|
|
*/
|
2016-05-09 13:59:33 +08:00
|
|
|
function check_unoconv_version(environment_results $result) {
|
2016-05-03 16:04:16 +08:00
|
|
|
global $CFG;
|
|
|
|
|
2016-05-09 13:59:33 +08:00
|
|
|
if (!during_initial_install() && !empty($CFG->pathtounoconv) && file_is_executable(trim($CFG->pathtounoconv))) {
|
2016-06-22 13:36:02 +08:00
|
|
|
$currentversion = 0;
|
|
|
|
$supportedversion = 0.7;
|
2016-05-09 13:59:33 +08:00
|
|
|
$unoconvbin = \escapeshellarg($CFG->pathtounoconv);
|
|
|
|
$command = "$unoconvbin --version";
|
|
|
|
exec($command, $output);
|
2016-06-22 13:36:02 +08:00
|
|
|
|
|
|
|
// If the command execution returned some output, then get the unoconv version.
|
2016-06-21 09:38:01 +08:00
|
|
|
if ($output) {
|
|
|
|
foreach ($output as $response) {
|
|
|
|
if (preg_match('/unoconv (\\d+\\.\\d+)/', $response, $matches)) {
|
|
|
|
$currentversion = (float)$matches[1];
|
|
|
|
}
|
|
|
|
}
|
2016-06-22 13:36:02 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
if ($currentversion < $supportedversion) {
|
|
|
|
$result->setInfo('unoconv version not supported');
|
|
|
|
$result->setStatus(false);
|
|
|
|
return $result;
|
2016-05-03 16:04:16 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
}
|