Controller¶
The controller controls the flow of data between the view and the data repository containing the model.
A controller can contain one or more actions. Each of them is a method which
ends on the name "Action" and returns an object of type
\Psr\
.
In the following action a tea object should be displayed in the view:
use Psr\Http\Message\ResponseInterface;
use TTN\Tea\Domain\Model\Product\Tea;
class TeaController extends ActionController
{
public function showAction(Tea $tea): ResponseInterface
{
$this->view->assign('tea', $tea);
return $this->htmlResponse();
}
}
This action would be displayed if an URL like the following would be requested:
https://
.
So where does the model Tea $tea
come from? The only reference we had
to the actual tea to be displayed was the ID 42
. In most cases, the
parent class \TYPO3\
will take care of matching parameters to
objects or models. In more advanced scenarios it is necessary to influence
the parameter matching. But in our scenario it is sufficient to know that this
happens automatically in the controller.
The following action expects no parameters. It fetches all available tea objects from the repository and hands them over to the view:
use Psr\Http\Message\ResponseInterface;
use TTN\Tea\Domain\Repository\Product\TeaRepository;
class TeaController extends ActionController
{
private TeaRepository $teaRepository;
public function __construct(TeaRepository $teaRepository)
{
$this->teaRepository = $teaRepository;
}
public function indexAction(): ResponseInterface
{
$this->view->assign('teas', $this->teaRepository->findAll());
return $this->htmlResponse();
}
}
The controller has to access the Tea
to find all available tea
objects. We use Dependency Injection to make the
repository available to the controller: The method inject
will be called automatically with an initialized Tea
when
the Tea
is created.
Both action methods return a call to the method $this->html
.
This method is implemented in the parent class Action
and is
a shorthand method to create a response from the response factory and attach
the rendered content. Let us have a look at what happens in this method:
use Psr\Http\Message\ResponseInterface;
abstract class ActionController implements ControllerInterface
{
protected function htmlResponse(string $html = null): ResponseInterface
{
return $this->responseFactory->createResponse()
->withHeader('Content-Type', 'text/html; charset=utf-8')
->withBody($this->streamFactory->createStream((string)($html ?? $this->view->render())));
}
}
You can also use this code directly in your controller if you need to return
a different HTTP header. If a different rendering from the standard view is
necessary you can just pass the rendered HTML content to this method. There
is also a shorthand method for returning JSON called json
.
This basic example requires no actions that are forwarding or redirecting. Read more about those concepts here: Forward to a different controller.