Access models from other modules zf3 - php

I'm trying to configure ZF3 after a few projects with ZF2, but cannot access a model which is in another module.
I have 3 tables in my database, and I defined the gateways as follow in my Application\src\Module.php
public function getServiceConfig()
{
return [
'factories' => [
Model\ChatTable::class => function($container) {
$tableGateway = $container->get(Model\ChatTableGateway::class);
return new Model\ChatTable($tableGateway);
},
Model\ChatTableGateway::class => function ($container) {
$dbAdapter = $container->get(AdapterInterface::class);
$resultSetPrototype = new ResultSet();
$resultSetPrototype->setArrayObjectPrototype(new Model\Chat());
return new TableGateway('chat', $dbAdapter, null, $resultSetPrototype);
},
Model\OperadorTable::class => function($container) {
$tableGateway = $container->get(Model\OperadorTableGateway::class);
return new Model\OperadorTable($tableGateway);
},
Model\OperadorTableGateway::class => function ($container) {
$dbAdapter = $container->get(AdapterInterface::class);
$resultSetPrototype = new ResultSet();
$resultSetPrototype->setArrayObjectPrototype(new Model\Operador());
return new TableGateway('operador', $dbAdapter, null, $resultSetPrototype);
},
Model\ConversacionTable::class => function($container) {
$tableGateway = $container->get(Model\ConversacionTableGateway::class);
return new Model\ConversacionTable($tableGateway);
},
Model\ConversacionTableGateway::class => function ($container) {
$dbAdapter = $container->get(AdapterInterface::class);
$resultSetPrototype = new ResultSet();
$resultSetPrototype->setArrayObjectPrototype(new Model\Conversacion());
return new TableGateway('conversacion', $dbAdapter, null, $resultSetPrototype);
},
],
];
}
public function getControllerConfig()
{
return [
'factories' => [
Controller\IndexController::class => function($container) {
return new Controller\IndexController(
$container->get(Model\ChatTable::class),
$container->get(Model\OperadorTable::class),
$container->get(Model\ConversacionTable::class)
);
},
],
];
}
Then, I can use them in my Application\Controller\IndexController as follow:
namespace Application\Controller;
use Application\Model\ChatTable;
use Application\Model\OperadorTable;
use Application\Model\ConversacionTable;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
class IndexController extends AbstractActionController
{
private $chatTable;
private $operadorTable;
private $conversacionTable;
//TABLAS
public function __construct(
ChatTable $chatTable,
OperadorTable $operadorTable,
ConversacionTable $conversacionTable
){
$this->chatTable = $chatTable;
$this->operadorTable = $operadorTable;
$this->conversacionTable = $conversacionTable;
}
//VIEW ACTIONS
public function indexAction()
{
return new ViewModel([
'chats' => $this->chatTable->fetchAll(),
'operadores' => $this->operadorTable->fetchAll(),
'conversaciones' => $this->conversacionTable->fetchAll(),
]);
}
}
This works perfectly. My question is ¿what if, for example, I prefer to put the Chat and ChatTable model in another module, for example, under Panel\Model\ChatTable and acces them from my Application module? ¿what changes should I make?
In ZF2 this was easy using Service Locator. I have found a question suggesting the use of service factories, but, at least in my case, does not solve the idea of using at the same time models within the module and from outside the module.
Thanks in advance. Bye!

