Show username of logged in user in zf2 - zend-framework2

I have login and logout system in ZF2. I want to show username of logged in user when he/she is logged in. Screen shot is given below:
I have different views like view/provinces/index.phtml, view/districts/index.phtml, etc.
I have layout.phtml in view/layout/layout.phtml, in which I described layout for admin which is for every view. So It is necessary to access username of logged in user in layout.phtml.
I have also corresponding controllers like Controller/ProvincesController.php, Controller/DistrictsController.php etc. I can access username of logged in user in Controller/ProvincesController.php etc by the code:
public function getAuthService()
{
$this->authservice = $this->getServiceLocator()->get('AuthService');
return $this->authservice;
}
$username = $this->getAuthService()->getStorage()->read();
But I am unable to access value of username of logged in user in layout.phtml.
So if anyone know about it or have simple idea or practice about it, then let me know please.
Module.php:
<?php
namespace Admin;
use Admin\Model\Profile;
use Admin\Model\ProfileTable;
use Admin\Model\Provinces;
use Admin\Model\ProvincesTable;
use Admin\Model\Districts;
use Admin\Model\DistrictsTable;
use Admin\Model\User;
use Admin\Model\UserTable;
use Zend\Db\ResultSet\ResultSet;
use Zend\Db\TableGateway\TableGateway;
use Zend\Mvc\ModuleRouteListener;
use Zend\Mvc\MvcEvent;
use Zend\ModuleManager\Feature\AutoloaderProviderInterface;
use Zend\Authentication\Adapter\DbTable as DbTableAuthAdapter;
use Zend\Authentication\AuthenticationService;
class Module implements AutoloaderProviderInterface
//class Module
{
public function getConfig()
{
return include __DIR__ . '/config/module.config.php';
}
public function getServiceConfig()
{
return array(
'abstract_factories' => array(),
'aliases' => array(),
'factories' => array(
// SERVICES
'AuthService' => function($sm) {
$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
$dbTableAuthAdapter = new DbTableAuthAdapter($dbAdapter, 'user','username','password', 'MD5(?)');
$authService = new AuthenticationService();
$authService->setAdapter($dbTableAuthAdapter);
return $authService;
},
// DB
'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);
},
// FORMS
'LoginForm' => function ($sm) {
$form = new \Admin\Form\LoginForm();
$form->setInputFilter($sm->get('LoginFilter'));
return $form;
},
// FILTERS
'LoginFilter' => function ($sm) {
return new \Admin\Form\LoginFilter();
},
'Admin\Model\ProvincesTable' => function($sm) {
$tableGateway = $sm->get('ProvincesTableGateway');
$table = new ProvincesTable($tableGateway);
return $table;
},
'ProvincesTableGateway' => function ($sm) {
$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
$resultSetPrototype = new ResultSet();
$resultSetPrototype->setArrayObjectPrototype(new Provinces());
return new TableGateway('provinces', $dbAdapter, null, $resultSetPrototype);
},
'Admin\Model\DistrictsTable' => function($sm) {
$tableGateway = $sm->get('DistrictsTableGateway');
$table = new DistrictsTable($tableGateway);
return $table;
},
'DistrictsTableGateway' => function ($sm) {
$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
$resultSetPrototype = new ResultSet();
$resultSetPrototype->setArrayObjectPrototype(new Districts());
return new TableGateway('districts', $dbAdapter, null, $resultSetPrototype);
},
),
'invokables' => array(),
'services' => array(),
'shared' => array(),
);
}
public function getAutoloaderConfig()
{
return array(
'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/' . str_replace('\\', '/' , __NAMESPACE__),
),
),
);
}
}
Thanks in advance.

