0

I'm working on a custom Joomla! CLI application and would like to rely on an external PHP library to reuse some functionality.

// Set flag that this is a parent file.
const _JEXEC = 1;

error_reporting(E_ALL | E_NOTICE);
//error_reporting(E_ALL & ~E_NOTICE);
ini_set('display_errors', 1);

// Load system defines
if (file_exists(dirname(__DIR__) . '/defines.php'))
{
    require_once dirname(__DIR__) . '/defines.php';
}

if (!defined('_JDEFINES'))
{
    define('JPATH_BASE', dirname(__DIR__));
    require_once JPATH_BASE . '/includes/defines.php';
}

require_once JPATH_LIBRARIES . '/import.legacy.php';
require_once JPATH_LIBRARIES . '/cms.php';

// Load the configuration
require_once JPATH_CONFIGURATION . '/configuration.php';

require_once JPATH_SITE . '/modules/gng/gng_shared.php';

$myApp = JApplicationCli::getInstance('GNGEmailToGuideDownloader');
$hostname = GNGParam::getParam('email', 'hostname');
$username = GNGParam::getParam('email_account_guides', 'username');
$password = GNGParam::getParam('email_account_guides', 'password');
$myApp->initStream($hostname, $username, $password);
$myApp->execute();

The CLI application is based on the GNGEmailToGuideDownloader class that is stored in the gng_shared.php file. This class should use the functionalities of the external library.

I copied the directory structure of the source code of the library in the same folder where the gng_shared.php file is stored:

enter image description here

Finally I tried to use the JLoader::register mechanism to load the classes in the library, so that I can instantiate and use them:

//retrieves new guides@ email from the server, saves it in the DB and notifies the guide
class GNGEmailToGuideDownloader extends GNGEmailDownloader  
{
    //downloads the emails from the stream and assigns them to a tour or inquiry
    public function loadEmails() {

        $filepath = JPATH_SITE . '/modules/gng/EmailReplyParser/Parser/EmailParser.php';
        if (file_exists($filepath)) {
            JLoader::register('EmailParser', $filepath);
            $parser = new EmailParser();
        } 

In the EmailParser.php there is the appropriate class:

namespace EmailReplyParser\Parser;

use EmailReplyParser\Email;
use EmailReplyParser\Fragment;

/**
 * @author William Durand <[email protected]>
 */
class EmailParser
{
    const QUOTE_REGEX = '/>+$/s';

However on the line where I'm trying to create the parser object I get the following error message when I'm running the CLI app:

Fatal error: Class 'EmailParser' not found in /home/gonative/public_html/dev/modules/gng/gng_shared.php on line 1737

What am I doing wrong?

5
  • Out of curiosity, does modules/gng folder contain a Joomla module? If it does, it should have mod_ prefix (the folder should be modules/mod_gngand the main module file mod_gng.php) to avoid various issues across Joomla. If not, it should not be installed in Joomla's modules directory.
    – Sharky
    Commented Mar 2, 2019 at 18:05
  • No, it does not contain a module. It contains files like gng_shared.php that contain a lot of classes used (required) by all the other modules. For practical reasons I kept the gng folder together with the module folders, so that I don't need to switch directories when I'm uploading my changes. But let me know if there is a better solution. Commented Mar 2, 2019 at 20:34
  • If it contains a set of classes used by other extensions but doesn't execute any code on its own, it would be a library. Joomla does have an extension type for libraries. docs.joomla.org/Using_own_library_in_your_extensions.
    – Sharky
    Commented Mar 2, 2019 at 21:45
  • @wander I don't know who crafted that regex pattern constant, but it doesn't look good. It says: match one or more greater than symbols before the end of the string and allow any dot (the any character symbol) in the pattern to additionally match newline characters -- but there are no dots in the pattern. ...I'd be concerned. How is it used? What is the intention? I think the pattern needs help. I can help. Commented Mar 3, 2019 at 11:36
  • @Sharky: thanks, I have not realized so far that my shared file is basically a library, I will convert it into one based on your link! mickmackusa: I got the regex from an example, I knew it is not perfect, but this external library will take over the job of the regex, so not need to rewrite it anymore. But thanks anyway! Commented Mar 3, 2019 at 20:58

1 Answer 1

3

Use JLoader::registerNamespace() to register this library's namespace. This should work for you current folder structure:

JLoader::registerNamespace('EmailReplyParser\\Parser', __DIR__, false, false, 'psr0');

Or you can use the included autoloader:

require_once __DIR__ . '/autoload.php';

Then add import statements before using the classes:

use EmailReplyParser\Parser\EmailParser;

$parser = new EmailParser;

Or use full classnames:

$parser = new EmailReplyParser\Parser\EmailParser;
1
  • Thanks for the great guidance! I had to register a few other namespaces based on error messages, but basically that was it! Commented Mar 3, 2019 at 20:56

Your Answer

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

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