Unit

Abstract class BlackFox\Unit it is an environment for creating controllers.

The descendant class is located in a file and folder of the same name, and also contains a sub-folder 'views', which contains views.
Any public method may be an action, and the parameters to them are formed from the user's request.
You can run multiple actions. It is possible to disable the inclusion of template+view. It is possible to inherit units from each other, while the templates+views are also inherited.
Defaults: action name is Default, view name is Default (is gonna include file 'Default.php').

Properties

Name Type Description
$ENGINE object reference to instance of BlackFox\Engine
$USER object reference to instance of BlackFox\User
$options array dictionary of dictionaries, describing possible parameters
$parents array the ancestors of the unit
$class string current class name
$view string current view (file name without extension)
$REQUEST array user request generated by method GetRequest()
$PARAMS array call parameters
$RESULT array combined result of work of all actions that has been invoked
$ALERTS array messages, warnings and errors encountered during operation
$unit_absolute_folder string absolute path to unit folder
$unit_relative_folder string relative path to unit folder
$view_absolute_folder string absolute path to template folder
$view_relative_folder string relative path to template folder

Actions

Action is a public method of the unit.
Unit consistently starts the action, forming parameters from the user query, which is generated by the GetRequest() method. If the action has a parameter without a default value and the user has not specified that value — unit throws an exception.

The sequence of performed actions (in the form of a list of lines) is formed in the method GetActions($request) as a simple array (list) of strings.

It is desirable to override this method, otherwise it will work by default as follows:

  • if the user specified the 'action' or 'ACTION' key in the request — this action will be added to the list of performed actions
  • if the user has specified the 'view' or 'VIEW' key in the request, this action will be added to the list of performed actions, otherwise 'Default' action will be added to the list.

There are three ways to complete the action:

  • to return an array or string or null
  • to throw an exception
  • to use the Redirect() method

There are two types of actions: preliminary actions and final action. Last element of the list of actions (from method GetActions($request)) becomes final action, everyone else — becomes preliminary actions.

namespace Example;
class UnitNames extends \BlackFox\Unit {

	public function GetActions(array $request = []) {
		if ($request['ACTION'] == 'Rename') {
			return ['Rename', 'Default'];
		}
		return ['Default'];
	}

	// $page = $_REQUEST['page'] ?: 1
	public function Default($page = 1) {
		if ($page < 1) {
			throw new \BlackFox\Exception("page must be positive");
		}
		$RESULT['ELEMENTS'] = Names::I()->Select(['PAGE' => $page]);
		return $RESULT;
	}

	// $ID = $_REQUEST['ID']
	// $new_name = $_REQUEST['new_name']
	public function Rename($ID, $new_name) {
		if (!is_numeric($ID)) {
			throw new \BlackFox\Exception("id must be numeric");
		}
		Names::I()->Update($ID, ['NAME' => $new_name]);
		$this->Redirect(null, "Rename successful");
	}

}

Preliminary actions

  • may attempt to change the internal state of the model
  • may prepare additional data for display
  • in case of success:
    • if response is a string — aggregates it into $ALERTS
    • otherwise — converts the response to an array and aggregates it into a $RESULT
  • in case of exception — catches an exception and aggregates it into $ALERTS (through the Error method)
  • in case of redirect — stops execution

Final action

  • should not attempt to change the internal state of the model
  • prepares main data for display
  • in case of success — converts the response to an array and aggregates it into a $RESULT
  • in case of exception — does not catch the exception, allowing it to pop up to a level above
  • in case of redirect — stops execution

Methods

Name Parameters Description
Run $params = [], $request = [] Static method that starts the unit, used on virtual root pages. It handles any exceptions by calling method ShowErrors of the Engine.
Execute $params = [], $request = [] Executes unit, no exception handling
Init $params = [] Initializes unit parameters by comparing them against $options
GetRequest array $request = [] Glues the passed parameter and super-global arrays $_REQUEST and $_FILES into a single array,
correcting the structure of the super-global array $_FILES
may be overridden
GetActions array $request = [] Returns a list of actions to run should be overridden
Controller array $request = [] Sequentially runs preliminary actions, then final action, collecting responses and exceptions into $RESULT and $ALERTS properties.
Invoke $method, $request Attempts to start the action by substituting the user request part into its parameters
Error $Exception, $action = null, $request = [] Handles exceptions that occur during pre-action operations: puts them in an array $ALERTS may be overridden
ShowAlerts Displays the $ALERTS array as HTML may be overridden
Redirect $url, array|string $alerts Redirects to another URL, saving alerts into users session

Connecting with template+view

If there are no exceptions or errors as a result of the final action, and property $view is not empty, the unit takes the result and connects it to the corresponding view as a $RESULT variable.
By default, before performing any actions, the Controller method sets the $view property equal to the name of the final action. If you find out during the action that you want to connect a different view, change the property $view.

Inheritance of templates+views

If it is necessary to connect the template+view, at first, unit looks for it in its own folder: 'views/$view.php', then it searches up the template folders of his parents. This search occurs in the Path($path) method. If you use it in your own view to connect sub-views, this will allow successor units to override your sub-views.

.../UnitExample/views/default.php
/**@var \BlackFox\Unit $this */
/**@var array $RESULT */
foreach ($RESULT as $element) {
	// usual way, successors can't override 'element' view
	require 'element.php';
	// better way, successor may override 'element' view 
	require($this->Path('element.php'));
}

The GetParentView() method returns the absolute path to the same view of the parent unit. It allows you to supplement view of the parent unit instead of completely redefine it.

.../UnitExample/views/element.php
/**@var \BlackFox\Unit $this */
/**@var array $element */
?>
<div class="i_want_to_wrap_element">
	<h3><?= $element['NAME'] ?></h3>
	<? require($this->GetParentView()); ?>
</div>
Ask question