The recommend way would be to use identity (https://framework.zend.com/manual/2.4/en/modules/zend.view.helpers.identity.html) view helper. Then in any view model you could use it as follow:
if ($user = $this->identity()) {
echo 'Logged in as ' . $this->escapeHtml($user->getUsername());
} else {
echo 'Not logged in';
}
In order to make it work you have to register your authentication service under specific name- Zend\Authentication\AuthenticationService.
So in your module.config.php file, add to service_manager:
'service_manager' => array(
'aliases' => array(
'Zend\Authentication\AuthenticationService' => 'AuthService', // <--- this line
),
'invokables' => array(
'AuthService' => 'Your\Authentication\Class',
),
),
Then you should be able to use identity controller plugin and view helper.
In your case, Module.php should look like this:
...
public function getServiceConfig()
{
return array(
'abstract_factories' => array(),
'aliases' => array(
'Zend\Authentication\AuthenticationService' => 'AuthService', // <--- this line
),
'factories' => array(
// SERVICES
'AuthService' => function($sm) {
$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
$dbTableAuthAdapter = new DbTableAuthAdapter($dbAdapter, 'user','username','password', 'MD5(?)');
$authService = new AuthenticationService();
$authService->setAdapter($dbTableAuthAdapter);
return $authService;
},
// DB
'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);
},
// FORMS
'LoginForm' => function ($sm) {
$form = new \Admin\Form\LoginForm();
$form->setInputFilter($sm->get('LoginFilter'));
return $form;
},
// FILTERS
'LoginFilter' => function ($sm) {
return new \Admin\Form\LoginFilter();
},
'Admin\Model\ProvincesTable' => function($sm) {
$tableGateway = $sm->get('ProvincesTableGateway');
$table = new ProvincesTable($tableGateway);
return $table;
},
'ProvincesTableGateway' => function ($sm) {
$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
$resultSetPrototype = new ResultSet();
$resultSetPrototype->setArrayObjectPrototype(new Provinces());
return new TableGateway('provinces', $dbAdapter, null, $resultSetPrototype);
},
'Admin\Model\DistrictsTable' => function($sm) {
$tableGateway = $sm->get('DistrictsTableGateway');
$table = new DistrictsTable($tableGateway);
return $table;
},
'DistrictsTableGateway' => function ($sm) {
$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
$resultSetPrototype = new ResultSet();
$resultSetPrototype->setArrayObjectPrototype(new Districts());
return new TableGateway('districts', $dbAdapter, null, $resultSetPrototype);
},
),
'invokables' => array(),
'services' => array(),
'shared' => array(),
);
}
...
Then in your layout or any other .phtml file:
layout.phtml
...
<?php if ($this->identity()): ?>
<p>Welcome, <?php echo $this->identity()->getUsername(); ?></p>
<?php endif; ?>

Taking help of Mr. SzymonM's answer, I changed my Module.php as suggested by him, and write the following simple code in layout.phtml
This solve my issue and username is shown with first letter in Upper case.
<?php
if ($this->identity())
{
echo ucfirst($this->identity());
}
?>
//ucfirst is php function which make first letter Uppercase.

Related

Zend/Session with ZfcUser