Well, I found the answer after a few attempts.
For example, if you prefer to use Panel\Model\Chat and Panel\Model\ChatTable instead of Application\Model\Chat and Application\Model\ChatTable, the configuration should be the following.
In your Application\src\Module.php:
public function getServiceConfig()
{
return [
'factories' => [
\Panel\Model\ChatTable::class => function($container) {
$tableGateway = $container->get(\Panel\Model\ChatTableGateway::class);
return new \Panel\Model\ChatTable($tableGateway);
},
\Panel\Model\ChatTableGateway::class => function ($container) {
$dbAdapter = $container->get(AdapterInterface::class);
$resultSetPrototype = new ResultSet();
$resultSetPrototype->setArrayObjectPrototype(new \Panel\Model\Chat());
return new TableGateway('chat', $dbAdapter, null, $resultSetPrototype);
},
],
//rest of stuff
];
}
public function getControllerConfig()
{
return [
'factories' => [
Controller\IndexController::class => function($container) {
return new Controller\IndexController(
$container->get(\Panel\Model\ChatTable::class),
//rest of stuff
);
},
],
];
}
Then, in your Application\Controller\IndexController:
use Panel\Model\ChatTable;
//rest of stuff
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
class IndexController extends AbstractActionController
{
private $chatTable;
//rest of stuff
//TABLAS
public function __construct(
ChatTable $chatTable,
//rest of stuff
){
$this->chatTable = $chatTable;
//rest of stuff
}
//VIEW ACTIONS
public function indexAction()
{
return new ViewModel([
'chats' => $this->chatTable->fetchAll(),
//rest of stuff
]);
}
}

I just started my first zf3 app weeks ago, and I had the same problem with you.
What did I do was, define the driver of the origin module inside the current module.config.php
'doctrine' => [
'driver' => [
__NAMESPACE__ . '_driver' => [
'class' => AnnotationDriver::class,
'cache' => 'array',
'paths' => [__DIR__ . '/../src/Model']
],
'Admin_driver' => [
'class' => AnnotationDriver::class,
'cache' => 'array',
'paths' => [__DIR__ . '/../../Admin/src/Model']
],
'orm_default' => [
'drivers' => [
__NAMESPACE__ . '\Model' => __NAMESPACE__ . '_driver',
'Admin\Model' => 'Admin_driver'
]
]
]
],
As you can see, I defined the Admin_driver and loaded it into the orm_default .

Related

ZF2 - shared models between modules

