Actions

This document assumes you’ve installed hiraeth/bootstrap or a combination of hiraeth/diactoros, hiraeth/fastroute, and hiraeth/actions. If you haven’t your mileage may vary. See the installation docs for more information.

Actions are PHP classes which handle incoming web requests. Their primary responsibility is mapping incoming requests data to your domain level services, models, repositories, etc, and then returning a result.

The only requirement of an action is that it implements the __invoke() method to perform the operations for which it is responsible. One of the simplest examples of a valid action would, therefore, be the following:

class HelloWorld
{
	public function __invoke()
	{
		return 'Hello World';
	}
}

The suggested directory for actions is local/actions. Once you’ve added your action, regenerate autoloading:

composer dump-autoload

Creating From Abstract Action

While the example above is valid, it’s not very practical because we don’t have any access to the data or tools we need to really analyze our request or generate an appropriate response. While it’s possible to add a __construct() method and get what we need injected, hiraeth/bootstrap{: .package]} provided an abstract action implementation that will cover most of the basics.

To make use of this functionality out of the box, simply make sure your action extends AbstractAction:

class MyCustomAction extends AbstractAction
{
	...
}

The AbstractAction name is an alias, by default, to Hiraeth\Actions\AbstractAction. You can use this alias to avoid more complex namespacing, however, because the alias is only regsitered if the class does not already exist, it allows you to easily add functionality to the abstract action implementation later by simply creating your own real AbstractAction.

Accessing Request Information

Once you have extended the AbstractAction, it’s now possible to easily access the PSR-7 server request object that represents the incoming client request via $this->request:

public function __invoke()
{
	if ($this->request->getMethod() == 'POST') {
		...
	}
}

For a full list of available methods, their arguments, and returned data types available on the request object, see the PSR-7 server request interface documentation.

Accessing Request Data

It is 100% possible to access all request data via the server request object through standard PSR-7 interfaces. Depending on the complexity of the incoming data, this may actually be necessary at time to distinguish between query parameters, post data, files, etc. However, more common is the need to have this information easily combined together and/or to get default values if it hasn’t been sent.

Hiraeth’s AbstractAction provides two methods for easily accomplishing these tasks.

Checking If Data Exists

If you need to check if a parameter has been sent (regardless of via query parameter, request body, or custom attributes), you can use the has() method:

if ($this->has('file')) {
	...
}

Getting Data

To get the data by name, you can use the get() method in very much the same way.

$this->get('file')

In addition to being able to get data that has been sent, you can also provide a default in the event it hasn’t. This is common, for example, in the case of pagination, where you likely want to default to a value of 1 if a specific page has not been requested:

$this->get('page', 1)

Returning Data

Hiraeth does not require actions to return a particular object or type of data. Rather, it uses a system of responders which are registered in the configuration and which, in turn will be matched against your action’s return value to convert it into a proper response. That said, the Hiraeth\Actions\AbstractAction provides a number of helpers to create the most common return types.

Basic Responses

return $this->response(404);

Redirects (With Parameters)

return $this->redirect('/people', ['page' => 1])

The default status code on a redirect will be a 303, to change it, just wrap it:

return $this->response(302, $this->redirect('/people', ['page' => 1]));

Templates (HTML/XML/Txt)

return $this->template('@pages/profile.html', [
	'firstName' => 'John',
	'lastName'  => 'Doe'
])

The default status code on a template is 200, and its content type will be inferred from its content. Just like redirects, you can set the status code or supply custom headers by wrapping it:

return $this->response(400, $this->template('@pages/error.html'), [
	'Content-Type' => 'application/xhtml+xml'
]);

It is often the case that you may return the same content with different status codes. One way to do this is to set your template to a variable:

$template = $this->template('@pages/organization/detail.html');

if ($this->request->getMethod() == 'POST') {
	try {
		// Update the record
	} catch (Exception $e) {
		return $this->response(400, $template);
	}
}

return $this->response(200, $template);

However, another approach is to always return the template directly instead of a response and to use the init() method to initialize the resolver’s response:

if ($this->request->getMethod() == 'POST') {
	try {
		// Update the record
	} catch (Exception $e) {
		$this->init(400);
	}
}

return $this->template('@pages/organization/detail.html', $data);

The response is always initialized at 200, so you only need to call it to change the value.

Objects (JSON)

return $this->object([
	'title' => 'A nice JSON response',
	'body'  => 'Nothing to see here'
])

The default status code on an object is 200, and its content type will be application/json. If you need to change these you can

return $this->response(201, $this->object($new_entity));

Now that you’ve got your action in place, you’re going to need to add a route in order to map a URL to your action.


Add a Route No, I want to learn more about responders