J'apprends actuellement ZF2 en développant une petite application MVC basée approximativement sur l'application squelette. À l'heure actuelle, j'essaie de masquer certains éléments HTML fixes en fonction de la route recherchée: à titre d'exemple, je ne souhaite pas que le menu principal s'affiche pendant la phase de connexion.
Je peux le faire facilement en transmettant les paramètres de bascule en tant que valeurs de retour des actions du contrôleur, mais cela ne me convient pas. Je voudrais simplement vérifier la route correspondante dans la présentation et composer celle-ci en conséquence.
Le problème, c'est que je ne sais pas comment obtenir l'itinéraire correspondant dans le modèle. Est-ce possible? Existe-t-il d'autres solutions pour éviter l'ajout d'une logique de présentation dans les contrôleurs?
Edit après quelques bons travaux de Frankenstein, j'ai pu trouver une solution à cela. J'aime l'idée d'utiliser un assistant, alors j'ai juste essayé de lui passer l'objet Application, à partir de la fonction boostrap du module principal:
$app = $e->getApplication();
$serviceManager = $app->getServiceManager();
....
$serviceManager->get('viewhelpermanager')->setFactory('getRoute', function($sm) use ($app) {
return new Helper\GetRoute($app);
});
et la fonction d'assistance:
use Zend\View\Helper\AbstractHelper;
class GetRoute extends AbstractHelper {
private $sm;
public function __construct($app) {
$this->sm = $app->getServiceManager();
}
public function echoRoute() {
$router = $this->sm->get('router');
$request = $this->sm->get('request');
$routeMatch = $router->match($request);
if (!is_null($routeMatch))
echo $routeMatch->getMatchedRouteName();
}
}
peut-être y a-t-il un moyen plus propre, plus ZF2ish de le faire ...
Une autre solution sans nouvelle correspondance
$routeMatch = $serviceLocator->get('Application')->getMvcEvent()->getRouteMatch();
echo $routeMatch->getMatchedRouteName();
Il existe un moyen d'obtenir le gestionnaire de service dans la mise en page:
$sm = $this->getHelperPluginManager()->getServiceLocator();
et alors vous pouvez accéder à $sm->get('router')
etc.
Vous pouvez créer un assistant de vue qui implémente ServiceManagerAwareInterface. Ensuite, à l'intérieur de l'assistant View, utilisez l'instance ServiceManager pour extraire le routeur et les objets de requête, puis reconstruisez la correspondance de route.
$services = $this->getServiceManager();
$router = $services->get('router');
$request = $services->get('request');
$routeMatch = $router->match($request);
echo $routeMatch->getMatchedRouteName();
Je vous recommande également d'écrire l'assistant View afin que le code ne soit déclenché qu'une seule fois par demande.
Lorsque vous passez à ZF3, vous devriez envisager d'utiliser cette méthode ... puisque getLocator n'est plus disponible (et que ce n'est pas correct, l'injecter).
Créer l'assistant
namespace Application\View\Helper;
use Zend\Http\Request;
use Zend\Router\RouteStackInterface;
use Zend\View\Helper\AbstractHelper;
/**
* Helper to get the RouteMatch
*/
class RouteMatch extends AbstractHelper
{
/**
* RouteStackInterface instance.
*
* @var RouteStackInterface
*/
protected $router;
/**
* @var Request
*/
protected $request;
/**
* RouteMatch constructor.
* @param RouteStackInterface $router
* @param Request $request
*/
public function __construct(RouteStackInterface $router, Request $request)
{
$this->router = $router;
$this->request = $request;
}
/**
* @return \Zend\Router\RouteMatch
*/
public function __invoke()
{
return $this->router->match($this->request);
}
}
Créer une usine pour cette aide
namespace Application\View\Helper;
use Interop\Container\ContainerInterface;
use Zend\ServiceManager\Factory\FactoryInterface;
class RouteMatchFactory implements FactoryInterface
{
public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
{
$router = $container->get('router');
$request = $container->get('request');
return new RouteMatch($router, $request);
}
}
Appelez votre fabrique sur votre Module.php
et créez un alias pour cela.
public function getViewHelperConfig()
{
return array(
'factories' => array(
RouteMatch::class => RouteMatchFactory::class,
),
'aliases' => array(
'routeMatch' => RouteMatch::class,
)
);
}
C'est ça ... vous avez un RouteMatch Helper utilisant les nouvelles normes ZF3.
Au revoir!
En vue, vous pouvez utiliser:
$this->getHelperPluginManager()->getServiceLocator()->get('request')->getUri()->getPath();
ou
$this->getHelperPluginManager()->getServiceLocator()->get('request')->getUri()->toString();
Je crois que vous pouvez le résoudre en trouvant les noms d'action/contrôleur:
$controller = $this->getRequest()->getControllerName();
$action = $this->getRequest()->getActionName();
Une fois que vous connaissez l'action, vous pouvez avoir des conditions spécifiques pour activer les sections de la mise en page.
Je vois que tu peux utiliser
$this->getHelperPluginManager()->getServiceLocator()->get('Application')->getMvcEvent()->getRouteMatch()->getMatchedRouteName();
Informations supplémentaires sur le message "Rodrigo Boratto" pour l'intégration de getRouteMatch dans ZF3 (je ne peux pas commenter car je dispose de moins de 50 repo ...)
Dans la vue auxiliaire, classez ces lignes:
use Zend\Mvc\Router\RouteMatch as MvcRouteMatch;
use Zend\Mvc\Router\RouteStackInterface;
devrait être:
use Zend\Router\RouteMatch as MvcRouteMatch;
use Zend\Router\RouteStackInterface;
Je ne sais pas quand ils ont apporté cette modification, mais les fichiers se trouvent dans l'espace de noms Zend\Router.
P.S. J'utilise compositeur si ça compte.
Dans n'importe quelle vue ou disposition, vous pouvez tester l'itinéraire avec cette fonction:
<?php function itsRoute($routeName){
$flag = false;
if($this->serverUrl(true) == $this->url($route,[],['force_canonical'=>true]))){
$flag = true;
}
return $flag;
}
Mon contrôleur:
<?PHP
namespace SomeName\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
class SomeController extends AbstractActionController
{
public function getIdAction()
{
$id = $this->params()->fromRoute('id', 0);
return new ViewModel(array(
'id' => $id,
));
}
}
Mon routeur:
<?php
return array(
'controllers' => array(
'invokables' => array(
'SomeName\Controller\Some' => 'SomeName\Controller\SomeController',
),
),
'router' => array(
'routes' => array(
'testId' => array(
'type' => 'segment',
'options' => array(
'route' => '/[:id]',
'constraints' => array(
'id' => '\d*',
),
'defaults' => array(
'controller' => 'SomeName\Controller\Some',
'action' => 'getId',
),
),
),
),
),
'view_manager' => array(
'template_path_stack' => array(
'album' => __DIR__ . '/../view',
),
),
);