2

I'm having trouble with using a helper file in Joomla 4, I'm not really sure where I'm going wrong.

I have a helper file in my template, like templates/mytemplate/html/helper.php and this works well within my template, using JLoader::register('myhelper', 'templates/mytemplate/html/helper.php'); and myhelper::testfunc("hello"); sort of thing.

Where I've hit a bump, is that I want to also use functions from this helper file elsewhere, for example, in a joomla console command. When I use the same code in my console I just Class not found errors.

I've tried quite a few variations of JLoader, like registerPrefix, registerNamespace and setup, and some use commands to pull in the namespace, with no luck. I also tried moving the helper into a library, but that didn't work either.

I think I'm missing something re Joomla 4 and namespaces, any ideas?

Some code, to help explain...

The template helper templates/mytemplate/html/myhelper.php

<?php 
/**
 * This is a helper file
 * Usage:
 * Register it like...
 * JLoader::register('myhelper', 'templates/mytemplate/html/myhelper.php'); 
 * Call functions like...
 * myhelper::tester("hello");
 */
namespace Myhelper; # not sure about this bit
class Myhelper{
    /**
     * tester
     * @param string    test string
     * @return string   output string
     */
    public static function tester($test_value){
        return "tester says " . $test_value;
    }
}

The console code plugins/system/myconsole/src/Console/MyconsoleCommand.php

<?php
/**
 * Call like...
 * php cli/joomla.php myconsole:action hello
 */
namespace Joomla\Plugin\System\Saaconsole\Console;
\defined('JPATH_PLATFORM') or die;
use Joomla\CMS\Factory;
use Joomla\Console\Command\AbstractCommand;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
use JLoader;

class MyconsoleCommand extends AbstractCommand
{
    # some console boilerplate is here, removed for brevity

    protected function doExecute(InputInterface $input, OutputInterface $output): int
    {
        # some console boilerplate is here, removed for brevity
        JLoader::register('myhelper', 'templates/mytemplate/html/myhelper.php'); 
        $test = myhelper::tester("galopin");
        $symfonyStyle->text('test: ' . $test);
        return 0;
    }

}

This code comes back with [Error] Class "Joomla\Plugin\System\myconsole\Console\myhelper" not found

2 Answers 2

3

JLoader::register() call should include fully qualified class name. In your case it's Myhelper\MyHelper:

JLoader::register('Myhelper\Myhelper', 'templates/mytemplate/html/helper.php');

The class also needs to be referenced using full name in code:

$test = Myhelper\MyHelper::tester("galopin");

Or you can import it with use statement like any other class in your plugin:

...
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
use JLoader;
use Myhelper\Myhelper;

class MyconsoleCommand extends AbstractCommand
{
    protected function doExecute(InputInterface $input, OutputInterface $output): int
    {
        JLoader::register('Myhelper\Myhelper', 'templates/mytemplate/html/helper.php');
        $test = Myhelper::tester("galopin");
    }
}

If you have many classes and don't want to register them separately, you can either create a custom autoloader or switch to PSR-4 autoloading and use JLoader::registerNamespace() to register the entire namespace. And once templates support autoloading like other extensions in Joomla, you could remove the use of JLoader completely.

Finally, you are misusing the template's html directory. It should be used strictly for layouts. You can put your code anywhere else.

1
  • Massive thanks Sharky, that did the trick Jan 27, 2022 at 20:32
0

I am fairly new to Joomla 4 development so please bear that in mind, but if you change your namespace to the following it should get it working:

namespace Joomla\Plugin\System\MyConsole\Console;

I've amended the capitalisation in the above to conform to PSR-1 naming standards and your class name should be altered to MyHelper for the same reason. That should get picked up by the autoloading so you'll be able to bring your helper in via the 'use' statements at the top of your MyConsoleCommand class rather than using JLoader::register.

E.g.

use Joomla\Plugin\System\MyConsole\Console\MyHelper

Then call your helper function with MyHelper::tester("galopin");.

Fingers crossed, that'll work for you.

3
  • Thanks for the reply, sadly that didn't work Jan 25, 2022 at 19:26
  • 1
    Ah, heck. I've added a copy of both files to my test setup and I can see in PHPStorm that it's recognising the namespace and tester function in the MyconsoleCommand class. I've never worked with Joomla Console Commands so I'll try and get more familiar with them today so I can test it from that angle.
    – Grant Hood
    Jan 26, 2022 at 8:12
  • Thanks Grant, the Joomla 4 console seems quite different to the old Joomla CLI, I'm still getting my head round it really. Jan 26, 2022 at 8:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.