Stand alone view url helper when cli is used

Hi all,

I am trying to migrate from laminas-console to laminas-cli, but the following issue appeared:
I am using cron to initiate regular tasks like sending reminding email to users (using my Mailer class). In those emails sometimes there are links, generated with $this->url(…). When I was using laminas-console, I was passing the uri part as parameter, but now it doesn’t even reach this point, because it throws exception in createUrlHelperFactory(), for calling ->getRouteMatch() on null, which is expected, since it is started from CLI.
This is very similar to the issue described here onBootstrap not called for CLI commands and I have checked the documentation for the stand alone use of the View, but it is not clear for me how exactly to implement it in my case.
For clarification:

My CommandManager class “executes” the CLI command, and calls function in TasksManager class, who checks for overdue tasks, and if there are any, calls function in Mailer class, which sends email using specific .phtml template. In this template there are some dynamically generated links pointing to those overdue tasks.
What would be the best practice for implementing the stand alone View in this case, having in mind that I use the same Mailer class for sending emails that were initiated from the normal “web” (not cli) use of the application?
Thank you in advance

Hello and welcome to our forums! :smiley:

In the same thread you can also find the URL helper topic. Create a custom factory:

Thank you for the suggestion. I was able to use that solution, I just wanted to “second” this topic , looking for “not so dirty” solution and having in mind your statement:

Additionally I want to get an advice how to deal with the Config Cache - I notice that when it is enabled if the config cache is generated by the command it “breaks” the web interface because in keeps the URL Helper Factory from the command config. Vice versa if there is already some cached config, from web request, the command does not work because it doesn’t read the new config, it directly reads the cached one. I have overcome this solution by deleting the config cache files in the beginning of the command config file and just before it returns the container, but I am not sure whether this is the best solution…
Thank you once again for your advices.

The URL helper is part of laminas-view and for an easy setup of this helper a solution should exist in laminas-view itself. The entire stand-alone usage should be simplified, this would also help in a CLI command.

This is related to:

Hello,
Thank you once again.
I have spent couple of hours to make this work, but with no success, probably have missed something.
I will give it another try after the summer holiday.
I will keep following the discussion in GitHub and the evolution of laminas-view and cli.

Do you have an example how to accomplish this? I’ve tried setting up a custom factory for the URL view helper and giving it the HttpRouter service and I’m still getting the same "Uncaught Error: Call to a member function getRouteMatch() on null " error message.

Hi,
I have managed to deal with this as described in both treads above, but to summarize:
Add the config parameter to your CLI command, in my case it looks like this:

/vendor/bin/laminas --container <<path to config>><<config-file>>.php <<command>>

and in that config file I am pointing to the URL Helper Factory, created as described in the first link above.

https://discourse.laminas.dev/t/onbootstrap-not-called-for-cli-commands/2447

In my case it looks like this:

$config = require <<path>>. 'application.config.php';
$extendedConfig = [
 'view_helpers' => [
        'factories' => [
            \Laminas\View\Helper\Url::class => \Application\View\Helper\UrlFactory::class,
        ]
    ]
];
$container = new ServiceManager();
(new ServiceManagerConfig())->configureServiceManager($container);
$container->setService('ApplicationConfig', $config);
/** @var \Laminas\ModuleManager\ModuleManager $moduleManager */
$moduleManager = $container->get('ModuleManager');

$events = $moduleManager->getEventManager();
$events->attach(\Laminas\ModuleManager\ModuleEvent::EVENT_MERGE_CONFIG, function (\Laminas\ModuleManager\ModuleEvent $e) use ($extendedConfig) {
    $configListener = $e->getConfigListener();
    $config = $configListener->getMergedConfig(false);
    $config = ArrayUtils::merge($config, $extendedConfig);
    // Pass the changed configuration back to the listener:
    $configListener->setMergedConfig($config);
});
$moduleManager->loadModules();

Don’t forget to “deal” with the config cache if you have such.