From d1bb2a5d51075426c8dde220f319da50f23445d3 Mon Sep 17 00:00:00 2001
From: =?utf8?q?Roland=20H=C3=A4der?= <roland@mxchange.org>
Date: Sat, 18 Feb 2023 00:52:54 +0100
Subject: [PATCH] Continued: - removed .htaccess files and added .gitkeep, you
 have to make this now sure by   yourself - developer_mode_enabled renamed to
 is_developer_mode_enabled and invoked method   isEnabled() instead - fixed
 writing class/list cache files - more debug lines added

---
 contrib/cleanup.sh                            |  10 +
 db/.gitkeep                                   |   0
 db/.htaccess                                  |   1 -
 db/news/.gitkeep                              |   0
 db/news/.htaccess                             |   1 -
 .../bootstrap/class_FrameworkBootstrap.php    |   4 +-
 framework/config-global.php                   |   4 +-
 framework/loader/class_ClassLoader.php        | 191 +++++++++++++-----
 .../classes/class_BaseFrameworkSystem.php     |   4 +-
 9 files changed, 154 insertions(+), 61 deletions(-)
 create mode 100755 contrib/cleanup.sh
 create mode 100644 db/.gitkeep
 delete mode 100644 db/.htaccess
 create mode 100644 db/news/.gitkeep
 delete mode 100644 db/news/.htaccess

diff --git a/contrib/cleanup.sh b/contrib/cleanup.sh
new file mode 100755
index 00000000..0dc5a864
--- /dev/null
+++ b/contrib/cleanup.sh
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+# Cleans up all created files to start from scratch
+
+echo "$0: Cleaning up database ..."
+rm -f db/*/*.serial*
+rm -f db/*.cache
+
+echo "$0: All done."
+exit 0
diff --git a/db/.gitkeep b/db/.gitkeep
new file mode 100644
index 00000000..e69de29b
diff --git a/db/.htaccess b/db/.htaccess
deleted file mode 100644
index 3a428827..00000000
--- a/db/.htaccess
+++ /dev/null
@@ -1 +0,0 @@
-Deny from all
diff --git a/db/news/.gitkeep b/db/news/.gitkeep
new file mode 100644
index 00000000..e69de29b
diff --git a/db/news/.htaccess b/db/news/.htaccess
deleted file mode 100644
index 3a428827..00000000
--- a/db/news/.htaccess
+++ /dev/null
@@ -1 +0,0 @@
-Deny from all
diff --git a/framework/bootstrap/class_FrameworkBootstrap.php b/framework/bootstrap/class_FrameworkBootstrap.php
index de4aac3d..91dde86e 100644
--- a/framework/bootstrap/class_FrameworkBootstrap.php
+++ b/framework/bootstrap/class_FrameworkBootstrap.php
@@ -376,9 +376,9 @@ final class FrameworkBootstrap {
 	public static function startApplication () {
 		// Is there an application helper instance?
 		$applicationInstance = call_user_func_array(
-			array(
+			[
 				'Org\Mxchange\CoreFramework\Helper\Application\ApplicationHelper', 'getSelfInstance'
-			), []
+			], []
 		);
 
 		// Some sanity checks
diff --git a/framework/config-global.php b/framework/config-global.php
index fbf68496..4ff43989 100644
--- a/framework/config-global.php
+++ b/framework/config-global.php
@@ -466,8 +466,8 @@ $cfg->setConfigEntry('crypto_openssl_stream_class', 'Org\Mxchange\CoreFramework\
 // CFG: CRYPTO-NULL-STREAM-CLASS
 $cfg->setConfigEntry('crypto_null_stream_class', 'Org\Mxchange\CoreFramework\Stream\Crypto\Null\NullCryptoStream');
 
-// CFG: DEVELOPER-MODE-ENABLED
-$cfg->setConfigEntry('developer_mode_enabled', true);
+// CFG: IS-DEVELOPER-MODE-ENABLED
+$cfg->setConfigEntry('is_developer_mode_enabled', true);
 
 // CFG: CRYPTO-HASH-FUNCTION-NAME
 $cfg->setConfigEntry('crypto_hash_function_name', 'sha256');
diff --git a/framework/loader/class_ClassLoader.php b/framework/loader/class_ClassLoader.php
index a9de4ee0..48021b4d 100644
--- a/framework/loader/class_ClassLoader.php
+++ b/framework/loader/class_ClassLoader.php
@@ -11,13 +11,14 @@ use \InvalidArgumentException;
 use \RecursiveDirectoryIterator;
 use \RecursiveIteratorIterator;
 use \SplFileInfo;
+use \UnexpectedValueException;
 
 /**
  * This class loads class include files with a specific prefix and suffix
  *
  * @author		Roland Haeder <webmaster@shipsimu.org>
- * @version		1.6.0
- * @copyright	Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2022 Core Developer Team
+ * @version		1.7.0
+ * @copyright	Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2023 Core Developer Team
  * @license		GNU GPL 3.0 or any newer version
  * @link		http://www.shipsimu.org
  *
@@ -35,6 +36,10 @@ use \SplFileInfo;
  * along with this program. If not, see <http://www.gnu.org/licenses/>.
  *
  * ----------------------------------
+ * 1.7.0
+ *  - "Cached" more like config instance and root/application base path for
+ *    shorter call stacks and lesser methods invoked
+ *  - More debug logging
  * 1.6.0
  *  - This class loader is now 100% singleton, no other instance is really
  *    required, therefore the factory method can be removed safely
@@ -68,9 +73,14 @@ final class ClassLoader {
 	private static $selfInstance = NULL;
 
 	/**
-	 * Cached configuration entry 'developer_mode_enabled'
+	 * Instance of a FrameworkConfiguration class
 	 */