In current state I've got two modules - main module, and admin panel module.
Main module is called "Kreator", admin -> "KreatorAdmin". All the models are located inside the Kreator module (Kreator/Model/UserTable.php etc.).
"KreatorAdmin" is almost empty, there is a configuration for it:
KreatorAdmin/config/module.config.php
<?php
return array(
'controllers' => array(
'invokables' => array(
'KreatorAdmin\Controller\Admin' => 'KreatorAdmin\Controller\AdminController',
),
),
'router' => array(
'routes' => array(
'zfcadmin' => array(
'options' => array(
'defaults' => array(
'controller' => 'KreatorAdmin\Controller\Admin',
'action' => 'index',
),
),
),
),
),
'view_manager' => array(
'template_path_stack' => array(
__DIR__ . '/../view'
),
),
);
KreatorAdmin/src/KreatorAdmin/AdminController.php
<?php
namespace KreatorAdmin\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
class AdminController extends AbstractActionController
{
public function indexAction()
{
//$this->getServiceLocator()->get('Kreator\Model\UserTable');
return new ViewModel();
}
}
KreatorAdmin/Module.php
<?php
namespace KreatorAdmin;
class Module
{
public function getConfig()
{
return include __DIR__ . '/config/module.config.php';
}
public function getAutoloaderConfig()
{
return array(
'Zend\Loader\StandardAutoloader' => array(
'namespaces' => array(
__NAMESPACE__ => __DIR__ . '/src/' . __NAMESPACE__,
),
),
);
}
}
Simply adding "use" statements in controller and navigating by namespaces results in error
Argument 1 passed to KreatorAdmin\Controller\AdminController::__construct() must be an instance of Kreator\Model\UserTable, none given,
I also tried to play a bit with service manager as described here:
ZF2 Models shared between Modules but no luck so far.
How am I supposed to access UserTable from KreatorAdmin/src/KreatorAdmin/AdminController.php ?
Cheers!
update 1
I've added getServiceConfig to Module.php
public function getServiceConfig()
{
return [
'factories' => [
// 'Kreator\Model\UserTable' => function($sm) {
// $tableGateway = $sm->get('UserTableGateway');
// $table = new UserTable($tableGateway);
// return $table;
// },
// 'UserTableGateway' => function($sm) {
// $dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
// $resultSetPrototype = new ResultSet();
// $resultSetPrototype->setArrayObjectPrototype(new User());
// return new TableGateway('user', $dbAdapter, null, $resultSetPrototype);
// },
'DbAdapter' => function (ServiceManager $sm) {
$config = $sm->get('Config');
return new Adapter($config['db']);
},
'UserTable' => function (ServiceManager $sm) {
return new UserTable($sm->get('UserTableGateway'));
},
'UserTableGateway' => function (ServiceManager $sm) {
$dbAdapter = $sm->get('DbAdapter');
$resultSetPrototype = new ResultSet();
$resultSetPrototype->setArrayObjectPrototype(new User());
return new TableGateway('users', $dbAdapter, null, $resultSetPrototype);
},
],
];
}
And updated controller
class AdminController extends AbstractActionController
{
protected $userTable;
public function indexAction()
{
$userTable = $this->getServiceLocator()->get('Kreator\Model\UserTable');
return new ViewModel();
}
}
First error - using commented version:
Zend\ServiceManager\Exception\ServiceNotFoundException: Zend\ServiceManager\ServiceManager::get was unable to fetch or create an instance for Zend\Db\Adapter\Adapter
Second - using uncommented part:
Zend\ServiceManager\Exception\ServiceNotFoundException: Zend\ServiceManager\ServiceManager::get was unable to fetch or create an instance for Kreator\Model\UserTable
Solution
If anyone wonder. Using above configuration there is a correct solution in jobaer answer.
Using commented version, you have to remember to add
'Zend\Db\Adapter\Adapter' => 'Zend\Db\Adapter\AdapterServiceFactory',
somewhere in config to service_manager.
May be you messed up with ZF2 and ZF3 configuration. I am not sure but somewhere may be, you tried to create a factory of AdminController by passing an instance of UserTable to make it available inside AdminController's action methods. And later you are not passing that instance of UserTable into the AdminController's constructor while working with it further. The highlighted part from the previous line results in that error.
In ZF2 you do not need to pass that UserTable instance in the controller's constructor for its availability. Just use the following one in any controller's action methods.
$userTable = $this->getServiceLocator()->get('UserTable');
If want to know how this process is done, please, refer to this part of the tutorial.

Correct way to use service manager in Zend3

I was reading Zend 3 documentation on Service Manager and i got this problem.
In documentation it says that if we have some DI in our controller we should update module.config.php file and add controllers key and invoke controller not with InvokableFactory::class but with custom factory class and add another key service_manager that contains array of classes that my first controller uses.
Ok so i do that:
module.config.php
'service_manager' => [
'factories' => [
Controller\Controller2::class => Factory\Controller2Factory::class,
Controller\Controller3::class => Factory\Controller3Factory::class,
],
],
'controllers' => [
'factories' => [
Controller\Controller1::class => Factory\Controller1Factory::class
],
]
Controller1Factory.php
class Controller1Factory implements FactoryInterface
{
public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
{
return new Controller1(
$container->get(Controller2::class),
$container->get(Controller3::class),
);
}
}
But now i have error that Controller2 and Controller3 also have DI in their constuctors, so i make new custom factories and so on and so on...until i get to my models.
And Models also have Dependency that is injected in their controller which is zend native \Zend\Db\TableGateway\TableGatewayInterface and i now have to edit my conf file again and add TableGatewayInterface.
And that is wrong. I should never be forced to inject native zend classes and services this way.
So what am i doing wrong?
If your Controller has no dependency, it's the best way to declare it in module.config.php as you did.
But if it has dependecies, it's better to do it in Module.php. You first declare your services, then the controller (don't forget to remove it from module.config.php), injecting in it the services it depends :
public function getServiceConfig()
{
return [
'factories' => [
Model\MyObjectTable::class => function($container) {
$tableGateway = $container->get(Model\MyObjectTableGateway::class);
return new Model\MyObjectTable($tableGateway);
},
Model\MyObjectTableGateway::class => function($container) {
$dbAdapter = $container->get(AdapterInterface::class);
$resultSetPrototype = new ResultSet();
$resultSetPrototype->setArrayObjectPrototype(new Model\User());
return new TableGateway('myObject', $dbAdapter, null, $resultSetPrototype);
},
]
];
}
public function getControllerConfig()
{
return [
'factories' => [
Controller\MyObjectController::class => function($container) {
return new Controller\MyObjectController(
$container->get(Model\MyObjectTable::class)
);
},
]
];
}
And in your controller:
private $table;
public function __construct(MyObjectTable $table)
{
$this->table = $table ;
}
It is described in This ZF3 tutorial page and following.