I'm using ZfcUser in my app and I need to control the timeout parameter. As it's not part of the configuration I would like to set my own Zend/Session object (with the remember_me_seconds param) to ZfcUser on bootstrap but I don't know how.
By chance, has anyone done this already?
The easiest way to set session params is as follows
config\autoload\global.php
return array(
'service_manager' => [
'factories' => [
// Configures the default SessionManager instance
'Zend\Session\ManagerInterface' => 'Zend\Session\Service\SessionManagerFactory',
// Provides session configuration to SessionManagerFactory
'Zend\Session\Config\ConfigInterface' => 'Zend\Session\Service\SessionConfigFactory',
],
],
'session_manager' => [
// SessionManager config: validators, etc
],
'session_config' => [
'cache_expire' => 86400,
'cookie_lifetime' => 86400,
'remember_me_seconds' => 86400,
'gc_probability' => 10,
'gc_divisor' => 1000,
'use_cookies' => true,
'cookie_httponly' => true,
'cookie_lifetime' => 0, // to reset lifetime to maximum at every click
'gc_maxlifetime' => 86400,
],
);
And add line to onBootstrap method at Module.php
public function onBootstrap(MvcEvent $e)
{
$manager = $e->getApplication()->getServiceManager()->get('Zend\Session\ManagerInterface');
}
This will affect session setting and phpinfo() shows it.
I found it in zfcuser github
I don't use zfcuser but try this
autoload/global.php
<?php
use Zend\Session\Config\SessionConfig;
use Zend\Session\SessionManager;
use Zend\Session\Container;
return array(
'service_manager' => array(
'factories' => array(
'SessionManager' => function($sm) {
$sessionConfig = new SessionConfig();
$sessionConfig->setOption('remember_me_seconds', 1440);
$sessionManager = new SessionManager($sessionConfig);
Container::setDefaultManager($sessionManager);
return $sessionManager;
},
),
),
);
Module.php
public function onBootstrap($event)
{
$serviceManager = $event->getApplication()->getServiceManager();
$serviceManager->get('SessionManager')->start();
}
Here is how I did it. I am not the worlds greatest coder but this seems to work. This is all in Module.php
public function onBootstrap(MvcEvent $e)
{
$eventManager = $e->getApplication()->getEventManager();
$sharedManager = $eventManager->getSharedManager();
$sm = $e->getApplication()->getServiceManager();
//This checks to see if the user is logged in.
$eventManager->attach(MvcEvent::EVENT_DISPATCH, array($this, 'checkLogin'), 100);
}
//This function is attached to a listener to see if the user is not currently logged in
//If they are not logged in they will be redirected to the login page. This check will happen through the
//application so there is no need to keep checking in other modules
public function checkLogin (MvcEvent $e)
{
$session = new Container('defaults');
$this->route = $e->getRouteMatch();
$this->matchedRouteName = explode('/', $this->route->getMatchedRouteName());
$this->route_root = $this->matchedRouteName[0];
$sm = $e->getApplication()->getServiceManager();
$zfcServiceEvents = $sm->get('ZfcUser\Authentication\Adapter\AdapterChain')->getEventManager();
$zfcServiceEvents->attach(
'authenticate',
function ($e) use ($session) {
$session->offsetSet('sessionstart', $_SERVER['REQUEST_TIME']);
}
);
$auth = $sm->get('zfcuser_auth_service');
if (!$auth->hasIdentity() && $this->route_root != 'zfcuser')
{
$response = new \Zend\Http\PhpEnvironment\Response();
$response->getHeaders()->addHeaderLine('Location', '/user/login');
$response->setStatusCode(302);
$response->sendHeaders();
$e->stopPropagation(true);
return $response;
}
else if ($auth->hasIdentity() && $session->offsetGet('sessionstart') < ($_SERVER['REQUEST_TIME'] - 10800) && $this->route_root != 'zfcuser')
{
$response = new \Zend\Http\PhpEnvironment\Response();
$response->getHeaders()->addHeaderLine('Location', '/user/logout');
$response->setStatusCode(302);
$response->sendHeaders();
$e->stopPropagation(true);
return $response;
}
else if ($auth->hasIdentity())
{
$session->offsetSet('sessionstart', $_SERVER['REQUEST_TIME']);
}
}

How to write router for this url "/products/{id}/payment_plans/{plan-id}"

