Attributes
1Presentation
Temma offers optional PHP attributes to control access to controllers and actions.
These attributes can be added together, so you can add several different attributes (and sometimes the same attribute several times, with different parameters) to the same controller or action.
More, you can create your own attributes to manage access to controllers and actions.
Attributes provided by Temma
Temma provides several attributes, which documentation is available in the "Helpers" sections:
- Auth: To restrict access to authenticated users.
- Check: To validate input data (URL/GET/POST parameters, payload, files).
- View: To manage controller and action views.
- Template: To define the path to the template file.
- Method: To manage the authorized HTTP methods.
- Referer: To filter access by HTTP REFERER.
- Redirect: To redirect requests automatically
2Write your own attributes
You can create your own attributes to manage access to controllers and actions.
In Temma, attributes are active: the framework reacts to their presence; it executes the attributes,
provides them with an API, and the attributes themselves control the framework’s behavior.
Compared to other frameworks, this makes Temma simpler. New attributes can be added without requiring any changes to the framework core.
2.1Principle
Your attributes must extend the \Temma\Web\Attribute class and can only be applied to controllers and actions.
An attribute must define a constructor, which may receive the parameters required by the attribute.
The constructor must not perform any logic and should only store the received parameters.
The actual processing of the attribute must be implemented in an apply() method,
which receives as its parameter an object implementing the
Reflector interface,
indicating the context in which the attribute is executed. This can be either a
ReflectionClass object (at the controller level)
or a ReflectionMethod object (at the action level).
Through inheritance, your attributes have access to features that are largely similar to those available to controllers:
-
Access to template variables via the hooked notion.
For example: $this['var'] = 'value'; to define a variable, and $var = $this['var']; to read the value of a variable. -
Access to data sources in the form of direct object properties.
For example: $this->db to access a database named db. -
Methods $this->_httpCode() and $this->_httpError()
to define the HTTP return code, or HTTP error code.
Methods $this->_getHttpCode() and $this->_getHttpError() to retrieve the HTTP code previously defined. - Methods $this->_redirect() and $this->_redirect301() to define redirection commands.
- Methods $this->_view() to define the view, $this->_template() to define the template, and $this->_templatePrefix() to define the template prefix.
In addition, properties are used to access Temma's internal objects:
- $this->_loader: instance of the dependency injection component.
- $this->_session: instance of the session management object.
- $this->_config: instance of the configuration access object.
- $this->_request: instance of the request management object..
- $this->_response: instance of the response management object.
All these elements make it possible to manipulate the execution flow in the same way as plugins.
2.2Execution flow
To modify the flow of execution, an attribute must raise a specific exception:
- \Temma\Exceptions\FlowHalt: Stops the flow of execution. No other plugins or controllers will be executed, and the framework moves straight on to processing the view or redirection.
- \Temma\Exceptions\FlowRestart: Restarts processing of the current phase (pre-plugins, controller or post-plugins).
- \Temma\Exceptions\FlowReboot: Restarts the entire processing chain (pre-plugins + controller + post-plugins).
- \Temma\ExceptionsFlowQuit: Stops execution of the framework. No further plugins or controllers will be executed. The view will not be executed and redirection requests are ignored.
2.3Example
Here is an example of an attribute named MyLog, which writes to a file just before a controller is instantiated or an action is executed. The name of the object or method is written, along with the file name and the line number.
<?php
use \Temma\Base\Log as TµLog;
/**
* Attribute used to write the execution flow of
* controllers and actions to a log.
*/
#[\Attribute(\Attribute::TARGET_CLASS | \Attribute::TARGET_METHOD)]
class MyLog extends \Temma\Web\Attribute {
/**
* Constructor.
* @param string $message (optional) Message to append to the log line.
*/
public function __construct(private ?string $message=null) {
}
/**
* Attribute execution.
* @param \Reflector $context Execution context (class or method).
*/
public function apply(\Reflector $context) : void {
// retrieve information
$name = $context->getName();
$file = $context->getFileName();
$line = $context->getStartLine();
// determine context type
if ($context instanceof \ReflectionClass) {
$type = 'Controller';
// $name already contains the full class name
} elseif ($context instanceof \ReflectionMethod) {
$type = 'Action';
// $name contains the method name, prepend the class name
$name = $context->getDeclaringClass()->getName() . '::' . $name;
} else {
return;
}
// build the log string
$logString = "[$type] $name ($file:$line)";
if ($this->message)
$logString .= ' : ' . $this->message;
// write to the log
TµLog::l($logString);
}
}
- Line 9 : The object is declared as an attribute that can be applied to classes and methods.
- Line 10 : Definition of the object, which extends \Temma\Web\Attribute.
- Line 15 : Attribute constructor, which receives a parameter promoted to a private property.
- Line 22 : Execution method, which receives the execution context as a parameter.
- Lines 23 to 38 : Retrieval of the information required to build the log message.
- Lines 40 to 43 : Construction of the log message.
- Line 46 : Writing the string using the \Temma\Base\Log object.
And here is an example of how this attribute can be used:
<?php
/** Controller. */
#[MyLog]
class Article extends \Temma\Web\Controller {
/** Action displaying the list of articles. */
#[MyLog('Article list')]
public function list() {
// ...
}
/**
* Action displaying an article.
* @param int $id Article identifier.
*/
#[MyLog('Display article')]
pulic function view(int $id) {
// ...
}
}
-
Line 4 : The MyLog attribute is applied to the controller.
This will add the following line to the log: [Controller] Article (Article.php:4) -
Line 7 : The attribute is applied to the list() action.
This will add the following line to the log: [Action] Article::list (Article.php:7) : Article list -
Line 16 : The attribute is applied to the view() action.
This will add the following line to the log: [Action] Article::view (Article.php:16) : Display article