User tests: Successful: Unsuccessful:
Pull Request for Issue # .
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
This is code review only for Joomla 4 team
Status | New | ⇒ | Pending |
Category | ⇒ | Libraries |
Labels |
Added:
?
|
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
Ah, sorry. Maybe your code works But in this case, language will be loaded twice I think. Will need to try it
My gut is that setting the existing language into the application is superior. But willing to listen to other arguments
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';)
Agreed. I think JPATH_BASE is correct. But JPATH_COMPONENT is wrong
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
Ugh
Status | Pending | ⇒ | Closed |
Closed_Date | 0000-00-00 00:00:00 | ⇒ | 2017-06-02 04:01:32 |
Closed_By | ⇒ | joomdonation |
Is this not better?