My current route file:
<?php
return array(
'controllers' => array(
'invokables' => array(
'Customers\Controller\Customers' => 'Customers\Controller\CustomersController',
),
),
// The following section is new` and should be added to your file
'router' => array(
'routes' => array(
'customers' => array(
'type' => 'Segment',
'options' => array(
'route' => '/customers[/:action][/:id]',
'constraints' => array(
'id' => '[0-9]+',
),
'defaults' => array(
'controller' => 'Customers\Controller\Customers',
),
),
),
),
),
'view_manager' => array(
'strategies' => array(
'ViewJsonStrategy',
),
),
);
How to function to get data
My current controller:
<?php
namespace Products\Controller;
// <-- Add this import
use Zend\Mvc\Controller\AbstractRestfulController;
use Products\Model\Products; // <-- Add this import
use Products\Form\ProductsForm; // <-- Add this import // <-- Add this import
use Zend\View\Model\JsonModel;
use Zend\Db\TableGateway\TableGateway;
class ProductsController extends AbstractRestfulController {
protected $productsTable;
private $returnMsg = array();
public function getList($data) {
$data = array();
$results = $this->getproductsTable()->select();
foreach ($results as $result) {
$data[] = $result;
}
return new JsonModel(array(
'data' => $data,
));
}
public function get($data) {
// $products = $this->getProductsTable()->getProducts($id);
return new JsonModel(array(
'data' => '',
));
}
public function payment_plans($data) {
// $products = $this->getProductsTable()->getProducts($id);
return new JsonModel(array(
'data' => '',
));
}
public function create($data) {
$form = new ProductsForm();
$products = new Products();
$form->setInputFilter($products->getInputFilter());
$form->setData($data);
if ($form->isValid()) {
$returnMsg = 'ok';
$products->exchangeArray($form->getData());
date_default_timezone_set("UTC");
$cdate = date("Y-m-d H:i:s", time());
$data = array(
'prd_main_id' => (isset($data['prd_main_id'])) ? $data['prd_main_id'] : null,
'prd_main_title' => (isset($data['prd_main_title'])) ? $data['prd_main_title'] : null,
'prd_main_description' => (isset($data['prd_main_description'])) ? $data['prd_main_description'] : null,
'prd_main_created_at' => (isset($cdate)) ? $cdate : null,
);
$this->getproductsTable()->insert($data);
/*
$cus_email = $data['cus_email'];
$results = $this->getCustomersTable()->select(array('cus_email' => $cus_email));
foreach ($results as $result) {
$datar[] = $result;
}
if (empty($datar)) {
$this->getCustomersTable()->insert($data);
$cus_email = $data['cus_email'];
$resultsv = $this->getCustomersTable()->select(array('cus_email' => $cus_email));
foreach ($resultsv as $resultv) {
$datav = $resultv;
}
$returnMsg = $datav;
} else {
$returnMsg = array('errors' => "email address already exists ! ");
}
*/
} else {
$returnMsg = 'ofgk';
}
return new JsonModel(array(
$data,
));
}
public function update($id, $data) {
$data['id'] = $id;
$products = $this->getProductsTable()->getProducts($id);
$form = new ProductsForm();
$form->bind($products);
$form->setInputFilter($products->getInputFilter());
$form->setData($data);
if ($form->isValid()) {
$id = $this->getProductsTable()->saveProducts($form->getData());
}
return new JsonModel(array(
'data' => $this->get($id),
));
}
public function delete($id) {
$this->getProductsTable()->deleteProducts($id);
return new JsonModel(array(
'data' => 'deleted',
));
}
public function getproductsTable() {
if (!$this->productsTable) {
$this->productsTable = new TableGateway('products', $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter'));
}
return $this->productsTable;
}
}
'name' => array(
'type' => 'Segment',
'options' => array(
'route' => '/products[/[:id]]/payment_plans[/[:payment_id]]',
'defaults' => array(
'__NAMESPACE__' => 'Template\Controller',
'id' => '[a-zA-Z][a-zA-Z0-9_-]*',
'payment_id' => '[a-zA-Z][a-zA-Z0-9_-]*',
),
),

How to set db adapter to Validator NoRecordExists and use it in controller?

I recently started learning ZF2 and hope someone can help me with this.
I am working my way through Rob Allen's Zend Framework 2 Tutorial (many thanks to #rob-allen).
Also I use a solution of #AlloVince and #Maciej How to set db adapter to Validator RecordExists in Zend Framework 2 (many thanks to both authors for it) and I confused because didn't to use this solution in editAction.
I see Fatal error: Call to a member function get() on a non-object in 'adapter' => $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter').
1) In the Module.php added
public function getServiceConfig()
{
return array(
'invokables' => array(
'RegionModel' => 'FcLibraries\Model\Region', //<-- added it
),
'factories' => array(
'FcLibraries\Model\RegionTable' => function ($sm) {
$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
$table = new RegionTable($dbAdapter);
return $table;
},
),
);
}
2) In the Region.php added
/**
* #var
*/
protected $serviceLocator;
/**
* #param \Zend\ServiceManager\ServiceLocatorInterface $serviceLocator
* #return Library
*/
public function setServiceLocator(ServiceLocatorInterface $serviceLocator)
{
$this->serviceLocator = $serviceLocator;
return $this;
}
/**
* #return \Zend\ServiceManager\ServiceLocatorInterface
*/
public function getServiceLocator()
{
return $this->serviceLocator;
}
and
$inputFilter->add($factory->createInput(array(
'name' => 'name',
'required' => true,
'filters' => $this->_filters,
'validators' => array(
array(
'name' => 'StringLength',
'options' => array(
'encoding' => 'UTF-8',
'min' => 1,
'max' => 30,
),
),
array(
'name' => 'Db\NoRecordExists',
'options' => array(
'table' => $this->table,
'field' => 'name',
//'exclude' => array(
// 'field' => 'id',
// 'value' => $this->id
//),
'adapter' => $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter'),
),
),
),
)));
3) In the RegionController.php in addAction using
$model = $this->getServiceLocator()->get('RegionModel');
instead of $model = new Region();.
This works fine for addAction, But I can not understand how I should use it in editAction.
My
public function editAction()
{
$id = (int)$this->params()->fromRoute('id', 0);
if (!$id) {
return $this->redirect()->toRoute('zfcadmin/region', array(
'action' => 'add'
));
}
$data = $this->getRegionTable()->get($id);
$form = new RegionForm();
$form->bind($data);
$form->get('submitBtn')->setAttribute('value', 'Save');
$request = $this->getRequest();
if ($request->isPost()) {
$form->setInputFilter($data->getInputFilter());
$form->setData($request->getPost());
if ($form->isValid()) {
$this->getRegionTable()->save($form->getData());
return $this->redirect()->toRoute('zfcadmin/regions');
}
}
return array(
'id' => $id,
'form' => $form,
);
}
My RegionTable has the following code:
/**
* #param \Zend\Db\Adapter\Adapter $adapter
*/
public function __construct(Adapter $adapter)
{
$this->adapter = $adapter;
$this->resultSetPrototype = new ResultSet();
$this->resultSetPrototype->setArrayObjectPrototype(new Region());
$this->initialize();
}
public function get($id)
{
$id = (int)$id;
$rowSet = $this->select(array('id' => $id));
$row = $rowSet->current();
if (!$row) {
throw new \Exception("Could not find row $id");
}
return $row;
}
Many thanks to all who will answer my question.
Best regards, Ruslan.
Instead of using the form filter from the entity which you gathered from the table you should instantiate a new entity via the service manager to use the database adapter.
You have a few options:
Move the input filter to its own class and instantiate via the service manager so your database adapter is injected.
Change the prototype object in the table gateway factory to be instantiated via the service manager factory.
Instantiate a separate entity via the service manager and get the input filter from there.
I personally would go for option 1 as it separates the code better.
Some examples:
Option 1 (my choice):
This involves moving the filter to its own file and class, creating a factory for it whilst injecting the database adapter. We will then, in the controller, get the filter via the service manager and apply the filter to the form.
So first move your filter to a file in ModName\src\ModName\Form\RegionFilter.php, obviosly replacing ModName with your module name.
and change the code to like so:
<?php
namespace Region\Form;
use Zend\InputFilter\Factory as InputFactory;
use Zend\InputFilter\InputFilter;
use Zend\InputFilter\InputFilterAwareInterface;
use Zend\InputFilter\InputFilterInterface;
use Zend\Db\Adapter\Adapter;
class RegionFilter implements InputFilterAwareInterface {
/**
* #var inputFilter
*/
protected $inputFilter;
/**
* #var Database Adapter
*/
protected $dbAdapter;
/**
* #param \Zend\InputFilter\InputFilterInterface $inputFilter
* #throws \Exception
*/
public function setInputFilter(InputFilterInterface $inputFilter) {
throw new \Exception("Not used");
}
/**
* #param \Zend\Db\Adapter $dbAdapter
*/
public function __construct(Adapter $dbAdapter) {
$this->dbAdapter = $dbAdapter;
}
/**
*
* #return Zend\Db\Adapter
*/
public function getDbAdapter() {
return $this->dbAdapter;
}
/**
* #return \Zend\InputFilter\InputFilter
*
* Get the input filter (build it first)
*/
public function getInputFilter() {
if (!$this->inputFilter) {
$inputFilter = new InputFilter();
$factory = new InputFactory();
$inputFilter->add($factory->createInput(array(
'name' => 'name',
'required' => true,
'filters' => $this->_filters,
'validators' => array(
array(
'name' => 'StringLength',
'options' => array(
'encoding' => 'UTF-8',
'min' => 1,
'max' => 30,
),
),
array(
'name' => 'Db\NoRecordExists',
'options' => array(
'table' => $this->table,
'field' => 'name',
//'exclude' => array(
// 'field' => 'id',
// 'value' => $this->id
//),
'adapter' => $this->getDbAdapter(),
),
),
),
)));
$this->inputFilter = $inputFilter;
}
return $this->inputFilter;
}
}
?>
You would then create a factory like so in Module.php:
public function getServiceConfig()
{
return array(
'factories' => array(
'ModName\Form\RegionFilter' => function($sm) {
$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
return new RegionFilter($dbAdapter);
},
),
);
}
And finally in your controller, just do the following:
if ($request->isPost()) {
$filter = $this->getServiceLocator()->get('ModName\Form\RegionFilter');
$form->setInputFilter($filter->getInputFilter());
$form->setData($request->getPost());
if ($form->isValid()) {
$this->getRegionTable()->save($form->getData());
return $this->redirect()->toRoute('zfcadmin/regions');
}
}
Option 2:
This involves constructing your table with an instance of Region injected. Then you can set the prototype to this.
So in your table construct:
public function __construct(Adapter $adapter, Region $region)
{
$this->adapter = $adapter;
$this->resultSetPrototype = new ResultSet();
$this->resultSetPrototype->setArrayObjectPrototype($region);
$this->initialize();
}
And then your factory:
public function getServiceConfig()
{
return array(
'invokables' => array(
'RegionModel' => 'FcLibraries\Model\Region',
),
'factories' => array(
'FcLibraries\Model\RegionTable' => function ($sm) {
$region = $sm->get('RegionModel');
$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
$table = new RegionTable($dbAdapter,$region);
return $table;
},
),
);
}
You should be able to leave the rest of the code as is. Eg the controller. Now I have not tested this method so I'm not 100% it will work, but I think it should. The other two methods I have used previously myself.
Option 3 (the simplest):
This involves getting a separate region model via the service manager and using that to apply the input filter to the form.
public function editAction()
{
$id = (int)$this->params()->fromRoute('id', 0);
if (!$id) {
return $this->redirect()->toRoute('zfcadmin/region', array(
'action' => 'add'
));
}
$data = $this->getRegionTable()->get($id);
$form = new RegionForm();
$form->bind($data);
$form->get('submitBtn')->setAttribute('value', 'Save');
$request = $this->getRequest();
if ($request->isPost()) {
$region = $this->getServiceLocator()->get('RegionModel');
$form->setInputFilter($region->getInputFilter());
$form->setData($request->getPost());
if ($form->isValid()) {
$this->getRegionTable()->save($form->getData());
return $this->redirect()->toRoute('zfcadmin/regions');
}
}
return array(
'id' => $id,
'form' => $form,
);
}
I have not tested the code but you should get the gist. Any questions just ask.
For doing the validation for "Username already exists or not", Do the following simple way of Service Manager config settings like:
// config/autoload/global.php
return array(
'db' => array(
'driver' => 'Pdo',
'dsn' => 'mysql:dbname=zf2tutorial;host=localhost',
),
'service_manager' => array(
'factories' => array(
'Zend\Db\Adapter\Adapter' => function ($serviceManager) {
$adapterFactory = new Zend\Db\Adapter\AdapterServiceFactory();
$adapter = $adapterFactory->createService($serviceManager);
\Zend\Db\TableGateway\Feature\GlobalAdapterFeature::setStaticAdapter($adapter);
return $adapter;
}
),
)
);
and add the following array into getInputFilter():
array(
'table' => 'users',
'field' => 'username',
'adapter' => \Zend\Db\TableGateway\Feature\GlobalAdapterFeature::getStaticAdapter();
)