-	private static $developerModeEnabled = false;
+	private static $configInstance = NULL;
+
+	/**
+	 * Cached configuration entry 'is_developer_mode_enabled'
+	 */
+	private static $developerModeEnabled = NULL;
 
 	/**
 	 * Array with all valid but pending for loading file names (class,
@@ -151,6 +161,11 @@ final class ClassLoader {
 	 */
 	private static $testPaths = [];
 
+	/**
+	 * Cached includes that needs to be flushed
+	 */
+	private $flushCache = [];
+
 	/**
 	 * The protected constructor. Please use the factory method below, or use
 	 * getSelfInstance() for singleton
@@ -158,8 +173,18 @@ final class ClassLoader {
 	 * @return	void
 	 */
 	private function __construct () {
-		// Cache config entry
-		self::$developerModeEnabled = FrameworkBootstrap::getConfigurationInstance()->getConfigEntry('developer_mode_enabled');
+		// Is developerModeEnabled set?
+		//* NOISY-DEBUG: */ printf('[%s:%d]: CONSTRUCTED!' . PHP_EOL, __METHOD__, __LINE__);
+		if (is_null(self::$developerModeEnabled)) {
+			// Cache config instance
+			self::$configInstance = FrameworkBootstrap::getConfigurationInstance();
+
+			// Cache config entry
+			self::$developerModeEnabled = self::$configInstance->isEnabled('developer_mode');
+		}
+
+		// Trace message
+		//* NOISY-DEBUG: */ printf('[%s:%d]: self::developerModeEnabled=%d - EXIT!' . PHP_EOL, __METHOD__, __LINE__, intval(self::$developerModeEnabled));
 	}
 
 	/**
@@ -169,41 +194,67 @@ final class ClassLoader {
 	 */
 	public function __destruct () {
 		// Skip here if dev-mode
+		//* NOISY-DEBUG: */ printf('[%s:%d]: self::developerModeEnabled=%d - DESTRUCTED!' . PHP_EOL, __METHOD__, __LINE__, intval(self::$developerModeEnabled));
 		if (self::$developerModeEnabled) {
+			// Is enabled, don't cache
+			//* NOISY-DEBUG: */ printf('[%s:%d]: Developer mode enabled, not caching classes - EXIT!' . PHP_EOL, __METHOD__, __LINE__);
 			return;
 		}
 
+		// Init content
+		$cacheContent = '';
+
 		// Skip here if already cached
+		//* NOISY-DEBUG: */ printf('[%s:%d]: this->listCached=%d' . PHP_EOL, __METHOD__, __LINE__, intval($this->listCached));
 		if ($this->listCached === false) {
 			// Writes the cache file of our list away
 			$cacheContent = json_encode($this->pendingFiles);
 
 			// Open cache instance
+			//* NOISY-DEBUG: */ printf('[%s:%d]: cacheContent()=%d' . PHP_EOL, __METHOD__, __LINE__, strlen($cacheContent));
 			$fileObject = $this->listCacheFile->openFile('w');
 
 			// And write whole list
 			$fileObject->fwrite($cacheContent);
+
+			// Close it
+			//* NOISY-DEBUG: */ printf('[%s:%d]: Closing file %s ...' . PHP_EOL, __METHOD__, __LINE__, $fileObject->getPathName());
+			unset($fileObject);
 		}
 
+		// Init content
+		$cacheContent = '';
+
 		// Skip here if already cached
+		//* NOISY-DEBUG: */ printf('[%s:%d]: this->classesCached=%d' . PHP_EOL, __METHOD__, __LINE__, intval($this->classesCached));
 		if ($this->classesCached === false) {
 			// Generate a full-cache of all classes
-			$cacheContent = '';
-			foreach (array_keys($this->loadedClasses) as $fileInstance) {
+			//* NOISY-DEBUG: */ printf('[%s:%d]: this->flushCache()=%d' . PHP_EOL, __METHOD__, __LINE__, count($this->flushCache));
+			foreach ($this->flushCache as $key => $fileInstance) {
 				// Open file
+				//* NOISY-DEBUG: */ printf('[%s:%d]: key=%s,fileInstance[]=%s' . PHP_EOL, __METHOD__, __LINE__, $key, gettype($fileInstance));
 				$fileObject = $fileInstance->openFile('r');
 
 				// Load the file
 				// @TODO Add some uglifying code (compress) here
+				//* NOISY-DEBUG: */ printf('[%s:%d]: Adding fileInstance->size=%d bytes ...' . PHP_EOL, __METHOD__, __LINE__, $fileInstance->getSize());
 				$cacheContent .= $fileObject->fread($fileInstance->getSize());
 			}
 
 			// Open file
+			//* NOISY-DEBUG: */ printf('[%s:%d]: cacheContent()=%d' . PHP_EOL, __METHOD__, __LINE__, strlen($cacheContent));
 			$fileObject = $this->classCacheFile->openFile('w');
 
 			// And write it away
 			$fileObject->fwrite($cacheContent);
+
+			// Close it
+			//* NOISY-DEBUG: */ printf('[%s:%d]: Closing file %s ...' . PHP_EOL, __METHOD__, __LINE__, $fileObject->getPathName());
+			unset($fileObject);
 		}
+
+		// Trace message
+		//* NOISY-DEBUG: */ printf('[%s:%d]: EXIT!' . PHP_EOL, __METHOD__, __LINE__);
 	}
 
 	/**
@@ -217,8 +268,7 @@ final class ClassLoader {
 		$loaderInstance = self::getSelfInstance();
 
 		// "Cache" configuration instance and framework base path
-		$configInstance = FrameworkBootstrap::getConfigurationInstance();
-		$frameworkBasePath = $configInstance->getConfigEntry('framework_base_path');
+		$frameworkBasePath = self::$configInstance->getConfigEntry('framework_base_path');
 
 		// Load all classes
 		//* NOISY-DEBUG: */ printf('[%s:%d]: frameworkBasePath=%s,self::$frameworkPaths()=%d,' . PHP_EOL, __METHOD__, __LINE__, $frameworkBasePath, count(self::$frameworkPaths));
@@ -255,22 +305,24 @@ final class ClassLoader {
 	 * Scans for application's classes, etc.
 	 *
 	 * @return	void
+	 * @throws	UnexpectedValueException	If a given path isn't one or not readable
 	 */
 	public static function scanApplicationClasses () {
 		// Get loader instance
 		//* NOISY-DEBUG: */ printf('[%s:%d]: CALLED!' . PHP_EOL, __METHOD__, __LINE__);
 		$loaderInstance = self::getSelfInstance();
 
-		// "Cache" configuration instance
-		$configInstance = FrameworkBootstrap::getConfigurationInstance();
+		// "Cache" application base path
+		$basePath = self::$configInstance->getConfigEntry('application_base_path');
 
 		// Load all classes for the application
+		//* NOISY-DEBUG: */ printf('[%s:%d]: self::frameworkPaths()=%d,basePath=%s' . PHP_EOL, __METHOD__, __LINE__, count(self::$frameworkPaths), $basePath);
 		foreach (self::$frameworkPaths as $shortPath) {
 			// Create path name
 			//* NOISY-DEBUG: */ printf('[%s:%d]: shortPath=%s' . PHP_EOL, __METHOD__, __LINE__, $shortPath);
-			$pathName = realpath(sprintf(
+			$realPathName = realpath(sprintf(
 				'%s%s%s%s%s',
-				$configInstance->getConfigEntry('application_base_path'),
+				$basePath,
 				DIRECTORY_SEPARATOR,
 				FrameworkBootstrap::getDetectedApplicationName(),
 				DIRECTORY_SEPARATOR,
@@ -278,11 +330,22 @@ final class ClassLoader {
 			));
 
 			// Is the path readable?
-			//* NOISY-DEBUG: */ printf('[%s:%d]: pathName[%s]=%s' . PHP_EOL, __METHOD__, __LINE__, gettype($pathName), $pathName);
-			if (is_dir($pathName)) {
-				// Try to load the application classes
-				$loaderInstance->scanClassPath($pathName);
+			//* NOISY-DEBUG: */ printf('[%s:%d]: realPathName[%s]=%s - AFTER!' . PHP_EOL, __METHOD__, __LINE__, gettype($realPathName), $realPathName);
+			if (!is_string($realPathName)) {
+				// Skip this cone
+				//* NOISY-DEBUG: */ printf('[%s:%d]: realPathName[]=%s - SKIPPED!' . PHP_EOL, __METHOD__, __LINE__, gettype($realPathName));
+				continue;
+			} elseif (!is_dir($realPathName)) {
+				// Is not a directory
+				throw new UnexpectedValueException(sprintf('realPathName=%s is not a directory', $realPathName));
+			} elseif (!is_readable($realPathName)) {
+				// Not readable
+				throw new UnexpectedValueException(sprintf('realPathName=%s cannot be read from', $realPathName));
 			}
+
+			// Try to load the application classes
+			//* NOISY-DEBUG: */ printf('[%s:%d]: Scanning for classes/interfaces at realPathName=%s ...' . PHP_EOL, __METHOD__, __LINE__, $realPathName);
+			$loaderInstance->scanClassPath($realPathName);
 		}
 
 		// Trace message
@@ -293,33 +356,45 @@ final class ClassLoader {
 	 * Scans for test classes, etc.
 	 *
 	 * @return	void
+	 * @throws	UnexpectedValueException	If a given path isn't one or not readable
 	 */
 	public static function scanTestsClasses () {
-		// "Cache" configuration instance
+		// Get loader instance
 		//* NOISY-DEBUG: */ printf('[%s:%d]: CALLED!' . PHP_EOL, __METHOD__, __LINE__);
-		$configInstance = FrameworkBootstrap::getConfigurationInstance();
+		$loaderInstance = self::getSelfInstance();
+
+		// "Cache" root base path
+		$basePath = self::$configInstance->getConfigEntry('root_base_path');
 
 		// Load all classes for the application
+		//* NOISY-DEBUG: */ printf('[%s:%d]: self::testPaths()=%d,basePath=%s' . PHP_EOL, __METHOD__, __LINE__, count(self::$testPaths), $basePath);
 		foreach (self::$testPaths as $shortPath) {
 			// Construct path name
 			//* NOISY-DEBUG: */ printf('[%s:%d]: shortPath=%s' . PHP_EOL, __METHOD__, __LINE__, $shortPath);
-			$pathName = sprintf(
+			$realPathName = realpath(sprintf(
 				'%s%s%s',
-				$configInstance->getConfigEntry('root_base_path'),
+				$basePath,
 				DIRECTORY_SEPARATOR,
 				$shortPath
-			);
-
-			// Try to find it
-			//* NOISY-DEBUG: */ printf('[%s:%d]: pathName[%s]=%s - BEFORE!' . PHP_EOL, __METHOD__, __LINE__, gettype($pathName), $pathName);
-			$realPathName = realpath($pathName);
+			));
 
 			// Is the path readable?
 			//* NOISY-DEBUG: */ printf('[%s:%d]: realPathName[%s]=%s - AFTER!' . PHP_EOL, __METHOD__, __LINE__, gettype($realPathName), $realPathName);
-			if ((is_dir($realPathName)) && (is_readable($realPathName))) {
-				// Try to load the application classes
-				ClassLoader::getSelfInstance()->scanClassPath($realPathName);
+			if (!is_string($realPathName)) {
+				// Skip this cone
+				//* NOISY-DEBUG: */ printf('[%s:%d]: realPathName[]=%s - SKIPPED!' . PHP_EOL, __METHOD__, __LINE__, gettype($realPathName));
+				continue;
+			} elseif (!is_dir($realPathName)) {
+				// Is not a directory
+				throw new UnexpectedValueException(sprintf('realPathName=%s is not a directory', $realPathName));
+			} elseif (!is_readable($realPathName)) {
+				// Not readable
+				throw new UnexpectedValueException(sprintf('realPathName=%s cannot be read from', $realPathName));
 			}
+
+			// Try to load the application classes
+			//* NOISY-DEBUG: */ printf('[%s:%d]: Scanning for classes/interfaces at realPathName=%s ...' . PHP_EOL, __METHOD__, __LINE__, $realPathName);
+			$loaderInstance->scanClassPath($realPathName);
 		}
 
 		// Trace message
@@ -353,7 +428,7 @@ final class ClassLoader {
 		}
 
 		// Get real path from it
-		$fullQualifiedPath = FrameworkBootstrap::getConfigurationInstance()->getConfigEntry('root_base_path') . $relativePath;
+		$fullQualifiedPath = self::$configInstance->getConfigEntry('root_base_path') . $relativePath;
 
 		// Is it there?
 		//* NOISY-DEBUG: */ printf('[%s:%d]: fullQualifiedPath=%s' . PHP_EOL, __METHOD__, __LINE__, $fullQualifiedPath);
@@ -413,13 +488,16 @@ final class ClassLoader {
 	 */
 	public static final function getSelfInstance () {
 		// Is the instance there?
+		//* NOISY-DEBUG: */ printf('[%s:%d]: self::selfInstance[]=%s - CALLED!' . PHP_EOL, __METHOD__, __LINE__, gettype(self::$selfInstance));
 		if (is_null(self::$selfInstance)) {
 			// Get a new one and initialize it
+			//* NOISY-DEBUG: */ printf('[%s:%d]: Initializing class loader ...' . PHP_EOL, __METHOD__, __LINE__);
 			self::$selfInstance = new ClassLoader();
 			self::$selfInstance->initClassLoader();
 		}
 
 		// Return the instance
+		//* NOISY-DEBUG: */ printf('[%s:%d]: self::selfInstance=%s - EXIT!' . PHP_EOL, __METHOD__, __LINE__, get_class(self::$selfInstance));
 		return self::$selfInstance;
 	}
 
@@ -440,7 +518,7 @@ final class ClassLoader {
 	public function getPrintableIncludeList () {
 		// Prepare the list
 		$includeList = '';
-		foreach ($this->loadedClasses as $classFile) {
+		foreach (array_keys($this->loadedClasses) as $classFile) {
 			$includeList .= basename($classFile) . '<br />' . PHP_EOL;
 		}
 
@@ -476,16 +554,13 @@ final class ClassLoader {
 		 * should be used here so is_dir(), is_file() and so on will always
 		 * find the correct files and dirs.
 		 */
-		$basePath2 = realpath($basePath);
+		$basePath = realpath($basePath);
 
 		// If the basePath is false it is invalid
-		//* NOISY-DEBUG: */ printf('[%s:%d] basePath2[%s]=%s' . PHP_EOL, __METHOD__, __LINE__, gettype($basePath2), $basePath2);
-		if ($basePath2 === false) {
+		//* NOISY-DEBUG: */ printf('[%s:%d] basePath[%s]=%s' . PHP_EOL, __METHOD__, __LINE__, gettype($basePath), $basePath);
+		if (!is_string($basePath)) {
 			/* @TODO: Do not exit here. */
 			exit(__METHOD__ . ': Cannot read ' . $basePath . ' !' . PHP_EOL);
-		} else {
-			// Set base path
-			$basePath = $basePath2;
 		}
 
 		// Get a new iterator
@@ -498,9 +573,11 @@ final class ClassLoader {
 			$currentEntry = $iteratorInstance->current();
 
 			// Get filename from iterator which is the class' name (according naming-convention)
+			//* NOISY-DEBUG: */ printf('[%s:%d] currentEntry=%s,currentEntry->size=%d' . PHP_EOL, __METHOD__, __LINE__, $currentEntry->__toString(), $currentEntry->getSize());
 			$fileName = $currentEntry->getFilename();
 
 			// Current entry must be a file, not smaller than 100 bytes and not on ignore list
+			//* NOISY-DEBUG: */ printf('[%s:%d] fileName=%s' . PHP_EOL, __METHOD__, __LINE__, $fileName);
 			if (!$currentEntry->isFile() || isset($this->ignoreList[$fileName]) || $currentEntry->getSize() < 100) {
 				// Advance to next entry
 				$iteratorInstance->next();
@@ -536,25 +613,26 @@ final class ClassLoader {
 	 * @return	void
 	 */
 	private function initClassLoader () {
-		// Construct the FQFN for the cache
-		if (!self::$developerModeEnabled) {
-			// Init cache instances
-			$this->listCacheFile  = new SplFileInfo(FrameworkBootstrap::getConfigurationInstance()->getConfigEntry('local_database_path') . 'list-' . FrameworkBootstrap::getDetectedApplicationName() . '.cache');
-			$this->classCacheFile = new SplFileInfo(FrameworkBootstrap::getConfigurationInstance()->getConfigEntry('local_database_path') . 'class-' . FrameworkBootstrap::getDetectedApplicationName() . '.cache');
-		}
-
 		// Set suffix and prefix from configuration
-		$this->suffix = FrameworkBootstrap::getConfigurationInstance()->getConfigEntry('class_suffix');
-		$this->prefix = FrameworkBootstrap::getConfigurationInstance()->getConfigEntry('class_prefix');
+		//* NOISY-DEBUG: */ printf('[%s:%d]: CALLED!' . PHP_EOL, __METHOD__, __LINE__);
+		$this->suffix = self::$configInstance->getConfigEntry('class_suffix');
+		$this->prefix = self::$configInstance->getConfigEntry('class_prefix');
 
 		// Set own instance
+		//* NOISY-DEBUG: */ printf('[%s:%d]: this->suffix=%s,this->prefix=%s' . PHP_EOL, __METHOD__, __LINE__, $this->suffix, $this->prefix);
 		self::$selfInstance = $this;
 
 		// Skip here if no dev-mode
+		//* NOISY-DEBUG: */ printf('[%s:%d]: self::developerModeEnabled=%d' . PHP_EOL, __METHOD__, __LINE__, intval(self::$developerModeEnabled));
 		if (self::$developerModeEnabled) {
 			return;
 		}
 
+		// Init cache instances
+		//* NOISY-DEBUG: */ printf('[%s:%d]: Initializing cache file instances ...' . PHP_EOL, __METHOD__, __LINE__);
+		$this->listCacheFile  = new SplFileInfo(self::$configInstance->getConfigEntry('local_database_path') . 'list-' . FrameworkBootstrap::getDetectedApplicationName() . '.cache');
+		$this->classCacheFile = new SplFileInfo(self::$configInstance->getConfigEntry('local_database_path') . 'class-' . FrameworkBootstrap::getDetectedApplicationName() . '.cache');
+
 		// Is the cache there?
 		if (FrameworkBootstrap::isReadableFile($this->listCacheFile)) {
 			// Load and convert it
@@ -572,6 +650,9 @@ final class ClassLoader {
 			// Mark the class cache as loaded
 			$this->classesCached = true;
 		}
+
+		// Trace message
+		//* NOISY-DEBUG: */ printf('[%s:%d]: EXIT!' . PHP_EOL, __METHOD__, __LINE__);
 	}
 
 	/**
@@ -595,6 +676,7 @@ final class ClassLoader {
 		$fileName = sprintf('%s%s%s', $this->prefix, $shortClassName, $this->suffix);
 
 		// Now look it up in our index
+		//* DEBUG-DIE: */ die(sprintf('[%s:%d]: this->pendingFiles=%s', __METHOD__, __LINE__, print_r($this->pendingFiles, TRUE)));
 		//* NOISY-DEBUG: */ printf('[%s:%d] ISSET: fileName=%s' . PHP_EOL, __METHOD__, __LINE__, $fileName);
 		if ((isset($this->pendingFiles[$fileName])) && (!isset($this->loadedClasses[$this->pendingFiles[$fileName]->getPathname()]))) {
 			// File is found and not loaded so load it only once
@@ -606,18 +688,21 @@ final class ClassLoader {
 			$this->total++;
 
 			// Mark this class as loaded for other purposes than loading it.
+			//* NOISY-DEBUG: */ printf('[%s:%d] LOAD: fileName=%s marked as loaded ...' . PHP_EOL, __METHOD__, __LINE__, $fileName);
 			$this->loadedClasses[$this->pendingFiles[$fileName]->getPathname()] = true;
 
-			// Remove it from classes list so it won't be found twice.
-			//* NOISY-DEBUG: */ printf('[%s:%d] UNSET: fileName=%s' . PHP_EOL, __METHOD__, __LINE__, $fileName);
-			unset($this->pendingFiles[$fileName]);
-
 			// Developer mode excludes caching (better debugging)
+			//* NOISY-DEBUG: */ printf('[%s:%d] self::developerModeEnabled=%d' . PHP_EOL, __METHOD__, __LINE__, intval(self::$developerModeEnabled));
 			if (!self::$developerModeEnabled) {
-				// Reset cache
-				//* NOISY-DEBUG: */ printf('[%s:%d] classesCached=false' . PHP_EOL, __METHOD__, __LINE__);
+				// Reset cache and mark file for flushing
+				//* NOISY-DEBUG: */ printf('[%s:%d] Setting this->classesCached=false ...' . PHP_EOL, __METHOD__, __LINE__);
 				$this->classesCached = false;
+				$this->flushCache[$fileName] = $this->pendingFiles[$fileName];
 			}
+
+			// Remove it from classes list so it won't be found twice.
+			//* NOISY-DEBUG: */ printf('[%s:%d] UNSET: fileName=%s' . PHP_EOL, __METHOD__, __LINE__, $fileName);
+			unset($this->pendingFiles[$fileName]);
 		} else {
 			// Not found
 			//* NOISY-DEBUG: */ printf('[%s:%d] 404: fileName=%s' . PHP_EOL, __METHOD__, __LINE__, $fileName);
diff --git a/framework/main/classes/class_BaseFrameworkSystem.php b/framework/main/classes/class_BaseFrameworkSystem.php
index 822debf9..e7cd1955 100644
--- a/framework/main/classes/class_BaseFrameworkSystem.php
+++ b/framework/main/classes/class_BaseFrameworkSystem.php
@@ -828,7 +828,7 @@ Loaded includes:
 		if ($this->isFieldSet($fieldName)) {
 			// Get it
 			$fieldValue = $fieldArray[$fieldName2];
-		} elseif (FrameworkBootstrap::getConfigurationInstance()->getConfigEntry('developer_mode_enabled')) {
+		} elseif (FrameworkBootstrap::getConfigurationInstance()->isEnabled('developer_mode')) {
 			// Missing field entry, may require debugging
 			self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-FRAMEWORK-SYSTEM: fieldArray<pre>=' . print_r($fieldArray, true) . '</pre>,fieldName=' . $fieldName . ' not found!');
 		} else {
@@ -887,7 +887,7 @@ Loaded includes:
 	 */
 	public function deprecationWarning (string $message) {
 		// Is developer mode active?
-		if (FrameworkBootstrap::getConfigurationInstance()->getConfigEntry('developer_mode_enabled')) {
+		if (FrameworkBootstrap::getConfigurationInstance()->isEnabled('developer_mode')) {
 			// Debug instance is there?
 			if (!is_null($this->getDebugInstance())) {
 				// Output stub message
-- 
2.39.5