ZF2 run the application without using the router - php

I am learning ZF2.
Is it possible to run the application without Router as in Zf1?
Do we need to define router for each controller?
Example:
In ZF1: "admin/index/index" shows as "module/controller/action"
IN ZF2: "admin/index/index" shows as "router[/:controller][/:action]"
please help me to clear my doubts.

Please tyr this
return array(
// routes
'router' => array(
'routes' => array(
'album' => array(
'type' => 'Literal',
'options' => array(
'route' => '/album',
'defaults' => array(
'controller' => 'album\Controller\Index',
'action' => 'index',
),
),
'may_terminate' => true,
'child_routes' => array(
'default' => array(
'type' => 'Segment',
'options' => array(
'route' => '/[:controller[/:action]]',
'constraints' => array(
'controller' => '[a-zA-Z][a-zA-Z0-9_-]*',
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
),
'defaults' => array(
// add the default namespace for :controllers in this route
'__NAMESPACE__' => 'album\Controller',
),
),
),
),
),
),
),
'controllers' => array(
'invokables' => array(
'album\Controller\Test' => 'Album\Controller\TestController',
),
),
'view_manager' => array(
'template_path_stack' => array(
'album' => __DIR__ . '/../view',
),
),
);
You need to add your controller name in invokables manually or invoke via Abstract Factories
'controllers' => array(
'invokables' => array(
'album\Controller\Test' => 'Album\Controller\TestController',
),
),
Automatic Controller Invokables via Abstract Factories
Reference

Related

Zend2 Routing __NAMESPACE__ doesn't work or be ignored

I'm using this config as my application module config in Zend2 which is really normal and every one suggested as a standard routing rule:
'controllers' => array(
'invokables' => array(
'Application\Controller\Index' => 'Application\Controller\IndexController',
),
),
'router' => array(
'routes' => array(
'home' => array(
'type' => 'Zend\Mvc\Router\Http\Literal',
'options' => array(
'route' => '/',
'defaults' => array(
'controller' => 'Application\Controller\Index',
'action' => 'index',
),
),
),
'application' => array(
'type' => 'Zend\Mvc\Router\Http\Literal',
'options' => array(
'route' => '/application',
'defaults' => array(
'__NAMESPACE__' => 'Application\Controller',
'controller' => 'Index',
'action' => 'index',
),
),
'may_terminate' => true,
'child_routes' => array(
'default' => array(
'type' => 'Zend\Mvc\Router\Http\Segment',
'options' => array(
'route' => '/[:controller[/:action]]',
'constraints' => array(
'controller' => '[a-zA-Z][a-zA-Z0-9_-]*',
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
),
'defaults' => array(
),
),
),
),
),
),
),
the routing for home works fine. but for http://localhost/application I get:
Index(resolves to invalid controller class or alias: Index)
and for http://localhost/application/index/index I get:
index(resolves to invalid controller class or alias: index)
if I change this:
'application' => array(
'type' => 'Zend\Mvc\Router\Http\Literal',
'options' => array(
'route' => '/application',
'defaults' => array(
'__NAMESPACE__' => 'Application\Controller',
'controller' => 'Index',
'action' => 'index',
),
),
to this:
'application' => array(
'type' => 'Zend\Mvc\Router\Http\Literal',
'options' => array(
'route' => '/application',
'defaults' => array(
'controller' => 'Application\Controller\Index',
'action' => 'index',
),
),
As you know definitely for http://localhost/application it will work fine like home url
if I use this:
'controllers' => array(
'invokables' => array(
'index' => 'Application\Controller\IndexController',
),
),
as you know the configurations will merge and I should have just one index controller in the project.
Why the line '__NAMESPACE__' => 'Application\Controller', be ignored and it looks for just Index or index in the controllers array which no exist??
EDIT:
With comparing to other projects I added this to Application/Module.php :
public function onBootstrap(MvcEvent $e)
{
$eventManager = $e->getApplication()->getEventManager();
$moduleRouteListener = new ModuleRouteListener();
$moduleRouteListener->attach($eventManager);
}
and it works now but I need and explanation. is it the solution? I mean should I add this to one of Module.php files in the project to make routing rules work fine? and why without it the __NAMESPACE__ will be ignored in routing rules?
You already found the solution, adding the ModuleRouteListener is the right thing to do. The explanation can be found in the description of the onRoute method inside this listener:
Listen to the "route" event and determine if the module namespace should be prepended to the controller name.
If the route match contains a parameter key matching the MODULE_NAMESPACE constant, that value will be prepended, with a namespace separator, to the matched controller parameter.

ZF2 route to controller

I have created a controller called "ActividadesPlanificadasController.php" and I have defined in my module.config the next routing but it is not work.
'publico/peticiones-incidencias-planificadas/actividades-planificadas' => array(
'type' => 'Literal',
'options' => array(
'route' => 'publico/peticiones-incidencias-planificadas/actividades-planificadas',
'defaults' => array(
'__NAMESPACE__' => 'Privado\Controller',
'controller' => 'Index',
'action' => 'index',
),
),
'may_terminate' => true,
'child_routes' => array(
'default' => array(
'type' => 'Segment',
'options' => array(
//'route' => '/[:controller[/:action[/:id]]]',
'route' => '/[:controller[/:action][/:id/:system]]',
'constraints' => array(
'controller' => '[a-zA-Z][a-zA-Z0-9_-]*',
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'id' => '[0-9]*',
'system' => '[a-zA-Z][a-zA-Z0-9_-]*'
//'system' => '[0-9]*'
),
'defaults' => array(
),
),
),
),
),
These are my controllers ...
'controllers' => array(
'invokables' => array(
'Publico\Controller\Index' => Controller\IndexController::class,
'Publico\Controller\Login' => Controller\LoginController::class,
'Publico\Controller\NoAccess' => Controller\NoAccessController::class,
'Publico\Controller\ActividadesPlanificadas' => Controller\ActividadesPlanificadasController::class
),
),
Because I want to access to my controller with the next url: http://gnsys.local/publico/peticiones-incidencias-planificadas/actividades-planificadas
And I've got the next error ...
A 404 error occurred
Page not found.
The requested controller could not be mapped to an existing controller class.
Controller:
Publico\Controller\PeticionesIncidenciasPlanificadas(resolves to invalid controller class or alias: Publico\Controller\PeticionesIncidenciasPlanificadas)
No Exception available
What am I doing wrong?
Edit 1:
I have updated my module.config and it works with the route: http://gnsys.local/publico/actividades-planificadas
module.config:
'publico/actividades-planificadas' => array(
'type' => 'Literal',
'options' => array(
'route' => 'publico/actividades-planificadas',
'defaults' => array(
'__NAMESPACE__' => 'Publico\Controller',
'controller' => 'Index',
'action' => 'index',
),
),
'may_terminate' => true,
'child_routes' => array(
'default' => array(
'type' => 'Segment',
'options' => array(
//'route' => '/[:controller[/:action[/:id]]]',
'route' => '/[:controller[/:action][/:id/:system]]',
'constraints' => array(
'controller' => '[a-zA-Z][a-zA-Z0-9_-]*',
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'id' => '[0-9]*',
'system' => '[a-zA-Z][a-zA-Z0-9_-]*'
//'system' => '[0-9]*'
),
'defaults' => array(
),
),
),
),
),
'controllers' => array(
'invokables' => array(
'Publico\Controller\Index' => Controller\IndexController::class,
'Publico\Controller\Login' => Controller\LoginController::class,
'Publico\Controller\NoAccess' => Controller\NoAccessController::class,
'Publico\Controller\ActividadesPlanificadas' => Controller\ActividadesPlanificadasController::class
),
),
But I want that my route to access to ActividadesPlanificadasController would be: http://gnsys.local/publico/peticiones-incidencias-actividades/actividades-planificadas
If I change my module.config to ...
'publico/peticiones-incidencias-planificadas/actividades-planificadas' => array(
'type' => 'Literal',
'options' => array(
'route' => 'publico/peticiones-incidencias-planificadas/actividades-planificadas',
'defaults' => array(
'__NAMESPACE__' => 'Publico\Controller',
'controller' => 'Index',
'action' => 'index',
),
),
'may_terminate' => true,
'child_routes' => array(
'default' => array(
'type' => 'Segment',
'options' => array(
//'route' => '/[:controller[/:action[/:id]]]',
'route' => '/[:controller[/:action][/:id/:system]]',
'constraints' => array(
'controller' => '[a-zA-Z][a-zA-Z0-9_-]*',
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'id' => '[0-9]*',
'system' => '[a-zA-Z][a-zA-Z0-9_-]*'
//'system' => '[0-9]*'
),
'defaults' => array(
),
),
),
),
),
I've got the error
A 404 error occurred Page not found.
The requested controller could not be mapped to an existing controller class.
Controller: Publico\Controller\PeticionesIncidenciasPlanificadas(resolves to
invalid controller class or alias:
Publico\Controller\PeticionesIncidenciasPlanificadas)
No Exception available
What am I still doing wrong?
You point to a controller called 'Privado\Controller\Index' but your invokable is called 'Publico\Controller\Index'.
Change the namespace so it corresponds.
Privado -> Publico
or
Publico -> Privado
or add a controller for 'Privado\Controller\Index'
'invokables' => array(
'Privado\Controller\Index' => //your privado controller,
//...other controllers...
)
UPDATE
Make also sure you have an invokable controller class in the correct namespace. So if you register like this:
'invokables' => array(
'Privado\Controller\Index' => 'Privado\Controller\IndexController'
)
You need a controller class in a php file called IndexController.php in the folder Privado - Controller
- Privado
- Controller
- IndexController.php
And the class should have the correct name and namespace constant:
<?php
namespace = Privado\Controller;
class IndexController extends ... {
}

ZF2 - The requested URL could not be matched by routing

i receive this error when i go to
localhost/app/public/spanel/test/index
This application have a sPanel module. Into it have a TestController with indexAction()
This is the sPanel\config\module.config.php
<?php
return array(
'controllers' => array(
'invokables' => array(
'sPanel\Controller\Test' => 'sPanel\Controller\TestController',
),
),
'router' => array(
'routes' => array(
'spanel' => array(
'type' => 'segment',
'options' => array(
'route' => '/test[/:action][/:id]',
'constraints' => array(
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'id' => '[0-9]+',
),
'defaults' => array(
'controller' => 'sPanel\Controller\Test',
'action' => 'index',
),
),
),
),
),
'view_manager' => array(
'template_path_stack' => array(
'spanel' => __DIR__ . '/../view',
),
),
);
First of all i strongly suggest that you start working with virtual hosts to get rid of that annoying localhost/bla/public
Second of all things, you try to access this route: yourdomain/spanel/test/index, but there is no indication of you assigning the part /spanel anywhere in your route, all you assign is /test[...]
So in short, you want to access yourdomain/test/index or you want to modify your route to inclide the /spanel part

Multiple routes under same tree in ZF2

I am having problem while implementing Multiple routes as defined Below in my snippet
EDIT: i am getting this exception too
Additional information:
Zend\Mvc\Exception\InvalidControllerException
with Message
Controller of type Account\Controller\VoucherController is invalid; must implement Zend\Stdlib\DispatchableInterface
<?php
namespace Account;
return array(
'controllers' => array(
'invokables' => array(
'Account\Controller\Account' => 'Account\Controller\AccountController',
'Account\Controller\Voucher' => 'Account\Controller\VoucherController',
),
// --------- Doctrine Settings For the Module
'doctrine' => array(
'driver' => array(
'account_entities' => array(
'class' => 'Doctrine\ORM\Mapping\Driver\AnnotationDriver',
'cache' => 'array',
'paths' => array(__DIR__ . '/../src/Account/Entity')
),
'orm_default' => array(
'drivers' => array(
'Account\Entity' => 'account_entities'
)
)
)
),
// The following section is new and should be added to your file
'router' => array(
'routes' => array(
'account' => array(
'type' => 'segment',
'options' => array(
'route' => '/account[/][:action][/:id]',
'constraints' => array(
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'id' => '[0-9]+',
),
'defaults' => array(
'controller' => 'Account\Controller\Account',
'action' => 'index',
),
),
),
'voucher' => array(
'type' => 'segment',
'options' => array(
'route' => '/account/voucher[/][:action][/:id]',
'constraints' => array(
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'id' => '[0-9]+',
),
'defaults' => array(
'controller' => 'Account\Controller\Voucher',
'action' => 'index',
),
),
),
),
),
'view_manager' => array(
'template_path_stack' => array(
'account' => __DIR__ . '/../view',
),
),
),
);
Now the issue is i am getting a 404, when i try to access MyHost/account/Voucher
P.S: I already have A Controller under Account/Controller/Voucher and a view under Account/View/Voucher named as index.phtml now i dont know what am i missing here.
As Adnrew and Timdev comments above that there is something not right in your controller, you can check few basic things in your controller, that you have following code correct. specially the typos.
namespace Account\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
class VoucherController extends AbstractActionController {
// you acctions
}

Routes with multiple modules

I'm currently working in ZF2 and need some help.
Unfortunately I can only find examples set the routes for the case that there is only one module. Or the example has still the application module in it, with dynamic segment routes. I want to totally remove the application module and only have my own modules running an configure all routing in them.
I have two modules:
CLFrontend,
CLBackend
My application config looks like this:
return array(
'modules' => array(
'ClFrontend',
'ClBackend'
),
'module_listener_options' => array(
'config_glob_paths' => array(
'config/autoload/{,*.}{global,local}.php',
),
'module_paths' => array(
'./module',
'./vendor',
),
),
);
I want to register my 2 own modules there. The routing should now look someway like this:
everything under / should go to the frontend module excerpt /backend
/ --> IndexController --> indexaction
/controller1 --> Controller1Controller -> indexaction
/controller1/add --> Controller1Controller --> addaction
/controller1/add/1/ --> COntroller1Controller --> addaction --> item 1
Now should everything under /backend route to the backend module
/backend --> BackendIndexController --> indexaction
/backend/controller1 --> BackendController1Controller -> indexaction
/backend/controller1/add --> BackendController1Controller -->
addaction
/backend/controller1/add/1/ --> BackendCOntroller1Controller -->
addaction --> item 1
And i want to define that routes fixed and not something like a segment route looking like that:
:module/:controller/:action
I want to end up with something like
/
/controller1/[:action[/:id]]
AND
/backend
/backend/backendcontroller/[:action[/:id]]
Myapproach was the following. The problem is now, that even the backend routes seem to match to the frontend module?! I either get a 404 with
The requested URL could not be matched by routing.
Or
Fatal error: Class 'ClBackend\Controller\AnswerController' not found
in
//*/**/***/checklistenassistent3/vendor/ZF2/library/Zend/ServiceManager/AbstractPluginManager.php
on line 177
CLFrontend/config/module.config.php
return array(
'controllers' => array(
'invokables' => array(
'ClFrontend\Controller\Index' => 'ClFrontend\Controller\IndexController',
'ClFrontend\Controller\User' => 'ClFrontend\Controller\UserController',
),
),
'router' => array(
'routes' => array(
'home' => array(
'type' => 'Zend\Mvc\Router\Http\Literal',
'options' => array(
'route' => '/',
'defaults' => array(
'controller' => 'ClFrontend\Controller\Index',
'action' => 'index',
),
),
),
),
),
'view_manager' => array(
'display_not_found_reason' => true,
'display_exceptions' => true,
'doctype' => 'HTML5',
'not_found_template' => 'error/404',
'exception_template' => 'error/index',
'template_map' => array(
'layout/layout' => __DIR__ . '/../view/cl-frontend/layout/layout.phtml',
'application/index/index' => __DIR__ . '/../view/cl-frontend/index/index.phtml',
'error/404' => __DIR__ . '/../view/cl-frontend/error/404.phtml',
'error/index' => __DIR__ . '/../view/cl-frontend/error/index.phtml',
),
'template_path_stack' => array(
__DIR__ . '/../view',
),
),
);
CLBackend/config/module.config.php
return array(
'controllers' => array(
'invokables' => array(
'ClBackend\Controller\Answer' => 'ClBackend\Controller\AnswerController',
'ClBackend\Controller\AnswerGroup' => 'ClBackend\Controller\AnswerGroupController',
'ClBackend\Controller\Category' => 'ClBackend\Controller\CategoryController',
'ClBackend\Controller\Checklist' => 'ClBackend\Controller\ChecklistController',
'ClBackend\Controller\Index' => 'ClBackend\Controller\IndexController',
'ClBackend\Controller\Question' => 'ClBackend\Controller\QuestionController',
'ClBackend\Controller\User' => 'ClBackend\Controller\UserController',
),
),
'router' => array(
'routes' => array(
'backend' => array(
'type' => 'Zend\Mvc\Router\Http\Literal',
'options' => array(
'route' => '/backend',
'defaults' => array(
'controller' => 'ClBackend\Controller\Index',
'action' => 'index',
),
'may_terminate' => true
),
'child_routes' => array (
'answer' => array(
'type' => 'Zend\Mvc\Router\Http\Segment',
'options' => array(
'route' => '/answer/:action/:id',
'defaults' => array(
'controller' => 'ClBackend\Controller\Answer',
'action' => 'index',
),
),
),
'answergroup' => array(
'type' => 'Zend\Mvc\Router\Http\Segment',
'options' => array(
'route' => '/answergroup/:action/:id',
'defaults' => array(
'controller' => 'ClBackend\Controller\AnswerGroup',
'action' => 'index',
),
),
),
'category' => array(
'type' => 'Zend\Mvc\Router\Http\Segment',
'options' => array(
'route' => '/category/:action/:id',
'defaults' => array(
'controller' => 'ClBackend\Controller\Category',
'action' => 'index',
),
),
),
'checklist' => array(
'type' => 'Zend\Mvc\Router\Http\Segment',
'options' => array(
'route' => '/checklist/:action/:id',
'defaults' => array(
'controller' => 'ClBackend\Controller\Checklist',
'action' => 'index',
),
),
),
'question' => array(
'type' => 'Zend\Mvc\Router\Http\Segment',
'options' => array(
'route' => '/question/:action/:id',
'defaults' => array(
'controller' => 'ClBackend\Controller\Question',
'action' => 'index',
),
),
),
'user' => array(
'type' => 'Zend\Mvc\Router\Http\Segment',
'options' => array(
'route' => '/user/:action[/:id]',
'defaults' => array(
'controller' => 'ClBackend\Controller\User',
'action' => 'index',
),
),
),
),
),
),
),
);
Have you considered a Controller factory? It would allow you to match a single route and use logic to decide on which controller to use.
For example your route could look like:
'backend-default' => array(
'type' => 'Segment',
'options' => array(
'route' => '/:controller_type[/:action][/id]',
'defaults' => array(
'action' => 'index',
'controller' => 'MyFactory'
),
),
),
If this route was matched then the Controller factory (MyFactory) would be used - within this factory you can gain access to the route match parameters. Using these parameters you should be able to return the appropriate controller.
You could even pass in an additional parameter signifying it's a backend controller (and use a single factory).
use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
class MyFactoryController implements FactoryInterface
{
public function createService(ServiceLocatorInterface $serviceLocator)
{
// $serviceLocator is a Zend\Mvc\Controller\ControllerManager
$app = $serviceLocator->getServiceLocator()->get('application');
$routeMatch = $app->getMvcEvent()->getRouteMatch();
var_dump($routeMatch);
/**
* Create controller based off $routeMatch params
*/
return $controller;
}
}
The controller factory would allow you to lookup the controller_type variable to a valid class name - or prefix an invokable name to controller_type.
I'm not sure I'd take this route myself but I hope this is somewhat useful for what you are trying to achieve.

Categories