Q:

ZF3 PhpRenderer not finding template path

I know there are dozen of questions about PHPRenderer not finding the path of a template, but I think the problem is quite different here.
First, the goal is to render a view to a variable in order to send it to a PDF Renderer (I use ZF3 TCPDF module). If there is any better way to do that, please tell me.
Here is roughly the architecture of the project: https://imgur.com/UhQ7hgP
In AlertAction() of ToolsController, I return the view like this, and it works, which make me think the template path is alright.
$view = new ViewModel();
$view->setTemplate('tools/tools/alert');
return $view;

However, when I try to render the same view with the same path in exportPDFAction(), it does not work and gives the following error.

Zend\View\Renderer\PhpRenderer::render: Unable to render template "tools/tools/alert"; resolver could not resolve to a file

The code in exportPDFAction() is:
$view = new ViewModel();
$renderer = new PhpRenderer();
$view->setTemplate('tools/tools/alert');
$html = $renderer->render($view);

I assume the last line screws it as it is the difference, but I can't get why, does anyone have any clue ?
Quite all the topics about Template path on SO were talking about the template map in module.config.php, but I think this is not the problem here since it works perfectly in AlertAction().
EDIT
The PhpRenderer is injected in the controller directly in module.config.php:
'controllers' => [
    'factories' => [
        ToolsController::class => function($container) {
            return new ToolsController(
                $container->get(Adapter::class),
                $container->get(\TCPDF::class),
                $container->get(PhpRenderer::class)
            );
        },
    ],
],

EDIT 2
This is the controller constructor:
public function __construct($db, $tcpdf, $renderer)
{
    $this->db = $db;
    $this->tcpdf = $tcpdf;
    $this->renderer = $renderer;
    ...
}

A:

The error you're getting might be due to the fact your Renderer is not injected via the Factory. 
Try:
class MyCustomControllerFactory implements FactoryInterface
{
    public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
    {
        /** @var \Zend\View\Renderer\PhpRenderer $renderer */
        $renderer = $container->get('ViewRenderer')

        return new MyCustomController($renderer);
    }
}

In the Controller, require it be set in the __construct() function:
public function __construct(PhpRenderer $renderer)
{
    // ... set it somewhere, e.g.:
    $this->setRenderer($renderer);
}

Then use it in your function:
$view = new ViewModel();
$renderer = $this->getRenderer();
$view->setTemplate('tools/tools/alert');
$html = $renderer->render($view);

Why, you ask?
Because the Renderer is configured via the Zend Configuration. You can find that in the \Zend\Mvc\Service\ServiceManageFactory class. The alias configuration provided is the following:
'ViewPhpRenderer'                      => 'Zend\View\Renderer\PhpRenderer',
'ViewRenderer'                         => 'Zend\View\Renderer\PhpRenderer',
'Zend\View\Renderer\RendererInterface' => 'Zend\View\Renderer\PhpRenderer',

The alias'es are mapped to Factory:
'Zend\View\Renderer\PhpRenderer' => ViewPhpRendererFactory::class,

That Factory is:
class ViewPhpRendererFactory implements FactoryInterface
{
    /**
     * @param  ContainerInterface $container
     * @param  string $name
     * @param  null|array $options
     * @return PhpRenderer
     */
    public function __invoke(ContainerInterface $container, $name, array $options = null)
    {
        $renderer = new PhpRenderer();
        $renderer->setHelperPluginManager($container->get('ViewHelperManager'));
        $renderer->setResolver($container->get('ViewResolver'));

        return $renderer;
    }
}

As such, it has some presets included when you use it with $this->getRenderer, namely it has the HelperPluginManager and the Resolver set. So it knows where to get additional resources (if needed) and it knows how to resolve (ie render) a View. 

