From 0b0375d2d9a22fdca1298709722e2a2db5abd3a9 Mon Sep 17 00:00:00 2001
From: =?utf8?q?Roland=20H=C3=A4der?= <roland@mxchange.org>
Date: Mon, 27 Feb 2023 13:18:44 +0100
Subject: [PATCH] Continued: - added more checks on parameter - added more
 debug lines

---
 .../controller/class_BaseController.php       | 125 +++++++++++++++---
 .../class_InvalidFilterChainException.php     |  51 +------
 ...lass_TestsConsoleDefaultNewsController.php |   2 +-
 3 files changed, 105 insertions(+), 73 deletions(-)

diff --git a/framework/main/classes/controller/class_BaseController.php b/framework/main/classes/controller/class_BaseController.php
index 2535df01..421ba3b2 100644
--- a/framework/main/classes/controller/class_BaseController.php
+++ b/framework/main/classes/controller/class_BaseController.php
@@ -3,9 +3,9 @@
 namespace Org\Mxchange\CoreFramework\Controller;
 
 // Import framework stuff
-use Org\Mxchange\CoreFramework\Chain\Filter\InvalidFilterChainException;
 use Org\Mxchange\CoreFramework\Factory\Object\ObjectFactory;
 use Org\Mxchange\CoreFramework\Filter\Filterable;
+use Org\Mxchange\CoreFramework\Generic\FrameworkInterface;
 use Org\Mxchange\CoreFramework\Object\BaseFrameworkSystem;
 use Org\Mxchange\CoreFramework\Registry\Object\ObjectRegistry;
 use Org\Mxchange\CoreFramework\Registry\Registerable;
@@ -13,6 +13,10 @@ use Org\Mxchange\CoreFramework\Request\Requestable;
 use Org\Mxchange\CoreFramework\Response\Responseable;
 use Org\Mxchange\CoreFramework\Traits\Resolver\ResolverTrait;
 
+// Import SPL stuff
+use \BadMethodCallException;
+use \InvalidArgumentException;
+
 /**
  * A generic controller class. You should extend this base class if you want to
  * write your own controller. You get the advantage that you can use the pre and
@@ -47,6 +51,7 @@ abstract class BaseController extends BaseFrameworkSystem implements Registerabl
 	// Names of controller's own filter chains
 	const FILTER_CHAIN_PRE_COMMAND  = 'controller_pre_command';
 	const FILTER_CHAIN_POST_COMMAND = 'controller_post_command';
+	const FILTER_CHAIN_SHUTDOWN     = 'shutdown';
 
 	/**
 	 * Generic filter chains
@@ -61,14 +66,23 @@ abstract class BaseController extends BaseFrameworkSystem implements Registerabl
 	 */
 	protected function __construct (string $className) {
 		// Call parent constructor
+		//* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-CONTROLLER: className=%s - CONSTRUCTED!', $className));
 		parent::__construct($className);
 
 		// Initialize both filter chains
-		$this->initFilterChain(self::FILTER_CHAIN_PRE_COMMAND);
-		$this->initFilterChain(self::FILTER_CHAIN_POST_COMMAND);
+		//* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage('BASE-CONTROLLER: Initializing filter chains ...');
+		foreach([self::FILTER_CHAIN_PRE_COMMAND, self::FILTER_CHAIN_POST_COMMAND] as $filterChain) {
+			// Init it
+			//* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-CONTROLLER: Invoking this->initFilterChain(=%s) ...', $filterChain));
+			$this->initFilterChain($filterChain);
+		}
 
 		// Add this controller to the registry
+		//* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('BASE-CONTROLLER: Registering this=%s ...', $this->__toString()));
 		ObjectRegistry::getRegistry('generic')->addInstance('controller', $this);
+
+		// Trace message
+		//* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-CONTROLLER: EXIT!');
 	}
 
 	/**
@@ -80,6 +94,7 @@ abstract class BaseController extends BaseFrameworkSystem implements Registerabl
 	 */
 	public function executeGenericPrePostCommand (Requestable $requestInstance, Responseable $responseInstance) {
 		// Get the command instance from the resolver by sending a request instance to the resolver
+		//* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-CONTROLLER: requestInstance=%s,responseInstance=%s - CALLED!', $requestInstance->__toString(), $responseInstance->__toString()));
 		$commandInstance = $this->getResolverInstance()->resolveCommandByRequest($requestInstance);
 
 		// Add more filters by the command
@@ -99,6 +114,9 @@ abstract class BaseController extends BaseFrameworkSystem implements Registerabl
 
 		// Flush the response out
 		$responseInstance->flushBuffer();
+
+		// Trace message
+		//* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-CONTROLLER: EXIT!');
 	}
 
 	/**
@@ -111,6 +129,7 @@ abstract class BaseController extends BaseFrameworkSystem implements Registerabl
 	 */
 	public function genericHanleRequestLoginFailedRedirect (Requestable $requestInstance, Responseable $responseInstance) {
 		// Get the "form action"
+		//* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-CONTROLLER: requestInstance=%s,responseInstance=%s - CALLED!', $requestInstance->__toString(), $responseInstance->__toString()));
 		$formAction = $requestInstance->getRequestElement('form');
 
 		// Get command instance from resolver
@@ -128,7 +147,7 @@ abstract class BaseController extends BaseFrameworkSystem implements Registerabl
 			$responseInstance->redirectToConfiguredUrl('login_failed');
 
 			// Exit here
-			exit();
+			exit;
 		}
 
 		/*
@@ -145,6 +164,9 @@ abstract class BaseController extends BaseFrameworkSystem implements Registerabl
 
 		// Flush the buffer out
 		$responseInstance->flushBuffer();
+
+		// Trace message
+		//* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-CONTROLLER: EXIT!');
 	}
 
 	/**
@@ -157,6 +179,7 @@ abstract class BaseController extends BaseFrameworkSystem implements Registerabl
 	 */
 	public function genericHanleRequestLoginAreaFailedRedirect (Requestable $requestInstance, Responseable $responseInstance) {
 		// Get the command instance from the resolver by sending a request instance to the resolver
+		//* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-CONTROLLER: requestInstance=%s,responseInstance=%s - CALLED!', $requestInstance->__toString(), $responseInstance->__toString()));
 		$commandInstance = $this->getResolverInstance()->resolveCommandByRequest($requestInstance);
 
 		// Add more filters by the command
@@ -171,7 +194,7 @@ abstract class BaseController extends BaseFrameworkSystem implements Registerabl
 			$responseInstance->redirectToConfiguredUrl('login_failed');
 
 			// Exit here
-			exit();
+			exit;
 		}
 
 		// This request was valid! :-D
