? Pending

User tests: Successful: Unsuccessful:

avatar joomdonation
joomdonation
22 Apr 2017

Pull Request for Issue # .

Summary of Changes

In case frontend code need to call a backend controller code (For example, com_config frontend call backend module controller save method to save module parameters), we will need some code like this (assume com_modules is already namespaced)

JLoader::register('ModulesDispatcher', JPATH_ADMINISTRATOR . '/components/com_modules/dispatcher.php');

$app             = \Joomla\CMS\Application\CmsApplication::getInstance('administrator');
$dispatcher      = new ModulesDispatcher('Joomla\\Component\\Modules', $app, $input);
$controllerClass = $dispatcher->getController('Module');

// Execute backend controller
$return = $controllerClass->save();

When the dispatcher object is created, it call loadLanguage() https://github.com/joomla/joomla-cms/blob/4.0-dev/libraries/src/CMS/Dispatcher/Dispatcher.php#L93 method. The problem is that $this->app->getLanguage() return null and it causes fatal error ($language is only available in application object after calling doExecute() method). This PR proposes a fix for that issue

Testing Instructions

This is code review only for Joomla 4 team

avatar joomdonation joomdonation - open - 22 Apr 2017
avatar joomdonation joomdonation - change - 22 Apr 2017
Status New Pending
avatar joomla-cms-bot joomla-cms-bot - change - 22 Apr 2017
Category Libraries
avatar joomdonation joomdonation - change - 22 Apr 2017
Labels Added: ?
avatar joomdonation joomdonation - change - 22 Apr 2017
The description was changed
avatar joomdonation joomdonation - edited - 22 Apr 2017
avatar wilsonge
wilsonge - comment - 22 Apr 2017

Is this not better?

JLoader::register('ModulesDispatcher', JPATH_ADMINISTRATOR . '/components/com_modules/dispatcher.php');

$app             = \Joomla\CMS\Application\CmsApplication::getInstance('administrator');
$app->loadLanguage($this->app->getLanguage());
$dispatcher      = new ModulesDispatcher('Joomla\\Component\\Modules', $app, $input);
$controllerClass = $dispatcher->getController('Module');

// Execute backend controller
$return = $controllerClass->save();
avatar joomdonation
joomdonation - comment - 22 Apr 2017

The problem is that when we create dispatcher object;

$dispatcher      = new ModulesDispatcher('Joomla\\Component\\Modules', $app, $input);

The loadLanguage() method is called immediately https://github.com/joomla/joomla-cms/blob/4.0-dev/libraries/src/CMS/Dispatcher/Dispatcher.php#L93

The $app property of dispatcher object now is Administrator application object, it doesn't have $language property available yet, so $this->app->getLanguage() return null, thus it causes fatal error as I described

avatar joomdonation
joomdonation - comment - 22 Apr 2017

Ah, sorry. Maybe your code works But in this case, language will be loaded twice I think. Will need to try it

avatar joomdonation
joomdonation - comment - 22 Apr 2017

OK. @wilsonge code works (although not easy to figure out). Let me know if you want to have the code like that and I will close this PR.

avatar wilsonge
wilsonge - comment - 22 Apr 2017

@mbabker thoughts please

avatar wilsonge
wilsonge - comment - 22 Apr 2017

My gut is that setting the existing language into the application is superior. But willing to listen to other arguments

avatar joomdonation
joomdonation - comment - 22 Apr 2017

BTW, loadLanguage() method in Dispatcher is not implemented properly. We are hardcode the path to JPATH_BASE and JPATH_COMPONENT which is wrong in the given sample code (the path must he JPATH_ADMINISTRATOR and JPATH_ADMINISTRATOR . '/components/com_modules';)

avatar wilsonge
wilsonge - comment - 22 Apr 2017

Agreed. I think JPATH_BASE is correct. But JPATH_COMPONENT is wrong

avatar joomdonation
joomdonation - comment - 22 Apr 2017

JPATH_BASE is not correct, too. With that sample code, the active component is com_config in the frontend, so JPATH_BASE equals JPATH_ROOT. But when we call com_modules backend, we need to language file from JPATH_ADMINISTRATOR, so JPATH_BASE is wrong

Unless application class has a method such as getPath() to return the root path of the application, I think we will need to use if else command here

avatar wilsonge
wilsonge - comment - 23 Apr 2017

Ugh

avatar joomdonation joomdonation - change - 2 Jun 2017
Status Pending Closed
Closed_Date 0000-00-00 00:00:00 2017-06-02 04:01:32
Closed_By joomdonation
avatar joomdonation joomdonation - close - 2 Jun 2017

Add a Comment

Login with GitHub to post a comment