zf2 The supplied parameters to DbTable failed to produce a valid sql statement, please check table and column names for validity

On authentication I am getting an error message
"The supplied parameters to DbTable failed to produce a valid sql statement, please check table and column names for validity."
my login controller code is
$form= new login();
$request=$this->getRequest();
if ($request->isPost())
{
$formValidator = new rotaryfilter();
$post=$request->getPost();
$form->setInputFilter($formValidator->getInputFilter());
$form->setData($request->getPost());
if($form->isValid())
{
$formValidator->exchangeArray($form->getData());
$dbAdapter = $this->serviceLocator->get('Zend\Db\Adapter\Adapter');
$authAdapter = new DbTable($dbAdapter,'Login','username','pwd');
$authAdapter->setIdentity($formValidator->username)
->setCredential($formValidator->pwd);
//->setCredentialTreatment('MD5(?)');
$authService = $this->serviceLocator->get('auth_service');
$authService->setAdapter($authAdapter);
$result = $authService->authenticate();
if($result->isValid())
{
echo 'valid';
exit();
}
else { echo 'invalid';exit();}
}
}
return array('form'=> $form);
and my module.php contains
public function getServiceConfig()
{
return array(
'factories' => array(
'auth_service' => function ($sm) {
$authService = new AuthenticationService(new SessionStorage('auth'));
return $authService;
},
'General\Model\Login' => function($sm) {
$tableGateway = $sm->get('LoginGateway');
$table = new Login($tableGateway);
return $table;
},
'LoginGateway' => function ($sm) {
$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
$resultSetPrototype = new ResultSet();
$resultSetPrototype->setArrayObjectPrototype(new rotaryfilter());
return new TableGateway('Login', $dbAdapter, null, $resultSetPrototype);
},
),);
}
This may seems old but I was able to solve this error. This error is caused from you MySQL version.
This one works for me. All you need to do is to remove the driver_options from your db setup, this code is usually located at your global.php or .local.php from your Config file.
Change FROM:
'db' => array(
'driver' => 'Pdo_Mysql',
'dsn' => 'mysql:dbname=dbName;host=localhost',
'username' => 'dbUser',
'password' => 'dbPass',
'driver_options' => array(
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''
),
),
TO
'db' => array(
'driver' => 'Pdo_Mysql',
'dsn' => 'mysql:dbname=dbName;host=localhost',
'username' => 'dbUser',
'password' => 'dbPass',
),
Thank you. This solution solved my problem.

