Zend2 Module can't be initialized - zend-framework

Here my Module.php:
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* #link http://github.com/zendframework/ZendSkeletonModule for the canonical source repository
* #copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* #license http://framework.zend.com/license/new-bsd New BSD License
*/
namespace Users;
use Zend\ModuleManager\Feature\AutoloaderProviderInterface;
use Zend\Mvc\ModuleRouteListener;
class Module implements AutoloaderProviderInterface
{
public function getAutoloaderConfig()
{
return array(
'Zend\Loader\ClassMapAutoloader' => array(
__DIR__ . '/autoload_classmap.php',
),
'Zend\Loader\StandardAutoloader' => array(
'namespaces' => array(
// if we're in a namespace deeper than one level we need to fix the \ in the path
__NAMESPACE__ => __DIR__ . '/src/' . __NAMESPACE__,
),
),
);
}
public function getConfig()
{
return include __DIR__ . '/config/module.config.php';
}
public function onBootstrap($e)
{
// You may not need to do this if you're doing it elsewhere in your
// application
$eventManager = $e->getApplication()->getEventManager();
$moduleRouteListener = new ModuleRouteListener();
$moduleRouteListener->attach($eventManager);
}
}
And here my module.config.php:
<?php
return array(
'controllers' => array(
'invokables' => array(
'Users\Controller\Index' => 'Users\Controller\IndexController',
),
),
'router' => array(
'routes' => array(
'users' => array(
'type' => 'Literal',
'options' => array(
// Change this to something specific to your module
'route' => '/users',
'defaults' => array(
// Change this value to reflect the namespace in which
// the controllers for your module are found
'__NAMESPACE__' => 'Users\Controller',
'controller' => 'Index',
'action' => 'index',
),
),
'may_terminate' => true,
'child_routes' => array(
// This route is a sane default when developing a module;
// as you solidify the routes for your module, however,
// you may want to remove it and replace it with more
// specific routes.
'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(
),
),
),
),
),
),
),
'view_manager' => array(
'template_path_stack' => array(
'users' => __DIR__ . '/../view',
),
),
);
But when I try to see the index page I get this:
( ! ) Fatal error: Uncaught
Zend\ModuleManager\Exception\RuntimeException: Module (Users) could
not be initialized. in
/var/www/html/communicationapp/vendor/zendframework/zendframework/library/Zend/ModuleManager/ModuleManager.php
on line 195
( ! ) Zend\ModuleManager\Exception\RuntimeException: Module (Users) could not be initialized. in /var/www/html/communicationapp/vendor/zendframework/zendframework/library/Zend/ModuleManager/ModuleManager.php
on line 195
Anyone knows what's wrong with this code?

A couple of things to check:
The filename is Module.php - that exact case.
That Module.php is in module/Users (i.e. not in module/Users/src/)

