Error on Injecting dependencies into your ZF2 controllers - zend-framework2

Hi I am having errors trying to inject dependencies on my controllers.
Warning: Missing argument 1 for User\Controller\LoginController::__construct(), called in /var/www/html/engsvc_dev/vendor/zendframework/zendframework/library/Zend/ServiceManager/AbstractPluginManager.php on line 170 and defined in /var/www/html/engsvc_dev/module/User/src/User/Controller/LoginController.php on line 23
Module.php
public function getControllerConfig(){
return array(
'factories' => array(
'Login' => function ($sm) {
$locator = $sm->getServiceLocator();
$controller = new LoginController($locator->get("Config"));
return $controller;
},
),
);
}
Controller
class LoginController extends AbstractActionController{
protected $globalConfig;
protected $UserModuleSetup;
public function __construct($config){
}
module.config.php
"invokables" => array(
"User" => "User\Controller\LoginController",
"Login" => "User\Controller\LoginController"
),

Module.php
public function getControllerConfig(){
return array(
'factories' => array(
'Login' => function ($sm) {
$locator = $sm->getServiceLocator();
$controller = new User\Controller\LoginController($locator->get("Config"));
return $controller;
},
),
);
}
Controller
class LoginController extends AbstractActionController{
protected $globalConfig;
protected $UserModuleSetup;
public function __construct($config){
}
module.config.php
"invokables" => array(
"User" => "User\Controller\LoginController",
),

Related

An exception was raised while creating "UserTable"; no instance returned

I am new to zend framework2.
I got the error.
An exception was raised while creating "UserTable"; no instance returned.
Please look my code.
Login\Model\UserTable.php
protected $tableGateway;
public function __construct(TableGateway $tableGateway)
{
$this->tableGateway = $tableGateway;
}
public function fetchAll()
{
$resultSet = $this->tableGateway->select();
return $resultSet;
}
Login\Module.php
public function getServiceConfig()
{
return array(
'factories' => array(
'UserTable' => function($serviceManager) {
$tableGateway = $serviceManager->get('UserTableGateway');
return new UserTable($tableGateway);
},
'UserTableGateway' => function ($serviceManager) {
$dbAdapter = $serviceManager->get('Zend\Db\Adapter\Adapter');
$resultSetPrototype = new ResultSet();
$resultSetPrototype->setArrayObjectPrototype(NULL);
return new TableGateway('user', $dbAdapter, NULL, $resultSetPrototype);
}
)
);
}
Login\src\Login\Controller\LoginController.php
public function getAction()
{
$serviceManager = $this->getServiceLocator();
$userTable = $serviceManager->get('UserTable');
$user = $userTable->fetchAll();
return $this->redirect()->toRoute('home', ['data' => $user]);
}
local.php
return array(
'db' => array(
'dsn' => 'mysql:dbname=album; host=localhost',
'username' => 'root',
'password' => 'root',
),
'service_manager' => array(
'factories' => array(
'Zend\Db\Adapter\Adapter'
=> 'Zend\Db\Adapter\AdapterServiceFactory',
),
)
);
when I just redirect to home in getAction() in controller, it working fine.
I couldn't get solution for this.
can anyone help me out.
Thanks in advance.
NOTE: please comment, if you need more details.

Inserting data From Zend's form to database

I have a problem with inserting Records into a DB using Zend FrameWork 2.
There are no records saved into the DB when submitting the Form and also no Error Messages Appear, just the Confirmation Message telling me that it << Registered Successfully >>
Here is my code, thanks in advance:
// App/config/autoload/global.php
return array(
'db' => array(
'driver' => 'pdo',
'dsn' => 'mysql:dbname=zf_app;host=localhost;port:8080',
'username' => 'zf_user',
'password' => 'zf_pass',
'driver_options' => array(
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''
),
),
'service_manager' => array(
'factories' => array(
'Zend\Db\Adapter\Adapter' =>'Zend\Db\Adapter\AdapterServiceFactory',
),
),
);
#################################################################
//App\module\Users\src\Users\Model\Usertable.php
<?php
namespace Users\Model;
use Zend\Db\Adapter\Adapter;
use Zend\Db\ResultSet\ResultSet;
use Zend\Db\TableGateway\TableGateway;
class UserTable
{
protected $tableGateway ;
public function __construct(TableGateway $tableGateway)
{
$this->tableGateway = $tableGateway;
}
public function saveUser(User $user)
{
$data = array(
'email' => $user->email ,
'name' => $user->name,
'password' => $user->password,
);
$id = (int)$user->id ;
if($id == 0)
{
$this->tableGateway->insert($data);
} else {
if($this->getUser($id))
{
$this->tableGateway->update($data , array('id' => $id));
} else {
throw new \Exception("User ID does not Exist ");
}
}
}
public function getUser($id)
{
$id = (int)$id;
$rowset = $this->tableGateway->select(array('id' => $id ));
$row = $rowset->current();
if(!$row)
{
throw new \Exception("Could not Find row $id ");
}
return $row ;
}
}
##########################################################
// App\module\Users\src\Users\Controller\RegisterController.php
<?php
namespace Users\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
use Users\Form\RegisterForm;
use Users\Form\RegisterFilter;
use Zend\Db\Adapter\Adapter;
class RegisterController extends AbstractActionController
{
public function indexAction()
{
$form = new RegisterForm();
$viewModel = new ViewModel(array('form' => $form));
return $viewModel;
}
public function confirmAction()
{
$viewModel = new ViewModel();
return $viewModel;
}
public function processAction()
{
if(!$this->request->isPost())
{
return $this->redirect()->toRoute(NULL , array(
'controller' => 'register',
'action' => 'index',
));
}
$post = $this->request->getPost();
$form = new RegisterForm();
$inputFilter = new RegisterFilter();
$form->setInputFilter($inputFilter);
$form->setData($post);
if (!$form->isValid())
{
$model = new ViewModel(array('error' => true , 'form' => $form));
$model->setTemplate('users/register/index');
return $model;
}
return $this->redirect()->toRoute(NULL , array('controller' => 'register' , 'action' => 'confirm' ,));
}
public function createUser(array $data)
{
$sm = $this->getServiceLocator();
$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
$resultSetPrototype = new \Zend\Db\ResultSet\ResultSet();
$resultSetPrototype->setArrayObjectPrototype(new \Users\Model\User);
$tableGateway = new \Zend\Db\TableGateway\TableGateway('user' , $dbAdapter , null , $resultSetPrototype);
$user = new User();
$user->exchangeArray($data);
$userTable = new UserTable($tableGateway);
$userTable->saveUser($user);
$this->createUser($form->getData());
return true;
}
}
Create // App/config/autoload/local.php
// App/config/autoload/local.php
return array(
'db' => array(
'username' => "zf_user",
'password' => "zf_pass",
)
);
and remove username and password from global.php
What is the User in public function saveUser(User $user) ? You didn't use User file.

Zend Framework 2 Service Manager Dependency Injection

My application is a collection of POPO's and I'm trying to wire these POPO's up using the Zend Framework 2 Service Manager.
To illustrate my problem, take the following example:
$config = array(
'services' => array(
'my.app.serviceA' => new \My\App\Services\ServiceA(),
'my.app.serviceB' => new \My\App\Services\ServiceB(),
'my.app.manager.task' => new \My\App\Manager\TaskManager(),
),
);
My TaskManager class looks something like this:
class TaskManager {
protected $serviceA;
protected $serviceB;
public function setServiceA( \My\App\Service\ServiceA $serviceA )
{
$this->serviceA = $serviceA;
}
public function setServiceB( \My\App\Service\ServiceB $serviceB )
{
$this->serviceB = $serviceB;
}
}
As you can see, the TaskManager class has dependencies on both ServiceA and ServiceB. How do inject those services into my.app.manager.task using the Service Manager configuration using the service names defined for both ServiceA and ServiceB?
UPDATE:
I'm beginning to believe that I shouldn't be using the ServiceManager component for my purposes at all but that I should be using the Zend DI component instead.
I get the impression that the ServiceManager is a ZF2 "framework" component whereas Zend\DI seems to be more of a generic all purpose DiC. Hence, this might be the reason of ServiceManager's tied relationship with the MVC and ModuleManager components (which also seem to be "framework" components).
Maybe someone could clarify?
in module.config.php The Service Manager can be configured in 7 different ways:
return array(
// instantiate the class for you when needed
'invokables' => array(
'commentController' => '\Comment\Controller\CommentController';
),
// Aliasing a name to a known service name
'aliases' => array(
'Comment\Service' => 'commentService';
),
// configure the instance of the object
'factories' => array(
'commentController' => function ($sm) {
$locator = $sm->getServiceLocator();
$controller = $locator->get('commentController');
$controller->setCommentService($locator->get('Comment\Service'));
return $controller;
}
),
// register already instantiated objects
'services' => array(
'commentController' => new \Comment\Controller\CommentController(),
),
//factory instance that can create multiple services based on the name supplied to the factory.
'abstract_factories' => array(
'SomeModule\Service\FallbackFactory',
),
// initialize the service whenever service created
'initializers' => array(
function ($instance, $sm) {
if ($instance instanceof \Comment\Controller\CommentController){
$instance->setCommentService($sm->get('Comment\Service'));
}
}
),
// indicating whether or not a service should be shared
'shared' => array(
'commentController' => false,
),
);
and in Module.php
public function getControllerConfig() {
return array(
'factories' => array(
'commentController' => function ($sm) {
$controller = new \Comment\Controller\CommentController();
$locator = $sm->getServiceLocator();
$controller->setCommentForm($locator->get('commentForm'));
$controller->setCommentService($locator->get('commentService'));
return $controller;
}
)
);
}
and simple use in controller :
$commentService = $this->serviceLocator->get('Comment\Service');
you put this in getter or in init() method
ZF2's New Controller::init() :: phly, boy, phly
in Controller ;
$yourService = $this->getServiceLocator()->get('your_service_alias');
in View Helper :
you should send in from Module.php by constructor of viewHelper
public function getViewHelperConfig() {
return array(
'factories' => array(
'loginHelper' => function($sm) {
return new LoginHelper($sm);
}
)
}
in a calss
use Zend\ServiceManager\ServiceLocatorAwareInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
public class UseCaseBO implements ServiceLocatorAwareInterface {
protected $serviceLocator;
public function setServiceLocator(ServiceLocatorInterface $serviceLocator) {
$this->serviceLocator = $serviceLocator;
}
public function getServiceLocator() {
return $this->serviceLocator;
}
// now instance of Service Locator is ready to use
public function someMethod() {
$table = $this->serviceLocator->get('your_service_alias');
//...
}
}
for me, the best way is to create a class factory and use the factoryInterface, like this :
return array(
'service_manager' => array(
'factories' => [
'Task' => 'Application\TaskFactory',
],
'invokables' => array(
'Task'=> 'Application\Task',
'ServiceA'=> 'Application\ServiceA',
'ServiceB' => 'Application\ServiceB'
)
),
);
And a factory class :
class TaskFactory implements FactoryInterface {
/** #var ServiceLocatorInterface $serviceLocator */
var $serviceLocator;
public function createService(ServiceLocatorInterface $serviceLocator) {
$sl = $this->serviceLocator = $serviceLocator;
// you can get your registered services
$serviceA = $sl->get('ServiceA');
$serviceB = $sl->get('ServiceB');
// You can build your class using the class loader
$task = new Application\Task();
// Or the Service Locator Again
$task = $sl->get('Task');
return $task;
}
}
You can implement the factory interface on your Task class. I prefer to have control on what I'm building.

calling adapter in model

Module :
public function getServiceConfig() {
return array(
'factories' => array(
// 'user' table-------------------------------------
'Album\Model\AlbumTable\dbtable=user' => function($sm) {
$tableGateway = $sm->get('UserTableGateway');
$table = new SignupTable($tableGateway);
return $table;
},
'UserTableGateway' => function ($sm) {
$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
$resultSetPrototype = new ResultSet();
$resultSetPrototype->setArrayObjectPrototype(new Signup());
return new TableGateway('user', $dbAdapter, null, $resultSetPrototype);
},
),
);
}
Now how can I call my ‘dbadapter’ in anywhere in the model while I need it for
new \Zend\Validator\Db\RecordExists(
array(
'table' => 'user',
'field' => 'username',
'adapter' => $dbadapter
)
)
please tell me the way to call adapter in anywhere.
-thanks.
Edit :
I followed this 'Get default zend db adapter in table model' thread and did the following in my ‘model’,
<?php
namespace Application\Model;
use Zend\InputFilter\InputFilter;
use Zend\InputFilter\InputFilterAwareInterface;
use Zend\InputFilter\InputFilterInterface;
use Zend\Validator;
class Signup implements InputFilterAwareInterface {
public $username;
protected $inputFilter;
protected $serviceLocator;
protected $dbAdapter;
public function getServiceLocator() {
return $this->serviceLocator;
}
public function setServiceLocator(Zend\ServiceManager\ServiceLocatorInterface $serviceLocator) {
$this->serviceLocator = $serviceLocator;
return $this;
}
public function exchangeArray($data) {
$this->username = (!empty($data['username'])) ? $data['username'] : null;
$this->password = (!empty($data['password'])) ? $data['password'] : null;
$this->email = (!empty($data['email'])) ? $data['email'] : null;
}
public function getArrayCopy() {
return get_object_vars($this);
}
public function setInputFilter(InputFilterInterface $inputFilter) {
throw new \Exception("Not used");
}
public function getInputFilter() {
$this->$dbAdapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
if (!$this->inputFilter) {
$inputFilter = new InputFilter();
$inputFilter->add(array(
'name' => 'username',
'required' => true,
'filters' => array(
array('name' => 'StripTags'),
array('name' => 'StringTrim'),
),
'validators' => array(
array(
'name' => 'NotEmpty',
'options' => array(
'messages' => array(
\Zend\Validator\NotEmpty::IS_EMPTY => 'Username required',
),
),
),
new \Zend\Validator\Db\RecordExists(
array(
'table' => 'user',
'field' => 'username',
'adapter' => $this->dbAdapter,
)
)
),
));
$this->inputFilter = $inputFilter;
}
return $this->inputFilter;
}
}
but I got this error,
Fatal error: Call to a member function get() on a non-object in F:\xampp\htdocs\zendtest\module\Application\src\Application\Model\Signup.php on line 41
Why is that ?
I made it like the following,
Module :
<?php
namespace Application;
use Zend\Mvc\ModuleRouteListener;
use Zend\Mvc\MvcEvent;
use Application\Model\Signup;
use Application\Model\SignupTable;
use Zend\Db\ResultSet\ResultSet;
use Zend\Db\TableGateway\TableGateway;
class Module {
public function onBootstrap(MvcEvent $e) {
$e->getApplication()->getServiceManager()->get('translator');
$eventManager = $e->getApplication()->getEventManager();
$moduleRouteListener = new ModuleRouteListener();
$moduleRouteListener->attach($eventManager);
}
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 getServiceConfig() {
return array(
'factories' => array(
'dbAdapter\dbtable=user' => function($sm) {
$dbAdapterr = $sm->get('Zend\Db\Adapter\Adapter');
return $dbAdapterr;
},
),
);
}
}
Controller :
<?php
namespace Application\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
use Application\Model\Signup;
use Application\Form\SignupForm;
class IndexController extends AbstractActionController {
protected $userTablee;
public function getSignTable($table, $object) {
if (!$this->$object) {
$sm = $this->getServiceLocator();
$this->$object = $sm->get($table);
}
return $this->$object;
}
public function indexAction() {
return new ViewModel();
}
public function signupAction() {
$form = new SignupForm();
$form->get('submi')->setValue('Submit');
$request = $this->getRequest();
if ($request->isPost()) {
$album = new Signup();
$t = $this->getSignTable('dbAdapter\dbtable=user', 'userTablee'); // its to get adapter from Module via getSignTable()
$form->setInputFilter($album->getInputFilter($t)); // passes adapter to Model
$form->setData($request->getPost());
if ($form->isValid()) {
// code goes here
}
}
}
}
Model :
<?php
namespace Application\Model;
use Zend\InputFilter\InputFilter;
use Zend\InputFilter\InputFilterAwareInterface;
use Zend\InputFilter\InputFilterInterface;
use Zend\Validator;
class Signup implements InputFilterAwareInterface {
public $username;
public $password;
public $email;
protected $inputFilter;
protected $adapter;
public function exchangeArray($data) {
$this->username = (!empty($data['username'])) ? $data['username'] : null;
$this->password = (!empty($data['password'])) ? $data['password'] : null;
$this->email = (!empty($data['email'])) ? $data['email'] : null;
}
public function getArrayCopy() {
return get_object_vars($this);
}
public function setInputFilter(InputFilterInterface $inputFilter) {
throw new \Exception("Not used");
}
public function getInputFilter($adapter = null) { // receives adapter here
$this->adapter = $adapter;
if (!$this->inputFilter) {
$inputFilter = new InputFilter();
$inputFilter->add(array(
'name' => 'username',
'required' => true,
'filters' => array(
array('name' => 'StripTags'),
array('name' => 'StringTrim'),
),
'validators' => array(
array(
'name' => 'NotEmpty',
'options' => array(
'messages' => array(
\Zend\Validator\NotEmpty::IS_EMPTY => 'Username required',
),
),
),
new \Zend\Validator\Db\NoRecordExists(
array(
'table' => 'user',
'field' => 'username',
'adapter' => $this->adapter, // this line for adapter
'messages' => array(
\Zend\Validator\Db\AbstractDb::ERROR_RECORD_FOUND => 'Username already exists',
),
)
)
),
));
$this->inputFilter = $inputFilter;
}
return $this->inputFilter;
}
}

ZF2 User\Module.php cannot call $sm->get('Zend\Db\Adapter\Adapter')

I'm learning ZF2 by starting write a simple UserAuth Plugin for authentication but have got the exceptions:
An exception was raised while creating "userAuth"; no instance returned
Previous exceptions:
The supplied or instantiated driver object does not implement Zend\Db\Adapter\Driver\DriverInterface
error at this line: $sm->get('Zend\Db\Adapter\Adapter')
The following is my User\Module.php
class Module {
public function onBootstrap(MvcEvent $e)
{
$e->getApplication()->getServiceManager()->get('translator');
$eventManager = $e->getApplication()->getEventManager();
$moduleRouteListener = new ModuleRouteListener();
$moduleRouteListener->attach($eventManager);
}
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 getConfig()
{
return include __DIR__ . '/config/module.config.php';
}
public function getServiceConfig()
{
return array(
'invokables' => array(
),
'factories' => array(
'User\Form\Signin' => function($sm) {
$form = new Form\Signin();
$form->setInputFilter(new Form\SigninFilter);
return $form;
},
'User\Auth\Service' => function ($sm) {
return new \Zend\Authentication\AuthenticationService(
new \Zend\Authentication\Storage\Session(),
new \Zend\Authentication\Adapter\DbTable($sm->get('Zend\Db\Adapter\Adapter'))
);
},
),
);
}
public function getControllerPluginConfig()
{
return array(
'factories' => array(
'UserAuth' => function ($sm) {
$sl = $sm->getServiceLocator();
$authService = $sl->get('User\Auth\Service');
$authAdapter = new \Zend\Authentication\Adapter\DbTable($sm->get('Zend\Db\Adapter\Adapter'));
$controllerPlugin = new Controller\Plugin\UserAuth();
$controllerPlugin->setAuthService($authService);
$controllerPlugin->setAuthAdapter($authAdapter);
return $controllerPlugin;
},
),
);
}
}
Please help me to fix it.
Add:
use Zend\Db\Adapter\Adapter;
to the top of Controller\Plugin\UserAuth.php
and:
extends Adapter
after:
class UserAuth
in the same file. That will at least get you going in the right direction.

Resources