I'm having trouble configuring multiple namespaces/classes under same module. For example, I have a module called "Account", in which I'd like to include all account related classes (companies: 'accounts', users: 'users', external api: 'api' etc.. ). Module structure looks like this..
/Account
- Module.php
- /config
- /view
- /src
- /Account
- /Controller (AccountController.php)
- /Form (AccountForm.php)
- /Model (Account.php + AccountTable.php)
- /User
- /Controller (UserController.php)
- /Form (UserForm.php)
- /Model (User.php + UserTable.php)
- /Api
- Api.php (simple class)
Being new to ZF2, I decided to keep things simple and stupid and Not to try implementing complex routing to Account module. So, in order to trigger indexAction for UserController, url should be /user (!)
Here's the module class:
namespace Account;
use Account\Model\AccountTable;
use Account\Model\UserTable;
class Module
{
public function getAutoloaderConfig()
{
return array(
'Zend\Loader\ClassMapAutoloader' => array(
__DIR__ . '/autoload_classmap.php',
),
'Zend\Loader\StandardAutoloader' => array(
'namespaces' => array(
__NAMESPACE__ => __DIR__ . '/src/' . __NAMESPACE__,
),
),
);
}
public function getServiceConfig()
{
return array(
'factories' => array(
'Account\Model\AccountTable' => function($sm) {
$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
$table = new AccountTable($dbAdapter);
return $table;
},
'Account\Model\UserTable' => function($sm) {
$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
$table = new UserTable($dbAdapter);
return $table;
},
),
);
}
public function getConfig()
{
return include __DIR__ . '/config/module.config.php';
}
}
And the module.config file
return array(
'controllers' => array(
'invokables' => array(
'Account\Controller\Account' => 'Account\Controller\AccountController',
'Account\Controller\User' => 'Account\Controller\UserController',
),
),
'router' => array(
'routes' => array(
'account' => array(
'type' => 'segment',
'options' => array(
'route' => '/account[/:action[/:accountId]]',
'constraints' => array(
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'accountId' => '[0-9]+',
),
'defaults' => array(
'controller' => 'Account\Controller\Account',
'action' => 'index',
),
),
/*
'may_terminate' => true,
'child_routes' => array(
'user' => array(
'type' => 'literal',
'options' => array(
'route' => '/user[/:action[/:userId]]',
'constraints' => array(
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'userId' => '[0-9]+',
),
'defaults' => array(
'controller' => 'Account\Controller\User',
'action' => 'index'
)
)
)
),
*/
),
'user' => array(
'type' => 'segment',
'options' => array(
'route' => '/user[/:action[/:userId]]',
'constraints' => array(
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'userId' => '[0-9]+',
),
'defaults' => array(
'controller' => 'Account\Controller\User',
'action' => 'index',
),
),
)
),
),
'view_manager' => array(
'template_path_stack' => array(
'account' => __DIR__ . '/../view',
'user' => __DIR__ . '/../view',
),
),
);
But the error I'm getting is, "Class 'Account\Controller\UserController' not found". I am sure i've missed something. Any clue please?
Thanks
You must let the StandardAutoloader
know about your new namespace:
public function getAutoloaderConfig()
{
return array(
'Zend\Loader\ClassMapAutoloader' => array(
__DIR__ . '/autoload_classmap.php',
),
'Zend\Loader\StandardAutoloader' => array(
'namespaces' => array(
// This is for the Account namespace
__NAMESPACE__ => __DIR__ . '/src/' . __NAMESPACE__,
// And this is for the User namespace
'User' => __DIR__ . '/src/' . 'User',
),
),
);
}
In the module.config.php
return array(
'controllers' => array(
'invokables' => array(
'Account\Controller\Account' => 'Account\Controller\AccountController',
// The key can be what ever you want, but the value must be a valid
// class name. Your UserController lives in the User namespace,
// not in Account
'Account\Controller\User' => 'User\Controller\UserController',
),
),
/* ... */
);
The StandardLoader needs to know where to find the classes. You can define it with an option called namespaces which is an array that contains absolute (or relative to the current script) paths. It should look like this:
'Zend\Loader\StandardAutoloader' => array(
'namespaces' => array(
__NAMESPACE__ => __DIR__ . '/src/' . __NAMESPACE__
)
)
__NAMESPACE__ is the name of the module, and __DIR__ the absolute path to the Module.php script
Check http://framework.zend.com/manual/2.0/en/modules/zend.loader.standard-autoloader.html
The ClassMapAutoloader is used for performance: you define the class key and its exactly path to the file, instead of a folder which zf2 has to browse its contents doing filesystem operations (StandardLoader's way).
Check http://framework.zend.com/manual/2.0/en/modules/zend.loader.class-map-autoloader.html
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With