I used internal server of php where I don't have xdebug enabled it got this:
127.0.0.1:48908 [500]: /public/ - Uncaught Zend\ModuleManager\Listener\Exception\InvalidArgumentException: Config being merged must be an array, implement the Traversable interface, or be an instance of Zend\Config\Config. boolean given. in /var/www/html/communicationapp/vendor/zendframework/zendframework/library/Zend/ModuleManager/Listener/ConfigListener.php:342
Stack trace:
0 /var/www/html/communicationapp/vendor/zendframework/zendframework/library/Zend/ModuleManager/Listener/ConfigListener.php(127): Zend\ModuleManager\Listener\ConfigListener->addConfig('Users', false)
1 [internal function]: Zend\ModuleManager\Listener\ConfigListener->onLoadModule(Object(Zend\ModuleManager\ModuleEvent))
2 /var/www/html/communicationapp/vendor/zendframework/zendframework/library/Zend/EventManager/EventManager.php(444): call_user_func(Array, Object(Zend\ModuleManager\ModuleEvent))
3 /var/www/html/communicationapp/vendor/zendframework/zendframework/library/Zend/EventManager/EventManager.php(205): Zend\EventManager\EventManager->triggerListeners('loadModule in /var/www/html/communicationapp/vendor/zendframework/zendframework/library/Zend/ModuleManager/Listener/ConfigListener.php on line 342

Related

Zend Framework 2 routing error: resolves to invalid controller class or alias

I'm trying to learn Zend Framework 2 and I have their skeleton application up and running. In order to access it I visit http://localhost:8080/. When visiting that link it displays their generic Zend page. What I want to be able to do is visit http://localhost:8080/application/test and have it bring me to a different page with a different layout.
Here is the module.config.php
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* #link http://github.com/zendframework/ZendSkeletonApplication for the canonical source repository
* #copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
* #license http://framework.zend.com/license/new-bsd New BSD License
*/
return array(
'router' => array(
'routes' => array(
'home' => array(
'type' => 'Zend\Mvc\Router\Http\Literal',
'options' => array(
'route' => '/',
'defaults' => array(
'controller' => 'Application\Controller\Index',
'action' => 'index',
),
),
),
// The following is a route to simplify getting started creating
// new controllers and actions without needing to create a new
// module. Simply drop new controllers in, and you can access them
// using the path /application/:controller/:action
'application' => array(
'type' => 'Literal',
'options' => array(
'route' => '/application',
'defaults' => array(
'__NAMESPACE__' => 'Application\Controller',
'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(
),
),
),
),
),
)
),
'service_manager' => array(
'abstract_factories' => array(
'Zend\Cache\Service\StorageCacheAbstractServiceFactory',
'Zend\Log\LoggerAbstractServiceFactory',
),
'aliases' => array(
'translator' => 'MvcTranslator',
),
),
'translator' => array(
'locale' => 'en_US',
'translation_file_patterns' => array(
array(
'type' => 'gettext',
'base_dir' => __DIR__ . '/../language',
'pattern' => '%s.mo',
),
),
),
'controllers' => array(
'invokables' => array(
'Application\Controller\Index' => 'Application\Controller\IndexController'
),
),
'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/layout/layout.phtml',
'application/index/index' => __DIR__ . '/../view/application/index/index.phtml',
'error/404' => __DIR__ . '/../view/error/404.phtml',
'error/index' => __DIR__ . '/../view/error/index.phtml',
),
'template_path_stack' => array(
__DIR__ . '/../view',
),
),
// Placeholder for console routes
'console' => array(
'router' => array(
'routes' => array(
),
),
),
);
In order to make it work for me this is what I tried:
First I created a controller named TestController in Application/src/Application/Controller/.
Next I added 'application/test/index' => DIR . '/../view/application/test/index.phtml' to the template_map array in view_manager.
I also added 'Application\Controller\Test' => 'Application\Controller\TestController' to the controllers array.
When I visit http://localhost:8080/application/test I get the error:
test(resolves to invalid controller class or alias: test)
I'm obviously doing something wrong but tbh the documentation on Zend is not newb friendly at all and it's becoming very frustrating. Could someone point me in the correct direction? There's just so much configuration that I'm sure I'm missing something small. Thanks!
At the moment the route named application (the parent) defines a URL route of /application. The child route default however requires the controller name to be passed in as the first argument, followed by
action.
This means the URL would be
/application/[:controller]/[:action]
So visting
/application/test
You are inadvertently trying to fetch the 'test' controller; hence the error.
Resolves to invalid controller class or alias : test
To resolve this I would strongly recomend against using the a :controller route parameter but instead use a route per controller action.
'application' => [
'type' => 'Literal',
'options' => [
'route' => '/application',
'defaults' => [
'controller' => 'Application\Controller\Index',
'action' => 'index',
],
'may_terminate' => true,
'child_routes' => [
'test' => [
'type' => 'Literal',
'options' => [
'route' => '/test',
'defaults' => [
// controller value is inherited from parent!
'action' => 'test',
],
],
],
],
],
],

How to add a Restful controller in a Zend module

I'm actually working on a zend framework 2 application which should render two sorts of View :
a view model
a json model
I would include the restful controller in my module but I don't understand if it's possible or recommended.
If someone has been already confronted to a same case, does he could bring me some explanations because I'm searching an answer since 2 days fruitlessly.
In my module.config.php I have :
return array(
'controllers' => array(
'invokables' => array(
'Role\Controller\Role' => 'Role\Controller\RoleController',
'Role\Controller\RoleRest' => 'Role\Controller\RoleRestController',
),
),
'router' => array(
'routes' => array(
'role' => array(
'type' => 'segment',
'options' => array(
'route' => '/role[/:action][/:id]',
'constraints' => array(
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'id' => '[a-zA-Z][a-zA-Z0-9_-]*',
),
'defaults' => array(
'controller' => 'Role\Controller\Role',
'action' => 'index',
),
),
),
'role-rest' => array(
'type' => 'segment',
'options' => array(
'route' => '/role-rest[/:id]',
'constraints' => array(
'id' => '[a-zA-Z][a-zA-Z0-9_-]*',
),
'defaults' => array(
'controller' => 'Role\Controller\RoleRest',
'action' => 'getList',
),
),
),
),
),
'view_manager' => array(
'strategies' => array(
'ViewJsonStrategy',
),
'template_path_stack' => array(
'role' => __DIR__ . '/../view',
),
),
);
and when i try to get myApplication.localhost/role-rest, the page displays the following message :
"The requested controller was unable to dispatch the request.
Controller:
Role\Controller\RoleRest"
I resolve the problem with a simple change in the id's regex constraint :
'constraints' => array(
'id' => '[a-zA-Z0-9_-]*',
),

