I'm writing a component, and I have this code for the frontend that works great to pull the menu object:
$menuObjects= JFactory::getApplication()->getMenu();
$menuArrays = $menuObjects ->getMenu();
From there, I can generate an article URL given an article ID (which is what I'm trying to do). However, from the backend administrator side, this comes back empty.
Without querying the database, how can I access the frontend menu object from the backend?
#Solution:
Thanks to @borracciaBlu for getting me on the right track:
For Joomla 2.5 (use JApplication
):
$app = JApplication::getInstance('site');
$menuObjects= $app->getMenu();
$menuArrays = $menuObjects ->getMenu();
For Joomla 3.x (use JApplicationCms
):
$app = JApplicationCms::getInstance('site');
$menuObjects= $app->getMenu();
$menuArrays = $menuObjects ->getMenu();
Ok I did some tests and those are the results.
The reason why you have two different results is because you are using JFactory::getApplication()
.
In fact in the frontend this method is returning a JApplicationSite
object instead in the backend is returning a JApplicationAdministrator
.
That's the test :
$app = JFactory::getApplication();
var_dump($app);
If you try them in your component you'll see the results above.
Now, in theory JFactory
was designed to accept parameters to override the std behaviour and instantiate the Object in the flavour you desire.
I'm saying that in "theory" method accepts several parameters.
From the documentation those are :
$id
A client identifier or name. $config
An optional associative array of configuration settings. $prefix
Application prefix Unfortunately that's just a theory..
In reality the method is ignoring $config
and $prefix
in any case and $id
if self::$application
is already instantiated.
Guess what.. Unluckily for you at this point self::$application
already exists.
Murphy would be proud of you.. :)
As first thing in administrator/index.php@39 we have:
$app = JFactory::getApplication('administrator');
So as you can see here the method is totally ignoring anything you pass to at this point. It can be used only to get an instance of JApplicationAdministrator.
//@see libraries/joomla/factory.php@101
/**
* Get a application object.
*
* Returns the global {@link JApplicationCms} object, only creating it if it doesn't already exist.
*
* @param mixed $id A client identifier or name.
* @param array $config An optional associative array of configuration settings.
* @param string $prefix Application prefix
*
* @return JApplicationCms object
*
* @see JApplication
* @since 11.1
* @throws Exception
*/
public static function getApplication($id = null, array $config = array(), $prefix = 'J')
{
if (!self::$application)
{
if (!$id)
{
throw new Exception('Application Instantiation Error', 500);
}
self::$application = JApplicationCms::getInstance($id);
}
return self::$application;
}
Btw the good news is that this method is not doing anything special except caching and wrapping JApplicationCms::getInstance($id);
.
So instead of your old code using JFactory::getApplication() :
$menuObjects= JFactory::getApplication()->getMenu();
$menuArrays = $menuObjects ->getMenu();
You can use it directly :
$app = JApplicationCms::getInstance('site');
$menuObjects= $app->getMenu();
$menuArrays = $menuObjects ->getMenu();
P.S.
Yes as you may thinking the interface of JFactory::getApplication()
it's a little bit buggy.