如何从后端访问 Joomla 中的前端菜单对象?
How to access the frontend menu object in Joomla from the backend?
我正在编写一个组件,我有这段前端代码,非常适合拉取菜单对象:
$menuObjects= JFactory::getApplication()->getMenu();
$menuArrays = $menuObjects ->getMenu();
从那里,我可以根据文章 ID 生成一篇文章 URL(这正是我想要做的)。但是,从后端管理员端来看,这返回是空的。
不查询数据库,如何从后台访问前台菜单对象?
#
解决方案:
感谢@borracciaBlu 让我走上正轨:
对于 Joomla 2.5(使用 JApplication
):
$app = JApplication::getInstance('site');
$menuObjects= $app->getMenu();
$menuArrays = $menuObjects ->getMenu();
对于 Joomla 3.x(使用 JApplicationCms
):
$app = JApplicationCms::getInstance('site');
$menuObjects= $app->getMenu();
$menuArrays = $menuObjects ->getMenu();
好的,我做了一些测试,结果就是这些。
你有两个不同结果的原因是因为你使用的是 JFactory::getApplication()
.
实际上在前端这个方法返回一个 JApplicationSite
对象而不是在后端返回一个 JApplicationAdministrator
.
这就是测试:
$app = JFactory::getApplication();
var_dump($app);
如果您在组件中尝试使用它们,您会看到上面的结果。
现在,理论上 JFactory
旨在接受参数以覆盖标准行为并以您想要的风格实例化对象。
我是说在“理论”中方法接受多个参数。
从文档中可以看出:
$id
客户端标识符或名称。
$config
可选的配置设置关联数组。
$prefix
应用程序前缀
不幸的是,这只是一个理论..
实际上,该方法在任何情况下都会忽略 $config
和 $prefix
,如果 self::$application
已经实例化,则忽略 $id
。
你猜怎么着.. 对你来说不幸的是此时 self::$application
已经存在。
Murphy 会以你为荣..:)
作为 administrator/index.php@39 中的第一件事,我们有:
$app = JFactory::getApplication('administrator');
正如您在这里看到的那样,该方法完全忽略了您此时传递给的任何内容。
它只能用于获取 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;
}
顺便说一句,好消息是这个方法除了缓存和包装外没有做任何特别的事情 JApplicationCms::getInstance($id);
。
因此,不要使用 JFactory::getApplication() 的旧代码:
$menuObjects= JFactory::getApplication()->getMenu();
$menuArrays = $menuObjects ->getMenu();
可以直接使用:
$app = JApplicationCms::getInstance('site');
$menuObjects= $app->getMenu();
$menuArrays = $menuObjects ->getMenu();
P.S。
是的,您可能会认为 JFactory::getApplication()
的界面有点问题。
我正在编写一个组件,我有这段前端代码,非常适合拉取菜单对象:
$menuObjects= JFactory::getApplication()->getMenu();
$menuArrays = $menuObjects ->getMenu();
从那里,我可以根据文章 ID 生成一篇文章 URL(这正是我想要做的)。但是,从后端管理员端来看,这返回是空的。
不查询数据库,如何从后台访问前台菜单对象?
#解决方案:
感谢@borracciaBlu 让我走上正轨:
对于 Joomla 2.5(使用 JApplication
):
$app = JApplication::getInstance('site');
$menuObjects= $app->getMenu();
$menuArrays = $menuObjects ->getMenu();
对于 Joomla 3.x(使用 JApplicationCms
):
$app = JApplicationCms::getInstance('site');
$menuObjects= $app->getMenu();
$menuArrays = $menuObjects ->getMenu();
好的,我做了一些测试,结果就是这些。
你有两个不同结果的原因是因为你使用的是 JFactory::getApplication()
.
实际上在前端这个方法返回一个 JApplicationSite
对象而不是在后端返回一个 JApplicationAdministrator
.
这就是测试:
$app = JFactory::getApplication();
var_dump($app);
如果您在组件中尝试使用它们,您会看到上面的结果。
现在,理论上 JFactory
旨在接受参数以覆盖标准行为并以您想要的风格实例化对象。
我是说在“理论”中方法接受多个参数。
从文档中可以看出:
$id
客户端标识符或名称。$config
可选的配置设置关联数组。$prefix
应用程序前缀
不幸的是,这只是一个理论..
实际上,该方法在任何情况下都会忽略 $config
和 $prefix
,如果 self::$application
已经实例化,则忽略 $id
。
你猜怎么着.. 对你来说不幸的是此时 self::$application
已经存在。
Murphy 会以你为荣..:)
作为 administrator/index.php@39 中的第一件事,我们有:
$app = JFactory::getApplication('administrator');
正如您在这里看到的那样,该方法完全忽略了您此时传递给的任何内容。 它只能用于获取 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;
}
顺便说一句,好消息是这个方法除了缓存和包装外没有做任何特别的事情 JApplicationCms::getInstance($id);
。
因此,不要使用 JFactory::getApplication() 的旧代码:
$menuObjects= JFactory::getApplication()->getMenu();
$menuArrays = $menuObjects ->getMenu();
可以直接使用:
$app = JApplicationCms::getInstance('site');
$menuObjects= $app->getMenu();
$menuArrays = $menuObjects ->getMenu();
P.S。
是的,您可能会认为 JFactory::getApplication()
的界面有点问题。