Including settings in to module class

Im my module.config.php file got following excerpt:
return array(
'service_manager' => array(
'aliases' => array(
'Util\Dao\Factory' => 'modelFactory',
),
'factories' => array(
'modelFactory' => function($sm) {
$dbAdapter = $sm->get('Doctrine\ORM\EntityManager');
return new \Util\Dao\Factory($dbAdapter);
},
)
),
'doctrine' => array(
'driver' => array(
'application_entities' => array(
'class' => 'Doctrine\ORM\Mapping\Driver\AnnotationDriver',
'cache' => 'array',
'paths' => array(
__DIR__ . '/../src/Application/Model'
),
),
'orm_default' => array(
'drivers' => array(
'Application\Model' => 'application_entities'
)
),
),
),
How do i put the block "doctrine" in module class?
Well, this is actually fairly simple. Probably your Module class has the method getConfig(). That method usually loads moduleName/config/module.config.php.
So in whatever function you are, simply call the getConfig()-method. This is pure and basic php ;)
//Module class
public function doSomethingAwesome() {
$moduleConfig = $this->getConfig();
$doctrineConfig = isset($moduleConfig['doctrine'])
? $moduleConfig['doctrine']
: array('doctrine-config-not-initialized');
}
However you need to notice that this only includes your Modules config. If you need to gain access to the merged configuration, you'll need to do that in the onBootstrap()-method. Which would be done like this:
//Module class
public function onBootstrap(MvcEvent $mvcEvent)
{
$application = $mvcEvent->getApplication();
$serviceLocator = $application->getServiceLocator();
$mergedConfig = $serviceLocator->get('config');
$doctrineConfig = isset($mergedConfig['doctrine'])
? $mergedConfig['doctrine']
: array('doctrine-config-not-initialized');
}
This works similar if you're attaching to some events...

Automatic convention-based routing within a module in Zend Framework 2--possible?

I'm trying to understand all the configuration necessary to get my routing working in Zend Framework 2, and I can't help but wonder if I am making this more complicated than necessary.
I am working on a simple app that will follow a very simple convention:
/:module/:controller/:action
I've already created and wired up my module, "svc" (short for "service)". I then created a second controller, the "ClientsController", and I can't get the routing to pass through my requests to, e.g., /svc/clients/list to ClientsController::listAction().
As I'm wading through hundreds of lines of configuration, in deeply nested arrays, I'm thinking--isn't there some way to just have a default mapping of my URLs to /:module/:controller/:action ?
Thanks for any assistance. I'm going off of the Zend Framework 2 Quick Start, which walked me through creating a new module and then adding a controller to that module. But when I tried to add second controller to that module, I am tripping over the routing.
Update: I didn't catch this the first time through, but apparently this is supposed to be a feature of the Zend Framework Skeleton app. From the quick start guide:
ZendSkeletonApplication ships with a “default route” that will likely
get you to this action. That route basically expects
“/{module}/{controller}/{action}”, which allows you to specify this:
“/zend-user/hello/world”
That's exactly what I want! But I can't get it to work.
It lists an incomplete module.config.php, with a comment at the bottom about putting "other configuration" here. I tried to figure out what that "other configuration" is, and wound up with this:
return array(
'svc' => array(
'type' => 'Literal',
'options' => array(
'route' => '/svc',
'defaults' => array(
'controller' => 'svc\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(
),
),
),
),
),
'controllers' => array(
'invokables' => array(
'svc\Controller\Clients' => 'svc\Controller\ClientsController',
),
),
'view_manager' => array(
'template_path_stack' => array(
'album' => __DIR__ . '/../view',
),
),
);
JFYI, here is what my controller looks like.
namespace svc\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
class ClientsController extends AbstractActionController {
public function indexAction() {
return new ViewModel();
}
public function anotherAction(){
return new ViewModel();
}
}
My routes are not working. I get "route not found" when I try to pull up any of my routes.
It lists an incomplete module.config.php, with a comment at the bottom about putting "other configuration" here. I tried to figure out what that "other configuration" is, and wound up with this:
If your module.config.php really looks like that then it won't work, routes is an array of routes defined in the router key, your config contains no such spec, try replacing it with this
return array(
// routes
'router' => array(
'routes' => array(
'svc' => array(
'type' => 'Literal',
'options' => array(
'route' => '/svc',
'defaults' => array(
'controller' => 'svc\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__' => 'svc\Controller',
),
),
),
),
),
),
),
'controllers' => array(
'invokables' => array(
'svc\Controller\Clients' => 'svc\Controller\ClientsController',
),
),
'view_manager' => array(
'template_path_stack' => array(
'album' => __DIR__ . '/../view',
),
),
);