@@ -185,6 +208,9 @@ abstract class BaseController extends BaseFrameworkSystem implements Registerabl
 
 		// Flush the response out
 		$responseInstance->flushBuffer();
+
+		// Trace message
+		//* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-CONTROLLER: EXIT!');
 	}
 
 	/**
@@ -192,11 +218,26 @@ abstract class BaseController extends BaseFrameworkSystem implements Registerabl
 	 *
 	 * @param	$filterChain	Name of the filter chain
 	 * @return	void
+	 * @throws	InvalidArgumentException	If a parameter has an invalid value
+	 * @throws	BadMethodCallException	If the given filter chain is already initialized
 	 */
 	protected function initFilterChain (string $filterChain) {
-		//* DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('CONTROLLER: ' . $filterChain . ' init: START');
+		// Check parameter
+		//* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-CONTROLLER: filterChain=%s - CALLED!', $filterChain));
+		if (empty($filterChain)) {
+			// Throw IAE
+			throw new InvalidArgumentException('Parameter "filterChain" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
+		} elseif (isset($this->filterChains[$filterChain])) {
+			// Throw BMCE
+			throw new BadMethodCallException(sprintf('filterChain=%s is already initialized', $filterChain), FrameworkInterface::EXCEPTION_BAD_METHOD_CALL);
+		}
+
+		// Initialize filter chain
+		//* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('BASE-CONTROLLER: Initializing filterChain=%s ...', $filterChain));
 		$this->filterChains[$filterChain] = ObjectFactory::createObjectByConfiguredName('filter_chain_class');
-		//* DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('CONTROLLER: ' . $filterChain . ' init: FINISHED');
+
+		// Trace message
+		//* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-CONTROLLER: EXIT!');
 	}
 
 	/**
@@ -205,20 +246,26 @@ abstract class BaseController extends BaseFrameworkSystem implements Registerabl
 	 * @param	$filterChain	Chain of the filter
 	 * @param	$filterInstance		An instance of a filter
 	 * @return	void
-	 * @throws	InvalidFilterChainException	If the filter chain is invalid
+	 * @throws	InvalidArgumentException	If a parameter has an invalid value
+	 * @throws	BadMethodCallException	If the given filter chain is not yet initialized
 	 */
 	protected function addFilter (string $filterChain, Filterable $filterInstance) {
-		//* DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('CONTROLLER: ' . $filterChain . ',' . $filterInstance->__toString(). ' add: START');
-
-		// Test if the filter is there
-		if (!isset($this->filterChains[$filterChain])) {
-			// Throw an exception here
-			throw new InvalidFilterChainException(array($this, $filterChain), self::EXCEPTION_FILTER_CHAIN_INVALID);
+		// Check parameter
+		//* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-CONTROLLER: filterChain=%s,filterInstance=%s - CALLED!', $filterChain, $filterInstance->__toString()));
+		if (empty($filterChain)) {
+			// Throw IAE
+			throw new InvalidArgumentException('Parameter "filterChain" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
+		} elseif (!isset($this->filterChains[$filterChain])) {
+			// Throw IAE
+			throw new BadMethodCallException(sprintf('filterChain=%s is not a valid chain', $filterChain), FrameworkInterface::EXCEPTION_BAD_METHOD_CALL);
 		}
 
 		// Add the filter
+		//* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('BASE-CONTROLLER: Adding filterInstance=%s to filterChain=%s ...', $filterInstance->__toString(), $filterChain));
 		$this->filterChains[$filterChain]->addFilter($filterInstance);
-		//* DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('CONTROLLER: ' . $filterChain . ',' . $filterInstance->__toString(). ' add: FINISH');
+
+		// Trace message
+		//* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-CONTROLLER: EXIT!');
 	}
 
 	/**
@@ -229,7 +276,11 @@ abstract class BaseController extends BaseFrameworkSystem implements Registerabl
 	 */
 	public function addPreFilter (Filterable $filterInstance) {
 		// Add the pre filter
+		//* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-CONTROLLER: filterInstance=%s - CALLED!', $filterInstance->__toString()));
 		$this->addFilter(self::FILTER_CHAIN_PRE_COMMAND, $filterInstance);
+
+		// Trace message
+		//* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-CONTROLLER: EXIT!');
 	}
 
 	/**
@@ -239,8 +290,12 @@ abstract class BaseController extends BaseFrameworkSystem implements Registerabl
 	 * @return	void
 	 */
 	public function addPostFilter (Filterable $filterInstance) {
-		// Add the post filter
+		// Add post filter
+		//* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-CONTROLLER: filterInstance=%s - CALLED!', $filterInstance->__toString()));
 		$this->addFilter(self::FILTER_CHAIN_POST_COMMAND, $filterInstance);
+
+		// Trace message
+		//* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-CONTROLLER: EXIT!');
 	}
 
 	/**
@@ -250,7 +305,12 @@ abstract class BaseController extends BaseFrameworkSystem implements Registerabl
 	 * @return	void
 	 */
 	public function addShutdownFilter (Filterable $filterInstance) {
-		$this->addFilter('shutdown', $filterInstance);
+		// Add shutdown filter
+		//* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-CONTROLLER: filterInstance=%s - CALLED!', $filterInstance->__toString()));
+		$this->addFilter(self::FILTER_CHAIN_SHUTDOWN, $filterInstance);
+
+		// Trace message
+		//* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-CONTROLLER: EXIT!');
 	}
 
 	/**
@@ -260,17 +320,25 @@ abstract class BaseController extends BaseFrameworkSystem implements Registerabl
 	 * @param	$requestInstance	An instance of a Requestable class
 	 * @param	$responseInstance	An instance of a Responseable class
 	 * @return	void
-	 * @throws	InvalidFilterChainException	If the filter chain is invalid
+	 * @throws	InvalidArgumentException	If the filter chain is invalid
 	 */
 	protected function executeFilters (string $filterChain, Requestable $requestInstance, Responseable $responseInstance) {
-		// Test if the filter is there
-		if (!isset($this->filterChains[$filterChain])) {
+		// Check parameter
+		//* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-CONTROLLER: filterChain=%s,requestInstance=%s,responseInstance=%s - CALLED!', $filterChain, $requestInstance->__toString(), $responseInstance->__toString()));
+		if (empty($filterChain)) {
+			// Throw IAE
+			throw new InvalidArgumentException('Parameter "filterChain" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
+		} elseif (!isset($this->filterChains[$filterChain])) {
 			// Throw an exception here
-			throw new InvalidFilterChainException(array($this, $filterChain), self::EXCEPTION_FILTER_CHAIN_INVALID);
+			throw new BadMethodCallException(sprintf('filterChain=%s is not a valid chain', $filterChain), FrameworkInterface::EXCEPTION_BAD_METHOD_CALL);
 		}
 
 		// Run all filters
+		//* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('BASE-CONTROLLER: Processing filterChain=%s...', $filterChain));
 		$this->filterChains[$filterChain]->processFilters($requestInstance, $responseInstance);
+
+		// Trace message
+		//* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-CONTROLLER: EXIT!');
 	}
 
 	/**
@@ -282,7 +350,11 @@ abstract class BaseController extends BaseFrameworkSystem implements Registerabl
 	 */
 	protected function executePreFilters (Requestable $requestInstance, Responseable $responseInstance) {
 		// Execute all pre filters
+		//* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-CONTROLLER: requestInstance=%s,responseInstance=%s - CALLED!', $requestInstance->__toString(), $responseInstance->__toString()));
 		$this->executeFilters(self::FILTER_CHAIN_PRE_COMMAND, $requestInstance, $responseInstance);
+
+		// Trace message
+		//* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-CONTROLLER: EXIT!');
 	}
 
 	/**
@@ -294,7 +366,11 @@ abstract class BaseController extends BaseFrameworkSystem implements Registerabl
 	 */
 	protected function executePostFilters (Requestable $requestInstance, Responseable $responseInstance) {
 		// Execute all post filters
+		//* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-CONTROLLER: requestInstance=%s,responseInstance=%s - CALLED!', $requestInstance->__toString(), $responseInstance->__toString()));
 		$this->executeFilters(self::FILTER_CHAIN_POST_COMMAND, $requestInstance, $responseInstance);
+
+		// Trace message
+		//* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-CONTROLLER: EXIT!');
 	}
 
 	/**
@@ -305,7 +381,12 @@ abstract class BaseController extends BaseFrameworkSystem implements Registerabl
 	 * @return	void
 	 */
 	public function executeShutdownFilters (Requestable $requestInstance, Responseable $responseInstance) {
-		$this->executeFilters('shutdown', $requestInstance, $responseInstance);
+		// Execute all shutdown filter
+		//* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-CONTROLLER: requestInstance=%s,responseInstance=%s - CALLED!', $requestInstance->__toString(), $responseInstance->__toString()));
+		$this->executeFilters(self::FILTER_CHAIN_SHUTDOWN, $requestInstance, $responseInstance);
+
+		// Trace message
+		//* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-CONTROLLER: EXIT!');
 	}
 
 }
diff --git a/framework/main/exceptions/filter/class_InvalidFilterChainException.php b/framework/main/exceptions/filter/class_InvalidFilterChainException.php
index aadc2455..7d6dceec 100644
--- a/framework/main/exceptions/filter/class_InvalidFilterChainException.php
+++ b/framework/main/exceptions/filter/class_InvalidFilterChainException.php
@@ -1,51 +1,2 @@
 <?php
-// Own namespace
-namespace Org\Mxchange\CoreFramework\Chain\Filter;
-
-// Import framework stuff
-use Org\Mxchange\CoreFramework\Generic\FrameworkException;
-
-/**
- * An exception thrown in a filter chain to stop processing further filters
- *
- * @author		Roland Haeder <webmaster@shipsimu.org>
- * @version		0.0.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
- * @deprecated	Don't use this anymore
- *
- * This program 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.
- *
- * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
- */
-class InvalidFilterChainException extends FrameworkException {
-	/**
-	 * The super constructor for all exceptions
-	 *
-	 * @param	$filterInstance		Instance of a filter class
-	 * @param	$code				Exception code for better debugging
-	 * @return	void
-	 */
-	public function __construct (array $filterArray, int $code) {
-		// Construct the message
-		$message = sprintf('[%s:%d] Filter chain %s is not initialized.',
-			$filterArray[0]->__toString(),
-			$this->getLine(),
-			$filterArray[1]
-		);
-
-		// Call the parent exception
-		parent::__construct($message, $code);
-	}
-
-}
+// @DEPRECATED
diff --git a/framework/main/tests/controller/console/class_TestsConsoleDefaultNewsController.php b/framework/main/tests/controller/console/class_TestsConsoleDefaultNewsController.php
index e7b9a654..589c80d5 100644
--- a/framework/main/tests/controller/console/class_TestsConsoleDefaultNewsController.php
+++ b/framework/main/tests/controller/console/class_TestsConsoleDefaultNewsController.php
@@ -45,7 +45,7 @@ class TestsConsoleDefaultNewsController extends BaseController implements Contro
 		parent::__construct(__CLASS__);
 
 		// Init additional filter chains
-		foreach (['bootstrap', 'tests', 'shutdown'] as $filterChain) {
+		foreach (['bootstrap', 'tests', BaseController::FILTER_CHAIN_SHUTDOWN] as $filterChain) {
 			self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('TEST-CONSOLE-DEFAULT-NEWS-CONTROLLER: Initializing filterChain=%s ...', $filterChain));
 			$this->initFilterChain($filterChain);
 		}
-- 
2.39.5