Apigility: Send Error code 404 module.php in bootstrap

I use APIGILITY to create a Web-service, I’d like to resolve a problem. I don’t have a specific database linked to my app ,the database is specified by a parameter in the URL.
For example http://sk.localhost/users-service/1, where 1 is the database’s paramaters “projet” you can see below.
It’s my database .conf:
return array(
'db' => array(
'1' => array(
'driver' => 'Pdo',
'dsn' => 'mysql:dbname=projet;host=localhost',
'driver_option' => array(
1002 => 'SET NAMES \'UTF8\''
),
),
'2' => array(
'driver' => 'Pdo',
'dsn' => 'mysql:dbname=cgm;host=localhost',
'driver_option' => array(
1002 => 'SET NAMES \'UTF8\''
),
));
And it’s my code to specify the database with the parameter:
class Module
{
private $id_base;
private $conf_Users_tables;
private $conf_Droits_tables;
private $data;
public function init(ModuleManager $moduleManager)
{
$events = $moduleManager->getEventManager();
$events->attach(ModuleEvent::EVENT_MERGE_CONFIG, array($this, 'initDBSConfig'));
}
public function onBootstrap(MvcEvent $e)
{
$eventManager = $e->getApplication()->getEventManager();
$moduleRouteListener = new ModuleRouteListener();
$moduleRouteListener->attach($eventManager);
$eventManager->attach('route', array($this, 'checkRoute'));
}
public function getConfig()
{
return include __DIR__ . '/config/module.config.php';
}
public function getAutoloaderConfig()
{
return array(
'Zend\Loader\StandardAutoloader' => array(
'namespaces' => array(
__NAMESPACE__ => __DIR__ . '/src/' . __NAMESPACE__,
),
),
);
}
public function checkRoute(MvcEvent $e)
{
$route = $e->getRouteMatch()->getParams();
$this->id_base = $route['id_base'];
}
public function initDBSConfig(ModuleEvent $e)
{
$conf = include __DIR__ . '/../../config/Dbs.conf.php';
$this ->data = $conf['db'];
$this->initConfTables();
}
function initConfTables()
{
$confUsers = include __DIR__ . '/../../config/Users.conf.php';
$confDroits = include __DIR__ . '/../../config/Droits.conf.php';
$this->conf_Users_tables = $confUsers;
$this->conf_Droits_tables = $confDroits;
}
public function getServiceConfig()
{
return array(
'factories' => array(
'Application\Model\UsersTable' => function($sm) {
if(isset($this->data[$this->id_base]))
{
$tableGateway = $sm->get('UsersTableGateway');
$table = new UsersTable($tableGateway);
return $table;
}
else
{
return;
}
},
'UsersTableGateway' => function ($sm) {
$dbAdapter = $sm->get('SwitchDbAdapter');
$resultSetPrototype = new ResultSet();
$resultSetPrototype->setArrayObjectPrototype($sm->get('UsersModel'));
return new TableGateway($this ->data['t'.$this->id_base]['users'], $dbAdapter, null, $resultSetPrototype);
},
'UsersModel' => function($sm) {
$usersModel = new UsersModel();
$usersModel->setConfig($this->conf_Users_tables[$this->id_base]);
return $usersModel;
},
'Application\Model\DroitsTable' => function($sm) {
$tableGateway = $sm->get('DroitsTableGateway');
$table = new DroitsTable($tableGateway);
return $table;
},
'DroitsTableGateway' => function ($sm) {
$dbAdapter = $sm->get('SwitchDbAdapter');
$resultSetPrototype = new ResultSet();
$resultSetPrototype->setArrayObjectPrototype($sm->get('DroitsModel'));
return new TableGateway($this ->data['t'.$this->id_base]['droits'], $dbAdapter, null, $resultSetPrototype);
},
'DroitsModel' => function($sm) {
$droitsModel = new DroitsModel();
$droitsModel->setConfig($this->$conf_Droits_tables[$this->id_base]);
return $droitsModel;
},
'SwitchDbAdapter' => function ($sm) {
$dbAdapter = new \Zend\Db\Adapter\Adapter($this->data[$this->id_base]);
return $dbAdapter;
},
),
);
}
}
So I’d like the application send HTTP ERROR code 404 if the parameter in the URL doesn’t match to any databases in my config.
public function getServiceConfig()
{
if (empty($this->data[$this->id_base])){
header('HTTP/1.0 404 Not Found');
die('<h1>404 Not Found</h1>Incorrect Database request.');
}
// Rest of you code in method getServiceConfig() ...
}

Database Translations Zend Framework 2

I have problem with creating custom translator from database in ZF2. I have a DB like this
and files:
1)Application/module.config.php
'service_manager' => array(
'abstract_factories' => array(),
'factories' => array(
'translator' => function (\Zend\ServiceManager\ServiceManager $serviceManager)
{
$pluginManager = new \Zend\I18n\Translator\LoaderPluginManager();
$pluginManager->setServiceLocator($serviceManager);
$pluginManager->setFactory('DatabaseTranslationLoaderFactory', function($serviceManager)
{
$translator = new \Zend\I18n\Translator\DatabaseTranslationLoaderFactory();
return $translator->createService($serviceManager);
});
$translator = new \Zend\I18n\Translator\Translator(array());
$translator->setFallbackLocale('en_US');
$translator->setPluginManager($pluginManager);
$translator->addRemoteTranslations('DatabaseTranslationLoaderFactory');
return $translator;
},
),
),
'translator' => array(
'locale' => 'en_US',
'translation_file_patterns' => array(
array(
'type' => 'Zend\I18n\Translator\Loader\Database',
'base_dir' => __DIR__ . '/../language',
'pattern' => '%s.mo',
),
),
),
2) Zend/I18n/Translator/Loader/Database.php
<?php
namespace Zend\I18n\Translator\Loader;
use Zend\Db\Adapter\Adapter;
use Zend\Db\Sql\Sql;
use Zend\I18n\Translator\Plural\Rule as PluralRule;
use Zend\I18n\Translator\TextDomain;
class Database implements RemoteLoaderInterface {
protected $dbAdapter;
public $dbAdapter;
public function __construct(Adapter $dbAdapter = null)
{
if ($dbAdapter === null)
{
$configArray = array('driver' => 'Pdo_Mysql',
'database' => 'dbname',
'username' => 'username',
'password' => 'pswd',
'hostname' => 'localhost',
'charset' => 'utf-8',
);
$dbAdapter = new Adapter($configArray);
}
$this->dbAdapter = $dbAdapter;
}
public function load($locale, $textDomain)
{
$sql = new Sql($this->dbAdapter);
$select = $sql->select('ic_var')->columns(array('value'))
->where(array('language' => $locale, 'name' => $textDomain));
$messages = $this->dbAdapter->query(
$sql->getSqlStringForSqlObject($select),
Adapter::QUERY_MODE_EXECUTE
);
$textDomain = new TextDomain();
foreach ($messages as $message) {
if (isset($textDomain[$message['name']])) {
if (!is_array($textDomain[$message['name']])) {
$textDomain[$message['name']] = array(
$message['plural_index'] => $textDomain[$message['name']]
);
}
$textDomain[$message['name']][$message['plural_index']] = $message['value'];
} else {
$textDomain[$message['name']] = $message['value'];
}
}
return $textDomain;
}
}
3) Zend/I18n/Translator/DatabaseTranslationLoaderFactory.php
<?php
namespace Zend\I18n\Translator;
use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
use Zend\I18n\Translator\Loader\Database;
class DatabaseTranslationLoaderFactory implements FactoryInterface
{
public function createService(ServiceLocatorInterface $serviceLocator)
{
return new Database($serviceLocator->get('Zend\Db\Adapter\Adapter'));
}
}
4) Application/Module.php
public function onBootstrap(MvcEvent $e)
{
$translator = $e->getApplication()->getServiceManager()->get('translator');
$translator->addTranslationFile(
'DatabaseTranslationLoader',
'text-domain',
'text-domain'
);
}
But translation doesn`t work, because db adapter not find in loader:
Fatal error: Uncaught exception 'Zend\I18n\Exception\RuntimeException' with message 'Specified loader is not a file loader'
Thanks for your answers!
First of all you shouldn't define your custom classes in the Zend namespace as this is reserved a namespace for the ZF2 library and you don't want to touch (or add) files in the vendor directory.
Just put the custom classes in your own namespace outside the vendor folder. i.e. MyI18n
You can register you custom remote loader to the pluginManager in module.config.php.
return array(
'translator' => array(
'loaderpluginmanager' => array(
'factories' => array(
'database' => 'MyI18n\Translator\DatabaseTranslationLoaderFactory',
)
),
'remote_translation' => array(
array(
'type' => 'database' //This sets the database loader for the default textDomain
),
),
)
);
You don't have to overwrite the Translator factory if you want to add a custom loader, so just remove that code in your Module.php.
Als remove the configuration under translation_file_patterns as this is only needed for file loaders.
EDIT
For the above to work you need to overwrite the TranslatorServiceFactory because ZF has no support to register custom loaders on the plugin manager.
namespace MyNamespace\Translator;
use Zend\Mvc\Service\TranslatorServiceFactory as BaseTranslatorFactory;
class TranslatorServiceFactory extends BaseTranslatorFactory
{
/**
* #param ServiceLocatorInterface $serviceLocator
* #return MvcTranslator
*/
public function createService(ServiceLocatorInterface $serviceLocator)
{
$translator = parent::createService($serviceLocator);
$config = $serviceLocator->get('Config');
$pluginManagerConfig = isset($config['translator']['loaderpluginmanager']) ? $config['translator']['loaderpluginmanager'] : array();
$pluginManager = new LoaderPluginManager(new Config($pluginManagerConfig));
$pluginManager->setServiceLocator($serviceLocator);
$translator->setPluginManager($pluginManager);
return $translator;
}
}
Now register your custom factory in the service configuration:
class Module
{
public function getServiceConfig()
{
return array(
'factories' => array(
'MvcTranslator' => 'MyNamespace\Translator\TranslatorServiceFactory',
)
)
}
}
I register custom remote loader to the pluginManager in module.config.php like this
'translator' => [
'loaderpluginmanager' => [
'factories' => [
'database' => function($lpm){
$sm = $lpm->getServiceLocator();
$loader = new Zf2Translation\Loader\DatabaseTranslationLoader($sm);
return $loader;
},
],
],
'remote_translation' => [
[
'type' => 'database',
],
],
]
Next in Database Loader class
use Zend\I18n\Translator\Loader\RemoteLoaderInterface;
class DatabaseTranslationLoader implements RemoteLoaderInterface
{
protected $dbAdapter;
protected $sm;
public function __construct(ServiceManager $sm)
{
$this->sm = $sm;
$this->dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
}
}
I hope it helps.

Zend 2: Model table from view helper error

I'm having a problem with setting up a model table from a view helper. I have used the exact same code that I use within my regular controllers: e.g.:
namespace Application\View\Helper;
use Zend\View\Helper\AbstractHelper;
use Application\Model\MenusTable;
use Zend\ServiceManager\ServiceLocatorAwareInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
**snipped**
public function setServiceLocator(ServiceLocatorInterface $serviceLocator)
{
$this->serviceLocator = $serviceLocator;
return $this;
}
public function getServiceLocator()
{
return $this->serviceLocator;
}
public function getMenusTable()
{
if (!$this->menusTable) {
$sm = $this->getServiceLocator();
$this->menusTable = $sm->get('Application\Model\MenusTable');
}
return $this->menusTable;
}
public function allLinks()
{
$all = $this->getMenusTable()->fetchAll();
return $all;
}
However I am met with this error:
Catchable fatal error: Argument 1 passed to Application\Model\MenusTable::__construct() must be an instance of Zend\Db\Adapter\Adapter, none given, called in C:\xampp\**snipped**\zend\library\Zend\ServiceManager\AbstractPluginManager.php on line 177 and defined in C:\xampp\**snipped**\Application\src\Application\Model\MenusTable.php on line 14
Everything works fine from the main controllers, but here I seem to hit a big problem - I'm new to Zend, but it appears to not be getting the factory from the Module.php file - is there any way to get it?
I have this in my Module.php - as said it works fine in a regular controller, but in a view helper it's not processed for some reason:
public function getServiceConfig()
{
return array
(
'factories' => array
(
'Application\Model\MenusTable' => function($sm)
{
$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
$table = new MenusTable($dbAdapter);
return $table;
},
),
);
}
After re-reading your question I realized that your using ZF2.
here is a tutorial on using ServiceLocators http://framework.zend.com/wiki/display/ZFDEV2/Proposal+for+ServiceLocator+and+DependencyInjector
From the Documentation you need to define your DB connection.
$services = new ServiceLocator();
// Registering an object:
$services->set('db', $db);
// Lazy-loading by registering a closure:
$services->set('db', function() use ($config) {
$db = Db::factory($config->db);
return $db;
});
// Retrieving:
$db = $services->get('db');
First you should use the getServiceConfig() in your module ::
public function getServiceConfig()
{
return array(
'factories' => array(
'MODULE\Model\MenusTable' => function($sm) {
$tableGateway = $sm->get('MenusTableGateway');
$table = new MenusTable($tableGateway);
return $table;
},
'MenusTableGateway' => function ($sm) {
$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
$resultSetPrototype = new ResultSet();
$resultSetPrototype->setArrayObjectPrototype(new Menus());
return new TableGateway('menus', $dbAdapter, null, $resultSetPrototype);
},
),
);
}
THE ADAPTER might be in your /config/autoload/global.php, like this :
'service_manager' => array(
'factories' => array(
'Zend\Db\Adapter\Adapter' => 'Zend\Db\Adapter\AdapterServiceFactory',
),
),
// CONNECTION DB
'db' => array(
'driver' => 'Pdo',
'dsn' => 'mysql:dbname=YOURDBNAME;host=localhost',
'username' => 'root',
'password' => '',
'driver_options' => array(
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''
),
),
Next your View helper must extend AbstractHelper but also implement ServiceLocatorAwareInterface
class MyViewHelper extends AbstractHelper implements ServiceLocatorAwareInterface
I'll put the code in my website

Categories