Я пытаюсь реализовать мою Zend навигацию из контейнера в ZF3. Я успешно создал навигацию с этим руководством по быстрому старту, представляя навигацию прямо в config/autoload/global.php
или же config/module.config.php
файлы:
https://docs.zendframework.com/zend-navigation/quick-start/
Но теперь мне нужно заставить его работать с помощниками, чтобы разрешить изменение навигации из контроллера, используя раздел «Настройка навигации, использованная в примерах»:
https://docs.zendframework.com/zend-navigation/helpers/intro/
Это мое module.php
namespace Application;
use Zend\ModuleManager\Feature\ConfigProviderInterface;
use Zend\View\HelperPluginManager;
class Module implements ConfigProviderInterface
{
public function getViewHelperConfig()
{
return [
'factories' => [
// This will overwrite the native navigation helper
'navigation' => function(HelperPluginManager $pm) {
// Get an instance of the proxy helper
$navigation = $pm->get('Zend\View\Helper\Navigation');
// Return the new navigation helper instance
return $navigation;
}
]
];
}
public function getControllerConfig()
{
return [
'factories' => [
$this->getViewHelperConfig()
);
},
],
];
}
}
А это мой IndexController.php
namespace Application\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
use Zend\Navigation\Navigation;
use Zend\Navigation\Page\AbstractPage;
class IndexController extends AbstractActionController
{
private $navigationHelper;
public function __construct(
$navigationHelper
){
$this->navigationHelper = $navigationHelper;
}
public function indexAction()
{
$container = new Navigation();
$container->addPage(AbstractPage::factory([
'uri' => 'http://www.example.com/',
]));
$this->navigationHelper->plugin('navigation')->setContainer($container);
return new ViewModel([
]);
}}
Но тогда я получаю следующую ошибку:
Fatal error: Call to a member function plugin() on array in /var/www/html/zf3/module/Application/src/Controller/IndexController.php on line 50
В учебном пособии они используют следующее утверждение:
// Store the container in the proxy helper:
$view->plugin('navigation')->setContainer($container);
// ...or simply:
$view->navigation($container);
Но я не знаю, что это $view
есть, так что я полагаю, это мой $navigation
от моего module.php. Проблема в том, что, поскольку это массив, он выдает ошибку. Вопросы:
$view
из учебника взялись?Заранее спасибо!
Добавить в module.config.php
'service_manager' => [
'factories' => [
Service\NavManager::class => Service\Factory\NavManagerFactory::class,
],
],
'view_helpers' => [
'factories' => [
View\Helper\Menu::class => View\Helper\Factory\MenuFactory::class,
],
'aliases' => [
'mainMenu' => View\Helper\Menu::class,
],
],
Создать фабрику в сервисном каталоге:
namespace Application\Service\Factory;
use Interop\Container\ContainerInterface;
use Application\Service\NavManager;class NavManagerFactory {
/**
* This method creates the NavManager service and returns its instance.
*/
public function __invoke(ContainerInterface $container, $requestedName, array $options = null) {
$authService = $container->get(\Zend\Authentication\AuthenticationService::class);
$viewHelperManager = $container->get('ViewHelperManager');
$urlHelper = $viewHelperManager->get('url');
return new NavManager($authService, $urlHelper);
}
}
Создайте файл NavManager:
namespace Application\Service;
class NavManager {
/**
* Auth service.
* @var Zend\Authentication\Authentication
*/
private $authService;
/**
* Url view helper.
* @var Zend\View\Helper\Url
*/
private $urlHelper;
/**
* Constructs the service.
*/
public function __construct($authService, $urlHelper) {
$this->authService = $authService;
$this->urlHelper = $urlHelper;
}
/**
* Menu render based on user role
*
* @return array
*/
public function getMenuItems() {
$navItem = array();
$url = $this->urlHelper;
$items = [];
$items[] = [
'label' => 'Dashboard',
'icon' => 'dashboard',
'link' => $url('home'),
'route' => ['home'],
];
$items[] = [
'label' => 'About Us',
'icon' => 'business',
'link' => $url('about', ['action'=>'index']),
'route' => ['about'],
];
$items[] = [
'label' => 'Service',
'icon' => 'service',
'link' => $url('service', ['action'=>'index']),
'route' => ['service'],
];
return $items;
}
Создать вспомогательную фабрику
namespace Application\View\Helper\Factory;
use Interop\Container\ContainerInterface;
use Zend\ServiceManager\Factory\FactoryInterface;
use Application\View\Helper\Menu;
use Application\Service\NavManager;
/**
* This is the factory for Menu view helper. Its purpose is to
instantiate the helper and init menu items. */
class MenuFactory implements FactoryInterface {
public function __invoke(ContainerInterface $container, $requestedName, array $options = null) {
$navManager = $container->get(NavManager::class);
// Get menu items.
$items = $navManager->getMenuItems();
// Instantiate the helper.
return new Menu($items);
}
}
Создать помощника:
namespace Application\View\Helper;
use Zend\View\Helper\AbstractHelper;
/**
* This view helper class displays a menu bar.
*/
class Menu extends AbstractHelper {
/**
* Menu items array.
* @var array
*/
protected $items = [];
/**
* Active item's ID.
* @var string
*/
protected $activeItemId = '';
/**
* Constructor.
* @param array $items Menu items.
*/
public function __construct($items=[]) {
$this->items = $items;
}
/**
* Sets menu items.
* @param array $items Menu items.
*/
public function setItems($items) {
$this->items = $items;
}
/**
* Sets ID of the active items.
* @param string $activeItemId
*/
public function setActiveItemId($activeItemId) {
$this->activeItemId = $activeItemId;
}
/**
* Renders the menu.
* @return string HTML code of the menu.
*/
public function render() {
if (count($this->items)==0) {
return ''; // Do nothing if there are no items.
}
// Render items
foreach ($this->items as $item) {
$result .= $this->renderItem($item);
}
return $result;
}
protected function renderItem($item) {
// here you can integrate with HTML
return $item;
}
}
После добавления вышеуказанных кодов просто добавьте следующий код в файл макета:
echo $this->mainMenu()->render();
Других решений пока нет …