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;
}
Related
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() ...
}
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);
},
),
);
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);
}
}
I'm using ZF2 TableGateway to update some data:
$this->update($data, array('id' => $id)));
I want to add a limit to this query, such as:
$this->update($data, array('id' => $id)))->limit(1);
This doesn't work however. Any ideas how to achieve this?
Thank you!
In You Controller use this:
import:
use Zend\Db\TableGateway\TableGateway
in main controller
public function updateuserAction() {
$form = new UserRegistration();
$request = $this->getRequest();
$id = $this->params()->fromRoute('id');
if(!$id) {
$this->redirect()->toUrl('/REDIRECT_URL');
}
if ($request->isPost()) {
$registeruser = new UserRegistrationModel();
$formValidator = new UserRegistrationValidator(); {
$form->setInputFilter($formValidator->getInputFilter());
$form->setData($request->getPost());
}
if ($form->isValid()) {
$data = $form->getData();
unset($data['submit']);
$this->getUsersTable()->update($data, array('uid' => $id));
return $this->redirect()->toUrl('/REDIRECT_URL');
}
$view = new ViewModel(array('form' => $form, 'action' => $this->params()->fromRoute('action')));
return $view;
}
else {
$form->setData($this->getUsersTable()->select(array('uid' => $id))->current());
}
$view = new ViewModel(array('form' => $form, 'id' => $id , 'rowset' => $this->getUsersTable()->select(array('uid' => $id))->current()));
return $view;
}
public function getUsersTable() {
if (!$this->RegisterUser) {
$article = $this->RegisterUser = new TableGateway(
'users', $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter')
);
}
return $this->RegisterUser;
}
//// Controller ends
and in View :
// to get id ( IN FORM )
$form->setAttribute('action', $this->url('user',
array('action' => 'updateuser', 'id' => $id)));
/REDIRECT_URL is your url to redirect user,
CHANGE UID to id from database table,
getUsersTable() is table gateway
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.