我正在创建一个动态应用程序,通过CMS添加内容。在CMS内部,我正在设置一个数据库条目,该条目说明了每个内容页面使用的模块。
的NodeId, ParentNodeId, Name_de, Name_en, 模块名, foreignkey_ContentLinks,
在此表条目中如下所示: 6, 1, Veranstaltung-21-02-2013, 事件21-02-2013, 活动, 682
整个树应该在我的导航中结束(完全也在我的路由中)。我不想在某个控制器中添加它,因为我的应用程序包含一大堆模块,我想在所有模块中访问该信息。
我已经尝试在global.php中注入它,但无济于事,因为我不能在我的数据库适配器或那个阶段的任何其他重要类。
任何有关最佳做法的想法或链接?
答案 0 :(得分:5)
导航容器由工厂类组成。最简单的方法是编写自己的工厂并使用getPages()
方法从数据库而不是从config获取页面。如果从AbstractNavigationFactory扩展,则只需要编写几个方法。
<?php
namespace Application\Navigation\Service;
use Zend\Navigation\Service\AbstractNavigationFactory;
use Zend\ServiceManager\ServiceLocatorInterface;
class CmsNavigationFactory extends AbstractNavigationFactory
{
/**
* @param ServiceLocatorInterface $serviceLocator
* @return array
* @throws \Zend\Navigation\Exception\InvalidArgumentException
*/
protected function getPages(ServiceLocatorInterface $serviceLocator)
{
if (null === $this->pages) {
$application = $serviceLocator->get('Application');
$routeMatch = $application->getMvcEvent()->getRouteMatch();
$router = $application->getMvcEvent()->getRouter();
// get your pages from wherever...
$pages = $this->getPagesFromDB();
$this->pages = $this->injectComponents($pages, $routeMatch, $router);
}
return $this->pages;
}
public function getName()
{
// this isn't used if fetching from db, it's just here to keep the abstract factory happy
return 'cms';
}
}
将工厂添加到服务管理器,就像您对其他容器一样
'service_manager' => array(
'factories' => array(
'CmsNavigation' => 'Application\Navigation\Service\CmsNavigationFactory',
),
),
并以相同的方式将其与导航视图助手一起使用
<?php echo $this->navigation()->menu('CmsNavigation'); ?>
答案 1 :(得分:0)
回应您对@ Crisp的回答的评论,对于未来的googlers,我将解释如何为路由做类似的事情。
通常,您可能希望创建一个自定义路由器,该路由器可以匹配数据库中URL的URL,类似于标准Segment
路由器。为此,您必须实现Zend\Mvc\Router\RouteInterface
接口。例如:
namespace Application\Router;
use Zend\Mvc\Router\RouteInterface;
use Application\Model\CMSTable;
class CmsRoute implements RouteInterface, ServiceLocatorAwareInterface
{
protected $table;
// Service locator injection code
public function getCmsTable()
{
// Retrieve the table from the service manager
}
public function match(Request $request)
{
// Match the request on some route field, etc.
}
public function assemble(array $params = array(), array $options = array())
{
// Assemble a URL based on the given parameters (e.g. page ID).
}
public static function factory($options = array())
{
// Construct a new route, based on the options.
}
}
然后,您可以将此路由注册为模块配置中RoutePluginManager
的可调用内容:
'route_manager' => array(
'invokables' => array(
'Cms' => 'Application\Router\CmsRoute'
),
),
然后,您可以创建一个类型为Cms
的新路线(就像您对任何其他路线一样)。路由插件管理器将创建您的路由实例,并且由于CmsRoute
实现ServiceLocatorAwareInterface
,插件管理器将在路由中注入自己。反过来,插件管理器设置了主服务管理器,以便您可以从那里获取数据库表!
当然,您可以匹配网页ID,但如果您有分层结构,则可以更好地在网址中反映出来。因此,我建议在数据库模式中添加一个route
字段并对其进行匹配,从树根开始并逐步减少。