diff --git a/admin/cli/install.php b/admin/cli/install.php index d02d1e31230..f0bee315f6a 100644 --- a/admin/cli/install.php +++ b/admin/cli/install.php @@ -36,6 +36,12 @@ if (isset($_SERVER['REMOTE_ADDR'])) { exit(1); } +// Force OPcache reset if used, we do not want any stale caches +// when preparing test environment. +if (function_exists('opcache_reset')) { + opcache_reset(); +} + $help = "Command line Moodle installer, creates config.php and initializes database. Please note you must execute this script with the same uid as apache diff --git a/admin/cli/install_database.php b/admin/cli/install_database.php index dfc7a420d8a..7a4f288ba5a 100644 --- a/admin/cli/install_database.php +++ b/admin/cli/install_database.php @@ -36,6 +36,12 @@ if (isset($_SERVER['REMOTE_ADDR'])) { exit(1); } +// Force OPcache reset if used, we do not want any stale caches +// when preparing test environment. +if (function_exists('opcache_reset')) { + opcache_reset(); +} + $help = "Advanced command line Moodle database installer. Please note you must execute this script with the same uid as apache. diff --git a/admin/cli/upgrade.php b/admin/cli/upgrade.php index ca6ef6ae384..98e87264b0b 100644 --- a/admin/cli/upgrade.php +++ b/admin/cli/upgrade.php @@ -29,6 +29,12 @@ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ +// Force OPcache reset if used, we do not want any stale caches +// when detecting if upgrade necessary or when running upgrade. +if (function_exists('opcache_reset') and !isset($_SERVER['REMOTE_ADDR'])) { + opcache_reset(); +} + define('CLI_SCRIPT', true); define('CACHE_DISABLE_ALL', true); diff --git a/admin/index.php b/admin/index.php index c54e8388791..9acf551fdd6 100644 --- a/admin/index.php +++ b/admin/index.php @@ -52,6 +52,12 @@ if (empty($_GET['cache']) and empty($_POST['cache'])) { // we redirect to self once we known no upgrades are necessary. // Note: $_GET and $_POST are used here intentionally because our param cleaning is not loaded yet. define('CACHE_DISABLE_ALL', true); + + // Force OPcache reset if used, we do not want any stale caches + // when detecting if upgrade necessary or when running upgrade. + if (function_exists('opcache_reset')) { + opcache_reset(); + } } require('../config.php'); diff --git a/admin/plugins.php b/admin/plugins.php index 280c0aebe93..8ceba12c755 100644 --- a/admin/plugins.php +++ b/admin/plugins.php @@ -85,10 +85,18 @@ if ($uninstall) { if ($pluginman->is_plugin_folder_removable($pluginfo->component)) { $continueurl = new moodle_url($PAGE->url, array('delete' => $pluginfo->component, 'sesskey' => sesskey(), 'confirm' => 1)); echo $output->plugin_uninstall_results_removable_page($pluginman, $pluginfo, $progress, $continueurl); + // Reset op code caches. + if (function_exists('opcache_reset')) { + opcache_reset(); + } exit(); } else { echo $output->plugin_uninstall_results_page($pluginman, $pluginfo, $progress); + // Reset op code caches. + if (function_exists('opcache_reset')) { + opcache_reset(); + } exit(); } } @@ -131,6 +139,10 @@ if ($delete and $confirmed) { // So long, and thanks for all the bugs. fulldelete($pluginfo->rootdir); + // Reset op code caches. + if (function_exists('opcache_reset')) { + opcache_reset(); + } redirect($PAGE->url); } diff --git a/admin/tool/behat/cli/init.php b/admin/tool/behat/cli/init.php index fd11b088bca..9ac693183cf 100644 --- a/admin/tool/behat/cli/init.php +++ b/admin/tool/behat/cli/init.php @@ -26,6 +26,12 @@ if (isset($_SERVER['REMOTE_ADDR'])) { die(); // No access from web! } +// Force OPcache reset if used, we do not want any stale caches +// when preparing test environment. +if (function_exists('opcache_reset')) { + opcache_reset(); +} + // Is not really necessary but adding it as is a CLI_SCRIPT. define('CLI_SCRIPT', true); diff --git a/admin/tool/phpunit/cli/init.php b/admin/tool/phpunit/cli/init.php index bf026a439c2..a3d875dfc61 100644 --- a/admin/tool/phpunit/cli/init.php +++ b/admin/tool/phpunit/cli/init.php @@ -26,6 +26,12 @@ if (isset($_SERVER['REMOTE_ADDR'])) { die; // no access from web! } +// Force OPcache reset if used, we do not want any stale caches +// when preparing test environment. +if (function_exists('opcache_reset')) { + opcache_reset(); +} + require_once(__DIR__.'/../../../../lib/clilib.php'); require_once(__DIR__.'/../../../../lib/phpunit/bootstraplib.php'); require_once(__DIR__.'/../../../../lib/testing/lib.php'); diff --git a/cache/locallib.php b/cache/locallib.php index 8124fdc76a9..e66384d6f94 100644 --- a/cache/locallib.php +++ b/cache/locallib.php @@ -108,6 +108,8 @@ class cache_config_writer extends cache_config { fflush($handle); fclose($handle); $locking->unlock('configwrite', 'config'); + // Tell PHP to recompile the script. + core_component::invalidate_opcode_php_cache($cachefile); } else { throw new cache_exception('ex_configcannotsave', 'cache', '', null, 'Unable to open the cache config file.'); } diff --git a/lib/classes/component.php b/lib/classes/component.php index fefe8e66fb9..0c7a8fa7bc8 100644 --- a/lib/classes/component.php +++ b/lib/classes/component.php @@ -142,6 +142,7 @@ class core_component { @chmod($cachefile, $CFG->filepermissions); } @unlink($cachefile.'.tmp'); // Just in case anything fails (race condition). + self::invalidate_opcode_php_cache($cachefile); } } @@ -735,4 +736,21 @@ $cache = '.var_export($cache, true).'; } return $return; } + + /** + * Invalidate opcode cache for given file, this is intended for + * php files that are stored in dataroot. + * + * Note: we need it here because this class must be self-contained. + * + * @param string $file + */ + public static function invalidate_opcode_php_cache($file) { + if (function_exists('opcache_invalidate')) { + if (!file_exists($file)) { + return; + } + opcache_invalidate($file, true); + } + } } diff --git a/lib/moodlelib.php b/lib/moodlelib.php index 9acd4677d70..a23299757a8 100644 --- a/lib/moodlelib.php +++ b/lib/moodlelib.php @@ -7216,6 +7216,11 @@ class core_string_manager implements string_manager { // and re-populate it again fulldelete($this->menucache); $this->get_list_of_translations(true); + + // Lang packs use PHP files in dataroot, it is better to invalidate opcode caches. + if (function_exists('opcache_reset')) { + opcache_reset(); + } } /** diff --git a/lib/phpunit/bootstrap.php b/lib/phpunit/bootstrap.php index ed38405263f..0593812cad1 100644 --- a/lib/phpunit/bootstrap.php +++ b/lib/phpunit/bootstrap.php @@ -31,6 +31,15 @@ error_reporting(E_ALL | E_STRICT); ini_set('display_errors', '1'); ini_set('log_errors', '1'); +// Make sure OPcache does not strip comments, we need them in phpunit! +if (ini_get('opcache.enable') and strtolower(ini_get('opcache.enable')) !== 'off') { + if (!ini_get('opcache.save_comments') or strtolower(ini_get('opcache.save_comments')) === 'off') { + ini_set('opcache.enable', 0); + } else { + ini_set('opcache.load_comments', 1); + } +} + require_once(__DIR__.'/bootstraplib.php'); require_once(__DIR__.'/../testing/lib.php'); require_once(__DIR__.'/classes/autoloader.php'); diff --git a/webservice/amf/server.php b/webservice/amf/server.php index 32a460227a5..a91fd59bb39 100644 --- a/webservice/amf/server.php +++ b/webservice/amf/server.php @@ -33,6 +33,15 @@ define('NO_DEBUG_DISPLAY', true); */ define('NO_MOODLE_COOKIES', true); +// Make sure OPcache does not strip comments, we need them for Zend! +if (ini_get('opcache.enable') and strtolower(ini_get('opcache.enable')) !== 'off') { + if (!ini_get('opcache.save_comments') or strtolower(ini_get('opcache.save_comments')) === 'off') { + ini_set('opcache.enable', 0); + } else { + ini_set('opcache.load_comments', 1); + } +} + require('../../config.php'); require_once("$CFG->dirroot/webservice/amf/locallib.php"); diff --git a/webservice/amf/simpleserver.php b/webservice/amf/simpleserver.php index 896ff35ecf4..9a12c29b397 100644 --- a/webservice/amf/simpleserver.php +++ b/webservice/amf/simpleserver.php @@ -33,6 +33,15 @@ define('NO_DEBUG_DISPLAY', true); */ define('NO_MOODLE_COOKIES', true); +// Make sure OPcache does not strip comments, we need them for Zend! +if (ini_get('opcache.enable') and strtolower(ini_get('opcache.enable')) !== 'off') { + if (!ini_get('opcache.save_comments') or strtolower(ini_get('opcache.save_comments')) === 'off') { + ini_set('opcache.enable', 0); + } else { + ini_set('opcache.load_comments', 1); + } +} + require('../../config.php'); require_once("$CFG->dirroot/webservice/amf/locallib.php"); diff --git a/webservice/soap/server.php b/webservice/soap/server.php index b110cfeaa89..0c34b9ddbd1 100644 --- a/webservice/soap/server.php +++ b/webservice/soap/server.php @@ -33,6 +33,15 @@ define('NO_DEBUG_DISPLAY', true); */ define('NO_MOODLE_COOKIES', true); +// Make sure OPcache does not strip comments, we need them for Zend! +if (ini_get('opcache.enable') and strtolower(ini_get('opcache.enable')) !== 'off') { + if (!ini_get('opcache.save_comments') or strtolower(ini_get('opcache.save_comments')) === 'off') { + ini_set('opcache.enable', 0); + } else { + ini_set('opcache.load_comments', 1); + } +} + require('../../config.php'); require_once("$CFG->dirroot/webservice/soap/locallib.php"); diff --git a/webservice/soap/simpleserver.php b/webservice/soap/simpleserver.php index e9e1bb6c418..26c5ddf592b 100644 --- a/webservice/soap/simpleserver.php +++ b/webservice/soap/simpleserver.php @@ -33,6 +33,15 @@ define('NO_DEBUG_DISPLAY', true); */ define('NO_MOODLE_COOKIES', true); +// Make sure OPcache does not strip comments, we need them for Zend! +if (ini_get('opcache.enable') and strtolower(ini_get('opcache.enable')) !== 'off') { + if (!ini_get('opcache.save_comments') or strtolower(ini_get('opcache.save_comments')) === 'off') { + ini_set('opcache.enable', 0); + } else { + ini_set('opcache.load_comments', 1); + } +} + require('../../config.php'); require_once("$CFG->dirroot/webservice/soap/locallib.php"); diff --git a/webservice/xmlrpc/server.php b/webservice/xmlrpc/server.php index bb07369d3ed..6e13b65c102 100644 --- a/webservice/xmlrpc/server.php +++ b/webservice/xmlrpc/server.php @@ -33,6 +33,15 @@ define('NO_DEBUG_DISPLAY', true); */ define('NO_MOODLE_COOKIES', true); +// Make sure OPcache does not strip comments, we need them for Zend! +if (ini_get('opcache.enable') and strtolower(ini_get('opcache.enable')) !== 'off') { + if (!ini_get('opcache.save_comments') or strtolower(ini_get('opcache.save_comments')) === 'off') { + ini_set('opcache.enable', 0); + } else { + ini_set('opcache.load_comments', 1); + } +} + require('../../config.php'); require_once("$CFG->dirroot/webservice/xmlrpc/locallib.php"); diff --git a/webservice/xmlrpc/simpleserver.php b/webservice/xmlrpc/simpleserver.php index ca8bbe1bc80..27df8398a5e 100644 --- a/webservice/xmlrpc/simpleserver.php +++ b/webservice/xmlrpc/simpleserver.php @@ -33,6 +33,15 @@ define('NO_DEBUG_DISPLAY', true); */ define('NO_MOODLE_COOKIES', true); +// Make sure OPcache does not strip comments, we need them for Zend! +if (ini_get('opcache.enable') and strtolower(ini_get('opcache.enable')) !== 'off') { + if (!ini_get('opcache.save_comments') or strtolower(ini_get('opcache.save_comments')) === 'off') { + ini_set('opcache.enable', 0); + } else { + ini_set('opcache.load_comments', 1); + } +} + require('../../config.php'); require_once("$CFG->dirroot/webservice/xmlrpc/locallib.php");