I have successfully completed the the album table tutorial in Zend Framework 2 manual. I have implemented using tablegateway. I can see that he used only one table named "album" and hence he implemented according to that one table.
Lets say I have another table called "artist" that holds the information of each artists from that "album" table.
Now in manual, he simply uses:
$this->getAlbumTable()->fetchAll();
Now I want to do similar thing with "artists" table so that my query can be like:
$this->getArtistsTable()->fetchAll();
So what should I change or add?? I already have created the artist table in mySql with columns: Name, DOB, Country.
P.S: I am not going to use joins or anything atm. Just want to access the second table in same controller (same module).
SOLUTION:
With the help of Venca, I was able to solve this problem: here is how you should edit the factory setting for 2 tables and more.
public function getServiceConfig()
{
// Given in Manual
return array(
'factories' => array(
'Album\Model\AlbumTable' => function($sm) {
$tableGateway = $sm->get('AlbumTableGateway');
$table = new AlbumTable($tableGateway);
return $table;
},
'AlbumTableGateway' => function ($sm) {
$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
$resultSetPrototype = new ResultSet();
$resultSetPrototype->setArrayObjectPrototype(new Album());
return new TableGateway('album', $dbAdapter, null, $resultSetPrototype);
},
// Added another table named Artist
'Album\Model\ArtistTable' => function($sm) {
$tableGateway = $sm->get('ArtistTableGateway');
$table = new AlbumTable($tableGateway);
return $table;
},
'ArtistTableGateway' => function ($sm) {
$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
$resultSetPrototype = new ResultSet();
$resultSetPrototype->setArrayObjectPrototype(new Artist());
return new TableGateway('artist', $dbAdapter, null, $resultSetPrototype);
},
),
);
}
Now you can access both tables from your controller. Problem Solved. Day well spent.
According to manual
Create model
Create model table
Add factory to your module
return array(
'factories' => array(
'Album\Model\ArtistTable' => function($sm) {
$tableGateway = $sm->get('ArtistTableGateway');
$table = new ArtistTable($tableGateway);
return $table;
},
'ArtistTableGateway' => function ($sm) {
$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
$resultSetPrototype = new ResultSet();
$resultSetPrototype->setArrayObjectPrototype(new Artist());
return new TableGateway('artist', $dbAdapter, null, $resultSetPrototype);
},
),
);
Related
I have one problem. I don't know how to use multiple table and join query in zf2.
I'm using service Manager and TableGateway for model. But in this it always use single table.
How can I use multiple table in single controller or model?
Here I'm using Module.php file and configure table gateway.
When I add another table gateway then it gives me errors.
public function getServiceConfig()
{
return array(
'factories' => array(
'User\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);
},
),
);
}
I need to insert userItems in user controller by using UseritemTable.php under the User/Model/UseritemTable. How I can achieve this?
Error message
Zend\Mvc\Controller\PluginManager::get was unable to fetch or create an instance for getUseritemTable
Updated Module.php
public function getServiceConfig()
{
return array(
'factories' => array(
'User\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);
},
'User\Model\UseritemTable' => function($sm) {
$tableGateway = $sm->get('UseritemTableGateway');
$table = new UseritemTable($tableGateway);
return $table;
},
'UseritemTableGateway' => function ($sm) {
$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
$resultSetPrototype = new ResultSet();
$resultSetPrototype->setArrayObjectPrototype(new Useritem());
return new TableGateway('useritem', $dbAdapter, null, $resultSetPrototype);
},
),
);
}
UserController.php under this userItemAction
public function userItemAction()
{
$form->get('submit')->setValue('Add');
$request = $this->getRequest();
if ($request->isPost()) {
$item = new Useritem();
$data = $request->getPost()->toArray();
$form->setData($data);
if($form->isValid()){
$item->exchangeArray($form->getData());
$this->getUseritemTable()->saveItem($item); // while saveItem cause error using getUseritemTable()
}
}
return array('form' => $form);
}
Here my code for User\Model\UseritemTable.php
namespace User\Model;
use Zend\Db\TableGateway\TableGateway;
class UseritemTable
{
protected $tableGateway;
public function __construct(TableGateway $tableGateway)
{
$this->tableGateway = $tableGateway;
}
public function fetchAll()
{
$resultSet = $this->tableGateway->select();
return $resultSet;
}
public function saveItem(User $item)
{
$this->tableGateway->insert($item);
}
}
Trying to adapt the ZF2 skeleton application, I'm having trouble with the fields retrieved in the resultSet.
My table 'project' contains four fields: id, title, shortTitle, year.
I'm using the typical fetchAll function:
public function fetchAll() {
$resultSet = $this->tableGateway->select();
return $resultSet;
}
The Project class reflects the four fields
class Project {
public $id;
public $title;
public $shortTitle;
public $year;
public function exchangeArray($data) {
$this->id = (!empty($data['id'])) ? $data['id'] : null;
$this->title = (!empty($data['title'])) ? $data['title'] : null;
$this->shortTitle = (!empty($data['shortTitle'])) ? $data['shortTitle'] : null;
$this->year = (!empty($data['year'])) ? $data['year'] : null;
}
}
The table gateway factory in Module.php is as described by the tutorial:
public function getServiceConfig() {
return array(
'factories' => array(
'Project\Model\ProjectTable' => function($sm) {
$tableGateway = $sm->get('ProjectTableGateway');
$table = new ProjectTable($tableGateway);
return $table;
},
'ProjectTableGateway' => function($sm) {
$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
$resultSetPrototype = new ResultSet();
$resultSetPrototype->setArrayObjectPrototype(new Project());
return new TableGateway('project', $dbAdapter, null, $resultSetPrototype);
},
),
);
}
The query passed to the database is correct and gives correct results:
SELECT `project`.* FROM `project`
$resultSet looks like it's getting the right prototype and the correct number of rows, but it does not match the column names properly. print_r($resultSet->current()); gives:
Project\Model\Project Object ( [id] => 1 [title] => Some title 1
[shortTitle] => [year] => )
While print_r($data); in exchangeArray function gives:
Array ( [id] => 1 [title] => Some title 1 [project] => 2012 )
It seems the object gets only the first two fields right, and then creates a field [project] with the value of the last column available within the result.
I must have made a stupid mistake somewhere, but I can't figure out where.
Thanks.
Please check your TableGateway factory in the Module.php - It should be similar to this -
Will need the use ... statements too.
use Zend\Db\ResultSet\ResultSet;
use Zend\Db\TableGateway\TableGateway;
use [.....]\Model\Product; //Add the Module Name here
use [.....]\Model\ProductTable; //Add the Module Name here
'Project\Model\ProjectTable' => function($sm) { //Change Module name accordingly.
$tableGateway = $sm->get('ProjectTableGateway');
$table = new ProjectTable($tableGateway);
return $table;
},
'ProjectTableGateway' => function ($sm) {
$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
$resultSetPrototype = new ResultSet();
$resultSetPrototype->setArrayObjectPrototype(new Project());
return new TableGateway('project', $dbAdapter, null, $resultSetPrototype);
//Change the the tablename accordingly.
},
Then add the result of print_r($resultSet->current()); in your question description.
The examples I have seen using Zend\Authentication instantiate a DbAdapter pointing to a database. But I want to pass it my table gateway model instead. Is this possible or am I misunderstanding something?
I have this setup in my Module.php:
'MyModule\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('view_users', $dbAdapter, null,
$resultSetPrototype);
},
),
And now in the controller action I'd like to do something like this:
use Zend\Authentication\Adapter\DbTable as AuthAdapter;
...
$authAdapter = new AuthAdapter(**$this->getUserTable()->getAdapter()**);
$authAdapter
->setTableName('users')
->setIdentityColumn('username')
->setCredentialColumn('password')
How can I integrate my TableGateway Model with Zend\Authentication?
Try this -
First - you should have the below code in config/autoload/global.php (or some other file)
'service_manager' => array(
'factories' => array(
'Zend\Db\Adapter\Adapter' => 'Zend\Db\Adapter\AdapterServiceFactory',
),
),
Second - in the controller action -
$dbAdapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
// create auth adapter
$authAdapter = new AuthAdapter($dbAdapter);
// configure auth adapter
$authAdapter->setTableName('users')
->setIdentityColumn('username')
->setCredentialColumn('password');
i want to create two controller with different tables fetch records then view,edit and update them my first album controller works fine but when i create another controller then it gives me error.
You need to register the service Album\Model\DemoTable with the service manager; just as you have with the existing Album\Model\AlbumTable.
The documentation shows you how to register the AlbumTable;
So by modifying that example, something like this should work:
// Module.php
public function getServiceConfig()
{
return array(
'factories' => array(
'Album\Model\DemoTable' => function($sm) {
$tableGateway = $sm->get('DemoTableGateway');
$table = new DemoTable($tableGateway);
return $table;
},
'Album\Model\AlbumTable' => function($sm) {
$tableGateway = $sm->get('AlbumTableGateway');
$table = new AlbumTable($tableGateway);
return $table;
},
'AlbumTableGateway' => function ($sm) {
$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
$resultSetPrototype = new ResultSet();
$resultSetPrototype->setArrayObjectPrototype(new Album());
return new TableGateway('album', $dbAdapter, null, $resultSetPrototype);
},
'DemoTableGateway' => function ($sm) {
$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
$resultSetPrototype = new ResultSet();
$resultSetPrototype->setArrayObjectPrototype(new Demo());
return new TableGateway('demo', $dbAdapter, null, $resultSetPrototype);
},
),
);
}
Obviously you will need to replace the Demo() class with the actual class that the table is mapping to.
I'm starting programming with Zend and I am using the default Album example they provide as a "getting started" guide.
I would like to have a select drop down field in the form, but I can't find an easy way of doing it like the code is right now
This is how I'm doing it without consulting DB from my UsersForm.php
$this->add(array(
'type' => 'Zend\Form\Element\Select',
'name' => 'level',
'options' => array(
'label' => 'User level',
'value_options' => array(
'1' => 'admin',
'2' => 'boss',
'3' => 'assistent',
'4' => 'client',
),
),
));
UPDATE
Ok, so following that tutorial using TableGateway I managed to have a selectable but is grabbing data from the 'project' table because the rest of my fields need that table, but I need that selectable to get from 'user' table.
My Module.php looks like this:
public function getServiceConfig()
{
return array(
'invokables' => array(),
'factories' => array(
'Project\Model\ProjectTable' => function($sm) {
$projectTableGateway = $sm->get('ProjectTableGateway');
$usersTableGateway = $sm->get('UsersTableGateway');
$table = new ProjectTable($projectTableGateway, $usersTableGateway);
return $table;
},
'project-model-selectable' => function($sm) {
$tableGateway = $sm->get('selecttable-gateway');
$table = new SelectTable($projectTableGateway, $usersTableGateway);
return $table;
},
'ProjectTableGateway' => function ($sm) {
$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
$resultSetPrototype = new ResultSet();
$resultSetPrototype->setArrayObjectPrototype(new Project());
return new TableGateway('project', $dbAdapter, null, $resultSetPrototype);
},
'UsersTableGateway' => function ($sm) {
$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
$resultSetPrototype = new ResultSet();
$resultSetPrototype->setArrayObjectPrototype(new Users());
return new TableGateway('user', $dbAdapter, null, $resultSetPrototype);
},
'selecttable-gateway' => function ($sm) {
$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
$resultSetPrototype = new ResultSet();
$resultSetPrototype->setArrayObjectPrototype(new SelectOption());
return new TableGateway('user', $dbAdapter, null, $resultSetPrototype);
},
),
);
}
And my getProject function in ProjectTable.php:
public function getProject($id)
{
$id = (int) $id;
$rowset = $this->projectTableGateway->select(array('id' => $id));
$row = $rowset->current();
if (!$row) {
throw new \Exception("Could not find row $id");
}
return $row;
}
My addAction in ProjectController.php
public function addAction()
{
$tableGateway = $this->getServiceLocator()->get('Project\Model\ProjectTable');
$form = new ProjectForm($tableGateway);
$form->get('submit')->setValue('Nuevo');
$request = $this->getRequest();
if ($request->isPost()) {
$project = new ProjectForm($tableGateway);
$form->setInputFilter($project->getInputFilter());
$form->setData($request->getPost());
if ($form->isValid()) {
$project->exchangeArray($form->getData());
$this->getProjectTable()->saveProject($project);
// Redirect to list of projects
return $this->redirect()->toRoute('project');
}
}
return array('form' => $form);
}
Thanks
public function getProject($id)
{
$id = (int) $id;
$rowset = $this->projectTableGateway->select(array('id' => $id));
$row = $rowset->current();
if (!$row) {
throw new \Exception("Could not find row $id");
}
return $row;
}