0

I have been using this doc to convert a client's CLi news import script from Joomla 3 to 4. The code has been stripped of all the JSON to article code for brevity.

I have gone over all of my code and files, but cannot figure out why the issue is occurring. I had tested the plugin using the Hello World example and it worked without issues. I used the same code with updated names and other details, but this is when the issues started to occur.

Error output from the terminal when running php joomla.php from within the cli directory

Symfony\Component\ErrorHandler\Error\ClassNotFoundError^ {#997
  #message: """
  Attempted to load class "DtnnewsConsolePlugin" from namespace "Ploszmarketing\Plugin\Console\Dtnnews\Extension".\n
  Did you forget a "use" statement for another namespace?
  """
#code: 0
#file: "/var/www/upgrade/plugins/console/dtnnews_cli/services/provider.php"
#line: 29
trace: {
  /var/www/upgrade/plugins/console/dtnnews_cli/services/provider.php:29 {
    Joomla\DI\ServiceProviderInterface@anonymous\x00/var/www/upgrade/plugins/console/dtnnews_cli/services/provider.php:17$aa->{closure}^
    › $dispatcher = $container->get(DispatcherInterface::class);
    › $plugin     = new DtnnewsConsolePlugin(
    › $dispatcher,
  }
  /var/www/upgrade/libraries/vendor/joomla/di/src/ContainerResource.php:182 { …}
  /var/www/upgrade/libraries/vendor/joomla/di/src/Container.php:96 { …}
  /var/www/upgrade/libraries/src/Extension/ExtensionManagerTrait.php:177 { …}
  /var/www/upgrade/libraries/src/Extension/ExtensionManagerTrait.php:99 { …}
  /var/www/upgrade/libraries/src/Plugin/PluginHelper.php:232 { …}
  /var/www/upgrade/libraries/src/Plugin/PluginHelper.php:192 { …}
  /var/www/upgrade/libraries/src/Application/ConsoleApplication.php:257 { …}
  /var/www/upgrade/cli/joomla.php:76 { …}
}
}

plg_dtnnews_cli > services > provider.php

<?php
/**
 * @package  dtnnews_cli
 * @copyright  Copyright (c) 2007 - Now Imagine Creative. All rights reserved.
 * @license  GNU General Public License version 3, or later
 */

defined('_JEXEC') or die;

use Joomla\CMS\Extension\PluginInterface;
use Joomla\CMS\Plugin\PluginHelper;
use Joomla\DI\Container;
use Joomla\DI\ServiceProviderInterface;
use Joomla\Event\DispatcherInterface;
use Ploszmarketing\Plugin\Console\Dtnnews\Extension\DtnnewsConsolePlugin;

return new class implements ServiceProviderInterface {
/**
* Registers the service provider with a DI container.
* @param   Container  $container  The DI container.
* @return  void
* @since   4.2.0
*/
public function register(Container $container) {
  $container->set(
    PluginInterface::class,
    function (Container $container) {
      $dispatcher = $container->get(DispatcherInterface::class);
      $plugin     = new DtnnewsConsolePlugin(
        $dispatcher,
        (array) PluginHelper::getPlugin('console', 'dtnnews_cli')
      );
      return $plugin;
    }
  );
}
};

plg_dtnnews_cli > src > CliCommand > RunDtnnewsCommand.php

<?php
/**
 * @package  dtnnews_cli
 * @copyright  Copyright (c) 2007 - Now Imagine Creative. All rights reserved.
 * @license  GNU General Public License version 3, or later
 */

 namespace Ploszmarketing\Plugin\Console\Dtnnews\CliCommand;

 defined('_JEXEC') or die;

 use Joomla\CMS\Factory;
 use Symfony\Component\Console\Input\InputInterface;
 use Symfony\Component\Console\Output\OutputInterface;
 use Symfony\Component\Console\Style\SymfonyStyle;
 use Joomla\Console\Command\AbstractCommand;

 class RunDtnnewsCommand extends AbstractCommand {
 /**
  * The default command name
  *
  * @var    string
  * @since  4.0.0
  */
  protected static $defaultName = 'dtn:import';

  /**
   * Internal function to execute the command.
   *
   * @param   InputInterface   $input   The input to inject into the command.
   * @param   OutputInterface  $output  The output to inject into the command.
   *
   * @return  integer  The command exit code
   *
   * @since   4.0.0
   */
   protected function doExecute(InputInterface $input, OutputInterface $output): int {
     $symfonyStyle = new SymfonyStyle($input, $output);

     $symfonyStyle->title('DTN News Command Title');

     // You might want to do some stuff here in Joomla

     $symfonyStyle->success('Successful import!');

     return 0;
   }

   /**
    * Configure the command.
    *
    * @return  void
    *
    * @since   4.0.0
    */
   protected function configure(): void {
     $this->setDescription('This command prints hello world to whoever calls it');
     $this->setHelp(
       <<<EOF
       The <info>%command.name%</info> command prints hello world to whoever calls it
       <info>php %command.full_name%</info>
       EOF
     );
   }
 }

plg_dtnnews_cli > src > Extension > DtnnewsConsolePlugin.php

<?php
/**
 * @package  dtnnews_cli
 * @copyright  Copyright (c) 2007 - Now Imagine Creative. All rights reserved.
 * @license  GNU General Public License version 3, or later
 */

 namespace Ploszmarketing\Plugin\Console\Dtnnews\Extension;

 defined('_JEXEC') or die;

 use Joomla\CMS\Plugin\CMSPlugin;
 use Joomla\Event\SubscriberInterface;
 use Joomla\Application\ApplicationEvents;
 use Joomla\CMS\Factory;
 use Ploszmarketing\Plugin\Console\Dtnnews\CliCommand\RunDtnnewsCommand;

 class DtnnewsConsolePlugin extends CMSPlugin implements SubscriberInterface {
   public static function getSubscribedEvents(): array {
     return [
       \Joomla\Application\ApplicationEvents::BEFORE_EXECUTE => 'registerCommands',
     ];
   }

   public function registerCommands(): void {
     $app = Factory::getApplication();
     $app->addCommand(new RunDtnnewsCommand());
   }
 }

plg_dtnnews_cli > dtnnews_cli.xml

<?xml version="1.0" encoding="utf-8"?>
<!--
@package  dtnnews_cli
@copyright  Copyright (c) 2007 - Now Imagine Creative. All rights reserved.
@license  GNU General Public License version 3, or later
-->
<extension type="plugin" group="console" method="upgrade">
  <name>DTN News Import</name>
  <version>1.0.0</version>
  <creationDate>2023-09-07</creationDate>
  <author>Michael Hermary</author>
  <authorEmail>hidden</authorEmail>
  <authorUrl>hidden</authorUrl>
  <copyright>Copyright (c) 2007 - Now Imagine Creative</copyright>
  <license>GNU General Public License version 3, or later</license>
  <description>This console plugin uses the CLi and the DTN News API to import items into the Article Manager</description>
  <namespace path="src">Ploszmarketing\Plugin\Console\Dtnnews</namespace>
  <files>
    <folder plugin="dtnnews_cli">services</folder>
    <folder>src</folder>
    <filename>.htaccess</filename>
  </files>
</extension>

PHP 8.2 for the CLi.

6
  • 1
    I downloaded the files and it worked all ok for me. Try deleting administrator/cache/autoload_psr4.php. Sep 14, 2023 at 21:58
  • @RobbieJackson Deleting that file worked, though it did produce an error until it was auto-generated by Joomla again. Sep 15, 2023 at 17:35
  • That's good! Joomla reads all the XML manifest files of the extensions to build up a mapping of namespace prefix to where source files are stored in the filesystem. As this is fair bit of work it caches this in autoload_psr4.php. So if you then change your XML manifest file <namespace> then it won't get taken account of until the cached file is deleted and regenerated by Joomla. In the meantime your class files may well not get found. If you're interested, there's some background info on namespaces and autoloading in manual.joomla.org/docs/general-concepts/namespaces. Sep 15, 2023 at 17:44
  • @RobbieJackson if you post your comment(s) as the answer Mike will be able to accept the solution. The autoload_psr4.php is also deleted and rebuiltr when an extension is installed through the Install and Discover features.
    – Irata
    Sep 16, 2023 at 9:14
  • @Irata I checked and the autoload_psr4.php is indeed regenerated when an extension is installed. So I'm wondering how it could have got out of step with the plugin code. Do you have any ideas Mike? Obviously if you're just editing the "live" files in the joomla instance rather than going through the dev -> install process that could occur. (Mike, if you understand why this occurred then I'd be equally happy for you to write the answer and accept it. Doing that does mean that people who are reading the questions looking to help someone don't waste their time.) Sep 17, 2023 at 10:47

1 Answer 1

0

When getting a Class Not Found error and you think that all your code is ok, then it's worth it to check the cache file in administrator/cache/autoload_psr4.php.

This file is generated from Joomla reading all the XML manifest files of the extensions to build up a mapping of namespace prefix to where source files are stored in the filesystem. As this is quite a bit of work Joomla caches the file, so there may be scenarios when it gets out of step with your code - for example, if you're changing your "live" code files directly, rather than using a develop - zip - install process. The file should be regenerated whenever you install an extension.

If the cache is out of date then the solution is simply to delete the administrator/cache/autoload_psr4.php file. Joomla will regenerate it the next time that it has an HTTP request to your site.

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.