ZF2 Database object

I have a ZF2 application that I need to pass custom database queries from. I have set up my database credentials in local.php and global.php. From a class, how do I get a database object?
This is my global.php:
return array(
'db' => array(
'driver' => 'Pdo',
'dsn' => 'mysql:dbname=database_name;host=localhost',
'driver_options' => array(
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''
),
),
'service_manager' => array(
'factories' => array(
'Zend\Db\Adapter\Adapter' => 'Zend\Db\Adapter\AdapterServiceFactory',
),
),
);
To get the DB object
In Module.php
public function getServiceConfig()
{
return array(
'factories' => array(
'db_adapter' => function($sm) {
$config = $sm->get('Configuration');
return new \Zend\Db\Adapter\Adapter($config['db']);
},
'xyz_class_name' => function ($sm) {
return new \WhatEver\Model\xyzMapper($sm->get('db_adapter'));
},
),
);
}
In xyzMapper
namespace WhatEver\Model;
use Zend\Db\Adapter\Adapter;
class xyzMapper
{
protected $adapter;
/**
* Make the Adapter object avilable as local prtected variable
* #param Adapter $adapter - DB PDO PgSQL conn
*/
public function __construct(Adapter $adapter = null)
{
$this->adapter = $adapter;
}
/**
* #return result object
*/
public function getdata()
{
$sql = "SELECT * FROM tbl";
$statement = $this->adapter->query($sql);
return $statement->execute();
}
}

Resources