I have custom router and I have to get access to Zend\Navigation
inside this custom router. I was googling, asking and searching and no results :/
All I need is to find nodes with 'link' param using Zend\Navigation in my Alias::match function.
Here is my module.config.php:
'navigation' => array(
'default' => array(
'account' => array(
'label' => 'Account',
'route' => 'node',
'pages' => array(
'home' => array(
'label' => 'Dashboard',
'route' => 'node',
'params' => array(
'id' => '1',
'link' => '/about/gallery'
),
),
),
),
),
),
[...]
And here is my Alias class:
// file within ModuleName/src/ModuleName/Router/Alias.php
namespace Application\Router;
use Traversable;
use Zend\Mvc\Router\Exception;
use Zend\Stdlib\ArrayUtils;
use Zend\Stdlib\RequestInterface as Request;
use Zend\Mvc\Router\Http;
use Zend\ServiceManager\ServiceLocatorAwareInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
class Alias extends Http\Segment implements ServiceLocatorAwareInterface
{
public function setServiceLocator(ServiceLocatorInterface $serviceLocator)
{
$this->serviceLocator = $serviceLocator;
return $this;
}
public function getServiceLocator()
{
return $this->serviceLocator;
}
public function match(Request $request, $pathOffset = null)
{
[...]
return parent::match($request, $pathOffset);
}
}
EDITED:
Now i know that I should inject service manager into my custom router. Let me know if You know how to do this :)
EDITED:
Ok, its not custom router but route. My bad. I was talking on #zftalk
irc chanell and AliasSegment
class should implements ServiceLocatorAwareInterface
. Ok I've tried it but now there is another problem.
In setServiceLocator
function i can't get service locator
. It returns null object, however $serviceLocator
is class Zend\Mvc\Router\RoutePluginManager
.
public function setServiceLocator(ServiceLocatorInterface $serviceLocator){
$sl = $serviceLocator->getServiceLocator();
var_dump($sl); // NULL
}
Any ideas how to get Zend navigation from it ?
EDITED
Corresponding to what @mmmshuddup said, I've changed my custom router class. (New version is above). Also in my Module.php
, within onBootstrap
function, I added this line:
$sm->setFactory('Navigation', 'Zend\Navigation\Service\DefaultNavigationFactory', true);
Navigation works and its instantiated before route
so it should be visible within my Alias class but it's not.
I've put into my match
function in Alias
class this line:
$servicesArray = $this->getServiceLocator()->getRegisteredServices();
and $servicesArray
is almost empty. There is no service, no factories. The same line inserted into onBootstrap
, just after setting new factory (as above) returns array with navigation
and other services.
The question is: how can i share this array (or ServiceManager) with my custom router: Alias
?
I have to say that all I want to do was possible in ZF1 and it was quite easy.
EDIT
I found a solution. The answer is below
I found the solution but this is NOT elegant solution i think. However everything works perfectly. If somebody knows disadvantages of this solution, please comment this answer or add another, better. I had to modify @mmmshuddup's idea (you can read the conversation).
First of all, the implementation of
ServiceLocatorAwareInterface
in custom route class is no more necessary.In
Module.php
withinonBootstrap
function:First we instantiate
Navigation
factory inServiceManager
and then our custom route. After that we can pass Navigation class into custom route usingsetNavigation
function. To complete instantiate of our custom route we need ingetServiceConfig
in the same file:And here is a tricky part. This instance is temporary. While routing, this class will be instantiated one more time and this is why, I think, it's not very elegant. We have to insert parameter into constructor however at this moment value of this parameter is not important.
The custom route class:
Because first instance is temporary, we have to collect our
Navigation
class in static variable. It's awful but works nice. Maybe there is a way to instantiate it only once and in route configuration get instance of it, but at this moment this is best answer for my question. Simply enough and working correctly.That is because the object itself really doesn't have any properties declared. But if you do this:You will see that it is indeed an instance of
Zend\ServiceManager\ServiceManager
You should be able to get your navigation instance by doing something like:
EDIT:
I just notice you have some stuff in the wrong location of your code. You're calling
getServiceLocator()
on$serviceLocator
which is already the instance of that. Also you're calling it withinsetServiceLocator()
. You should change it to: