We have more than two RESTful modules (Restful & Testservices). Only one REST module is working at a time.
If I rearranged the Modules order in application.config.php , the last module of REST api is working .
For example if I keep 'Testservices' module after " Restful" module , "Testservices" is working.
Exmple - Testservices : http://localhost/dev/public/testservices/Userslist is working fine .
If I am calling this http://localhost/dev/public/restful/stateslist getting the following error :
A 404 error occurred
Page not found.
The requested controller was unable to dispatch the request.
Controller:
Application\Controller\Index
If I keep if I keep ' Restful ' module after " Testservices " module , " Restful " is working. Getting errors just reverse of above.
Here is the application.config.php
return array(
// This should be an array of module namespaces used in the application.
'modules' => array(
'DoctrineModule',
'DoctrineORMModule',
'Application',
'Ads',
'Consumer',
'Restful',
'Cron',
'Admin',
'Payment',
'Frontoffice',
'Onboarding',
'Testservices',
),
// These are various options for the listeners attached to the ModuleManager
'module_listener_options' => array(
// This should be an array of paths in which modules reside.
// If a string key is provided, the listener will consider that a module
// namespace, the value of that key the specific path to that module's
// Module class.
'module_paths' => array(
'./module',
'./vendor',
),
// An array of paths from which to glob configuration files after
// modules are loaded. These effectively overide configuration
// provided by modules themselves. Paths may use GLOB_BRACE notation.
'config_glob_paths' => array(
'config/autoload/{,*.}{global,local}.php',
),
// Whether or not to enable a configuration cache.
// If enabled, the merged configuration will be cached and used in
// subsequent requests.
//'config_cache_enabled' => $booleanValue,
// The key used to create the configuration cache file name.
//'config_cache_key' => $stringKey,
// Whether or not to enable a module class map cache.
// If enabled, creates a module class map cache which will be used
// by in future requests, to reduce the autoloading process.
//'module_map_cache_enabled' => $booleanValue,
// The key used to create the class map cache file name.
//'module_map_cache_key' => $stringKey,
// The path in which to cache merged configuration.
//'cache_dir' => $stringPath,
// Whether or not to enable modules dependency checking.
// Enabled by default, prevents usage of modules that depend on other modules
// that weren't loaded.
// 'check_dependencies' => true,
),
// Used to create an own service manager. May contain one or more child arrays.
//'service_listener_options' => array(
// array(
// 'service_manager' => $stringServiceManagerName,
// 'config_key' => $stringConfigKey,
// 'interface' => $stringOptionalInterface,
// 'method' => $stringRequiredMethodName,
// ),
// )
// Initial configuration with which to seed the ServiceManager.
// Should be compatible with Zend\ServiceManager\Config.
// 'service_manager' => array(),
);
Here is the module.config.php for Restful module
namespace Restful;
return array(
'controllers' => array(
'invokables' => array(
'Restful\Controller\Stateslist' => 'Restful\Controller\StateslistController',
'Restful\Controller\Citieslist' => 'Restful\Controller\CitieslistController',
),
),
'router' => array(
'routes' => array(
'api' => array(
'type' => 'Literal',
'options' => array(
'route' => '/Restful',
'defaults' => array(
'__NAMESPACE__' => 'Restful\Controller',
),
),
'may_terminate' => true,
'child_routes' => array(
'default' => array(
'type' => 'Segment',
'options' => array(
'route' => '/[:controller]',
'constraints' => array(
'controller' => '[a-zA-Z][a-zA-Z0-9_-]*'
),
'defaults' => array(
),
),
),
),
),
),
),
'view_manager' => array(
'template_path_stack' => array(
'api' => __DIR__ . '/../view',
),
'strategies' => array(
'ViewJsonStrategy'
)
),
);
Here is the module.config.php for Testservices module
namespace Testservices;
return array(
'controllers' => array(
'invokables' => array(
'Testservices\Controller\Userslist' => 'Testservices\Controller\Userslist',
'Testservices\Controller\Roleslist' => 'Testservices\Controller\RoleslistController',
),
),
'router' => array(
'routes' => array(
'api' => array(
'type' => 'Literal',
'options' => array(
'route' => '/Testservices',
'defaults' => array(
'__NAMESPACE__' => 'Testservices\Controller',
),
),
'may_terminate' => true,
'child_routes' => array(
'default' => array(
'type' => 'Segment',
'options' => array(
'route' => '/[:controller]',
'constraints' => array(
'controller' => '[a-zA-Z][a-zA-Z0-9_-]*'
),
'defaults' => array(
),
),
),
),
),
),
),
'view_manager' => array(
'template_path_stack' => array(
'api' => __DIR__ . '/../view',
),
'strategies' => array(
'ViewJsonStrategy'
)
),
);
Thanks for your help in advance.
Both your routes use the key api in module.config.php I assume when this all gets merged together the last one loaded wins. Change one of them like:
'router' => array(
'routes' => array(
'api_changed' => array(
'type' => 'Literal',
'options' => array(
'route' => '/Testservices',
'defaults' => array(
'__NAMESPACE__' => 'Testservices\Controller',
),
),
'may_terminate' => true,
'child_routes' => array(
'default' => array(
'type' => 'Segment',
'options' => array(
'route' => '/[:controller]',
'constraints' => array(
'controller' => '[a-zA-Z][a-zA-Z0-9_-]*'
),
'defaults' => array(
),
),
),
),
),
),
),
Where api has been updated to api_changed
Related
I have ported my Zend Framework application to a different server. It's a Zend Framework application version 2.3.*
Now when going to this url http://calendar.app/calendar I get the following error:
Fatal error: Class 'Calendar\Controller\CalendarController' not found in /home/vagrant/Code/calendar/vendor/zendframework/zendframework/library/Zend/ServiceManager/AbstractPluginManager.php on line 170
My CalendarControler lives in my calendar module which is loaded like
return array(
'controllers' => array(
'invokables' => array(
'Calendar' => 'Calendar\Controller\CalendarController',
),
),
'router' => array(
'routes' => array(
'calendar' => array(
'type' => 'Literal',
'options' => array(
'route' => '/calendar',
'defaults' => array(
'controller' => 'calendar',
'action' => 'index',
),
),
),
),
),
'view_manager' => array(
'template_path_stack' => array(
__DIR__ . '/../view',
),
),
);
I tried
composer clear-cache
composer dump-autoload
But this didn't help.
How could I fix this.
Your Calendar declaration inside the array is wrong. You need to use the full name in the array in order for Zend to find the class.
return array(
'controllers' => array(
'invokables' => array(
'Calendar\ControllerCalendar' => 'Calendar\Controller\CalendarController',
),
'alias' => array(
'Calendar' => 'Calendar\ControllerCalendar',
),
),
'router' => array(
'routes' => array(
'calendar' => array(
'type' => 'Literal',
'options' => array(
'route' => '/calendar',
'defaults' => array(
'controller' => 'calendar',
'action' => 'index',
),
),
),
),
),
'view_manager' => array(
'template_path_stack' => array(
__DIR__ . '/../view',
),
),
Aside fro this error. Consider using controller factories if your class has hard dependancies or you are using the service manager like $this->getServiceLocator() inside your controller. :)
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
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
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.
I have created new module called 'currency' and configured routes in module.config. It is working fine.
After that I have added new controller called CrateController for currency rates.And also created forms, models and view files.
But It is not routing correctly.
Error:
Fatal error: Uncaught exception 'Zend\View\Exception\RuntimeException' with message 'Zend\View\Renderer\PhpRenderer::render: Unable to render template "currency/crate/index"; resolver could not resolve to a file....
Any clue to check this out will be helpful.
My module.config file as follows.
return array(
'controllers' => array(
'invokables' => array(
'Currency\Controller\Currency' => 'Currency\Controller\CurrencyController',
'Currency\Controller\Crate' => 'Currency\Controller\CrateController',
),
),
// The following section is new and should be added to your file
'router' => array(
'routes' => array(
'currency' => array(
'type' => 'segment',
'options' => array(
'route' => '/currency[/:action][/:currency_id]',
'constraints' => array(
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'currency_id' => '[0-9]+',
),
'defaults' => array(
'controller' => 'Currency\Controller\Currency',
'action' => 'index',
),
),
),
'crate' => array(
'type' => 'segment',
'options' => array(
'route' => '/crate[/:action][/:c_rate_id]',
'constraints' => array(
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'c_rate_id' => '[0-9]+',
),
'defaults' => array(
'controller' => 'Currency\Controller\Crate',
'action' => 'index',
),
),
),
),
),
Check for two things:
First: Is the template file present? ./module/Currency/view/currency/crate/index.phtml
Second: Check for the following entry inside ./Currency/config/module.config.php
'view_manager' => array(
'template_path_stack' => array(
'currency' => __DIR__ . '/../view',
)
),