/**
  * Saves the current configuration.
  *
  * Exceptions within this function are tolerated but must be of type cache_exception.
  * They are caught during initialisation and written to the error log. This is required in order to avoid
  * infinite loop situations caused by the cache throwing exceptions during its initialisation.
  */
 protected function config_save()
 {
     global $CFG;
     $cachefile = self::get_config_file_path();
     $directory = dirname($cachefile);
     if ($directory !== $CFG->dataroot && !file_exists($directory)) {
         $result = make_writable_directory($directory, false);
         if (!$result) {
             throw new cache_exception('ex_configcannotsave', 'cache', '', null, 'Cannot create config directory. Check the permissions on your moodledata directory.');
         }
     }
     if (!file_exists($directory) || !is_writable($directory)) {
         throw new cache_exception('ex_configcannotsave', 'cache', '', null, 'Config directory is not writable. Check the permissions on the moodledata/muc directory.');
     }
     // Prepare a configuration array to store.
     $configuration = $this->generate_configuration_array();
     // Prepare the file content.
     $content = "<?php defined('MOODLE_INTERNAL') || die();\n \$configuration = " . var_export($configuration, true) . ";";
     // We need to create a temporary cache lock instance for use here. Remember we are generating the config file
     // it doesn't exist and thus we can't use the normal API for this (it'll just try to use config).
     $lockconf = reset($this->configlocks);
     if ($lockconf === false) {
         debugging('Your cache configuration file is out of date and needs to be refreshed.', DEBUG_DEVELOPER);
         // Use the default
         $lockconf = array('name' => 'cachelock_file_default', 'type' => 'cachelock_file', 'dir' => 'filelocks', 'default' => true);
     }
     $factory = cache_factory::instance();
     $locking = $factory->create_lock_instance($lockconf);
     if ($locking->lock('configwrite', 'config', true)) {
         // Its safe to use w mode here because we have already acquired the lock.
         $handle = fopen($cachefile, 'w');
         fwrite($handle, $content);
         fflush($handle);
         fclose($handle);
         $locking->unlock('configwrite', 'config');
         @chmod($cachefile, $CFG->filepermissions);
         // 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.');
     }
 }