ZF2 routing configuration

I've just built a zf2 project and i'm having a configuration problem.
When i go to mydomain.com this routs as specified in configuration files to Application module, index controller, index action.
But If i type mydomain.com/otheraction this is not routed to Application module, index controller, otheraction action. Of course, since it isn't configured to do this.
So my question would be how do i configure the app to do that? I've added my Application/config/module.config.php file and the main config file. Thank you!
module.config.php
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* #link http://github.com/zendframework/ZendSkeletonApplication for the canonical source repository
* #copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* #license http://framework.zend.com/license/new-bsd New BSD License
*/
return array(
'router' => array(
'routes' => array(
'home' => array(
'type' => 'Zend\Mvc\Router\Http\Literal',
'options' => array(
'route' => '/',
'defaults' => array(
'controller' => 'Application\Controller\Index',
'action' => 'index',
),
),
),
// The following is a route to simplify getting started creating
// new controllers and actions without needing to create a new
// module. Simply drop new controllers in, and you can access them
// using the path /application/:controller/:action
'application' => array(
'type' => 'Literal',
'options' => array(
'route' => '/application',
'defaults' => array(
'__NAMESPACE__' => 'Application\Controller',
'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(
),
),
),
),
),
),
),
'service_manager' => array(
'factories' => array(
'translator' => 'Zend\I18n\Translator\TranslatorServiceFactory',
),
),
'translator' => array(
'locale' => 'en_US',
'translation_file_patterns' => array(
array(
'type' => 'gettext',
'base_dir' => __DIR__ . '/../language',
'pattern' => '%s.mo',
),
),
),
'controllers' => array(
'invokables' => array(
'Application\Controller\Index' => 'Application\Controller\IndexController'
),
),
'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/layout/layout.phtml',
'application/index/index' => __DIR__ . '/../view/application/index/index.phtml',
'error/404' => __DIR__ . '/../view/error/404.phtml',
'error/index' => __DIR__ . '/../view/error/index.phtml',
),
'template_path_stack' => array(
__DIR__ . '/../view',
),
),
);
application.config.php
<?php
return array(
'modules' => array(
'Application',
'ZfcBase',
'ZfcUser',
),
'module_listener_options' => array(
'config_glob_paths' => array(
'config/autoload/{,*.}{global,local}.php',
),
'module_paths' => array(
'./module',
'./vendor',
),
),
);
The default route configured is to accept any url of this format, this is the standard format
mydomain.com/
mydomain.com/applicatiom/controller/action (standard format)
in your case mydomain.com/otheraction the router expect a module otheraction, but its not present.
if you need to have a route as specified above have a entry under route
'otheraction' => array(
'type' => 'Zend\Mvc\Router\Http\Literal',
'options' => array(
'route' => '/otheraction',
'defaults' => array(
'controller' => 'Application\Controller\Index',
'action' => 'otheraction',
),
),
),
In the routes subarray, add a next entry similar to the 'home' entry, for example:
'user' => array(
'type' => 'Zend\Mvc\Router\Http\Literal',
'options' => array(
'route' => '/user',
'defaults' => array(
'controller' => 'Application\Controller\User',
'action' => 'some-action',
),
),
),
That would route yourpage.com/user to someActionAction in your UserController.