how to update main registration table and secondary multicheckbox populated table? - zend-framework

I have a registration form with different input fields one of them being a multi checkbox so that the user can decide what countries he wants to receive information from. This last one is created like this:
$pais = $this->createElement('multiCheckbox', 'pais');
$pais->setLabel('Pais\es: ');
$pais->addMultioption('1', 'Argentina');
$pais->addMultioption('2', 'Espa?a');
$pais->addMultioption('3', 'Brasil');
$pais->addMultioption('4', 'USA');
$pais->addMultioption('5', 'Italia');
$this->addElement($pais);
In my UserController I have the following action to update the table 'users':
public function createAction()
{
$this->view->pageTitle = 'Create User';
require_once APPLICATION_PATH . '/models/Users.php';
$userForm = new Form_User();
if ($this->_request->isPost()) {
if ($userForm->isValid($_POST)) {
$userModel = new Model_User();
$userMode->createUser(
$userForm->getValue('email'),
$userForm->getValue('password'),
$userForm->getValue('url'),
$userForm->getValue('responsable'),
$userForm->getValue('role')
);
return $this->_forward('list');
}
}
$userForm->setAction('/user/create');
$this->view->form = $userForm;
}
which of course, right now is not contemplating the multicheckbox populatedn$pais variable, nor here nor in the model:
class Model_User extends Zend_Db_Table_Abstract
{
protected $_name = 'users';
public function createUser($email, $password, $url, $responsable, $role)
{
// create a new row
$rowUser = $this->createRow();
if($rowUser) {
// update the row values
$rowUser->email = $email;
$rowUser->password = md5($password);
$rowUser->url = $url;
$rowUser->responsable = $responsable;
$rowUser->role = $role;
$rowUser->save();
//return the new user
return $rowUser;
} else {
throw new Zend_Exception("El usuario no se ha podido crear!");
}
}
}
I have also a 'pais' table, which contains the 5 different countries, and I'm working on a separate model for 'users_has_pais' which is the table I created in the workbench for this purpose...but I'm not getting any results with what I'm doing right now. Can someone point me in the right path to get to update 'users_has_pais' at the same time that I update the 'users' table?
Thanks a lot in advance to anyone with good advice on this.
EDIT: this is the db model in case anyone needs it to figure out what I'm saying
EDIT2:
public function createAction()
{
$this->view->pageTitle = 'Create User';
require_once APPLICATION_PATH . '/models/Users.php';
$userForm = new Form_User();
if ($this->_request->isPost()) {
if ($userForm->isValid($_POST)) {
$userModel = new Model_User();
$user = $userModel->createUser(
$userForm->getValue('email'),
$userForm->getValue('password'),
$userForm->getValue('url'),
$userForm->getValue('responsable'),
$userForm->getValue('role')
);
$paises = $this->getRequest()->getParam('pais');
$userId = intval($user['id']);
require_once APPLICATION_PATH . '/models/UserHasPais.php';
$paisesModel = new Model_UsersHasPais();
$paisesModel->updateUserPais($userId, $paises);
return $this->_forward('index');
}
}
and users_has_pais model:
class Model_UsersHasPais extends Zend_Db_Table_Abstract
{
protected $_name = 'users_has_pais';
public function updateUserPais($id, array $paises)
{
$row = ($r = $this->fetchRow(array('users_id = ?' => $id))) ? $r : $this->createRow();
foreach($paises as $pais){
$row->users_id = $id;
$row->pais_id = $pais;
$row->save();
}
}
}

One way would be to create user row first, and use it's ID when creating rows for 'user_has_pais'. A pseudo-code is below:
public function createAction()
{
$this->view->pageTitle = 'Create User';
require_once APPLICATION_PATH . '/models/Users.php';
$userForm = new Form_User();
if ($this->_request->isPost()) {
if ($userForm->isValid($_POST)) {
$userModel = new Model_User();
$newUserRow = $userMode->createUser(
$userForm->getValue('email'),
$userForm->getValue('password'),
$userForm->getValue('url'),
$userForm->getValue('responsable'),
$userForm->getValue('role')
);
$user_id = newUserRow->id;
$checkBoxValues = $userForm->getValue('pais');
// $checkBoxValues should be an array where keys are option names and
// values are values. If checkbox is not checked, than the value = 0;
// At this moment I'm not 100% sure of the real nature of the 'pais' value,
// but this is only an example.
// I also assume that the values of the checkboxfields correspond to IDs in
// 'pais'.
foreach ($checkBoxValues as $key => $pais_id) {
if (intval(pais_id) > 0) {
// if language was checked
// do insert into user_has_pais having $pais_id and $user_id.
}
}
return $this->_forward('list');
}
}
$userForm->setAction('/user/create');
$this->view->form = $userForm;
}
You could also put all of this in transaction if you want.
Hope this helps, or at least you point you in the right direction.

Related

How to update an object in Zend Framework 2

i'm trying to update an object by using this code :
The column co_nbre will be updated to 0 !!!!
I think you will help me to fix this issue and thnx a lot.
public function update($model) {
$data = get_object_vars($model);
$id = (int) $model->id;
$this->tableGateway->update($data, array('id' => $id));
}
and this is how did i use it in my controller:
if ($form->isValid()) {
$data = $form->getData();
$addi_info = new Addiinfo();
$addi_info->exchangeArray($data);
$addi_info->co_nbre = $request->getPost("co_nbre");
$addi_info->user_pin = $this->layout()->pin;
$addi_info->co_latitude = $request->getPost("latitude");
$addi_info->co_longitude = $request->getPost("longitude");
$addi_info->co_adresse = $request->getPost("adresse");
print_r($addi_info);die;
$checkuser=$this->getAddiinfoTable()->getAddiInfoByUserPin($user_pin);
if($checkuser[user_pin]==$user_pin){
$this->getAddiinfoTable()->update($addi_info);
I think you should create a function that returns associative array from model itself.
May be some of property in "Addiinfo" class be protected/private, so you need to get all property-value of model from inside it.
This one should be in your "Addiinfo" class,
public function getArrayData()
{
return get_object_vars($this);
}
Then call it in update function
public function update($model) {
$data = $model->getArrayData();
$id = (int) $model->id;
$this->tableGateway->update($data, array('id' => $id));
}

How to populate zend form using data from different database columns?

I have a form :
$houserent = new Zend_Form_Element_Text('houserent');
$houserent ->setLabel('House Rent :');
$this ->addElement($houserent);
$tax = new Zend_Form_Element_Text('tax');
$siteName ->setLabel('Tax :');
$this ->addElement($tax);
$internet = new Zend_Form_Element_Text('internet');
$internet->setLabel('Internet :');
$this ->addElement($internet);
and my data table "test" is
id name value
1 house rent 100
2 tax 10
3 internet 10
I want to populate the form using the above data from tha database table. But I don't know how to this. Please help me. Thanks
You can overwrite the populate function in your form.
public function populate($data)
{
foreach($data as $field => $value)
{
$this->{$field}->setValue($value);
}
return $this;
}
where $data is an associated array of name => value.
[edit]
So you form is now:
<?php
class Form_Admin_Settings_Add extends Zend_Form
{
public function init()
{
$houserent = new Zend_Form_Element_Text('houserent');
$houserent->setLabel('House Rent :');
$this->addElement($houserent);
$tax = new Zend_Form_Element_Text('tax');
$siteName->setLabel('Tax :');
$this->addElement($tax);
$internet = new Zend_Form_Element_Text('internet');
$internet->setLabel('Internet :');
$this->addElement($internet);
}
public function populate($data)
{
foreach($data as $field => $value)
{
$this->{$field}->setValue($value);
}
return $this;
}
}
In your controller:
<?php
//instantiate form and model
$form = new Form_Admin_Settings_Add();
$model = new Model_Test();
//get results
$results = $model->fetchAll()->toArray();
$data = array();
//put results into our data array as name => value
foreach($results as $r)
{
$data[$r['name']] = $r['value'];
}
//populate our form
$form->populate(data);
echo $form;
Try some like this:
class Form extends Zend_Form {
public funcition Form(){
$houserent = new Zend_Form_Element_Text('houserent');
$houserent->setLabel('House Rent :')
->setValue($this->_Data['houserent']);
$this->addElement($houserent);
}
public function setData($Data){
$this->_Data = $Data;
return $this;
}
}

how to insert zend form values in two tables in zend?

i have two tables users and userslog where i have users contains id, username,email,gender and userslog contains id,firstname,lastname,designation and u_id which is foreign key of users table.
my register controller
class RegisterController extends Zend_Controller_Action
{
public function init()
{
/* Initialize action controller here */
}
public function indexAction()
{
$form = new Application_Form_register();
$this->view->form = $form;
if($this->getRequest()->isPost())
{
$data = $this->getRequest()->getPost();
}
}
}
my register model is
class Application_Model_DBtable_register extends Zend_Db_Table
{
protected $_name = 'users';
// i have to define two tables here!! how?
}
my register zend form
class Application_Form_register extends Zend_Form
{
public function init()
{
$this->setName('register');
$this->setMethod('post');
$firstname = $this->createElement('text', 'firstname');
$firstname->setLabel('FirstName: ')
->setRequired(true)
->setFilters(array(
'stringTrim','StringToLower'));
$lastname = $this->createElement('text', 'lastname');
$lastname->setLabel('LastName: ')
->setRequired(true)
->setFilters(array(
'stringTrim','StringToLower'));
$email = $this->createElement('text', 'email');
$email->setLabel('Email: ')
->setRequired(true);
$username = $this->createElement('text', 'username');
$username->setLabel('UserName: ')
->setRequired(true)
->setFilters(array(
'stringTrim','StringToLower'));
$password = $this->createElement('password', 'password');
$password->setLabel('Password: ')
->setRequired(true);
$password2 = $this->createElement('password', 'password2');
$password2->setLabel('Confirm Password: ')
->setRequired(true);
$submit = $this->createElement('submit', 'register');
$submit->setLabel('Register')
->setIgnore(true);
$this->addElements(array(
$firstname,
$lastname,
$email,
$username,
$password,
$password2,
$submit));
}
}
how can i do it? can we use Zend_Auth for authentication? if yes then how.please give me example. I saw $_dependantTable and $_referenceMaps but i can't undestand it . I am confused how to do it because i am not able to define table name more than once in a class. i have to insert the values at same time in two different tables.
So as to insert values in users and userslog tables, you can try it:
In your RegisterController:
$db = new Application_Model_DBtable_register();
$db->instertValuesInUsers(array('column_name' => $data['value'], 'column_name' => $data['value'], ...........));
$db->insertValuesInUserslog(array('column_name' => $data['value'], 'column_name' => $data['value'], ...........));
In you Application_Model_DBtable_register:
public function instertValuesInUsers(array $data) {
$this->insert($data);
}
public function insertValuesInUserslog(array $data) {
$db = new Zend_Db_Table(array('name' => 'userslog'));
$db->insert($data);
}
ok this is incorrect:
class Application_Model_DBtable_register extends Zend_Db_Table
{
protected $_name = 'users';
// i have to define two tables here!! how?
}
The intent of classes that have DbTable in their names is that they they are the adapter/gateway to a single database table.
So your issue would breakdown into at least 2 classes/files:
class Application_Model_DBtable_Users extends Zend_Db_Table
{
protected $_name = 'users';
}
class Application_Model_DBtable_Userslog extends Zend_Db_Table
{
protected $_name = 'userslog';
}
I would at this level put a method in either class that does the actions required to register a user. Later you may decide to use mappers and domain objects.
class Application_Model_DBtable_Users extends Zend_Db_Table
{
protected $_name = 'users';
/*
* psuedocode not meant for production
*/
public function register($array $data) {
//sort out the data
$user = array();//put the elements from the $data array that you want to go into the users table
$userLog = array(); //same thing for the userslog table
//get userslog adapter
$userlogTable = new Application_Model_DbTable_Userslog();
//do the first insert
$result = $this->insert($user);
//insert returns the primary key of the row created,
$u_id = array('u_id' => $result);
$userLog = array_merge($u_id, $userLog); //merge u_id with existing data
//perform second insert
$result2 = $userlogTable->insert($userLog);
//handle any errors
}
}
This should provide a basic example to demonstrate the steps you might take to implement you design. The point behind the DbTable models is to abstract the connection to a given table, each table has it's own DbTable model. The DbTable model provides an adapter to each table and access to the api provided by Zend_Db_Table_Abstract.
The Steps shown above could just as easily be taken in a third model or in the controller itself.
Note: There may be away to do this with one sql statement but I'm not the person who knows that answer.

Zend Framework query db and getParam

At the moment I have a page where I have retrieved information on a club by the id of that club. I now have a comments box where I want to retrieve the comments about that club, in the comments table I have the club_id and the parameter "club_id" is passed into this page. At the moment I am retrieving all of the comments from the table but I want just the comments for that club. A point in the right direction would be great!
Controller:
class ClubDescriptionController extends Zend_Controller_Action
{
public $auth = null;
public function init()
{
$this->auth=Zend_Auth::getInstance();
}
http://pastebin.com/m66Sg26x
protected function authoriseUser()
{
if (!$this->auth->hasIdentity()) {
$route = array('controller'=>'auth', 'action'=>'index');
$this->_helper->redirector->gotoRoute($route);
}
}
}
Model:
class Application_Model_DbTable_Comments extends Zend_Db_Table_Abstract
{
protected $_name = 'comments';
public function getComment($id) {
$id = (int) $id;
$row = $this->fetchRow('id = ' . $id);
if (!$row) {
throw new Exception("Count not find row $id");
}
return $row->toArray();
}
public function addComment($comment, $club_id) {
$data = array(
'comment' => $comment,
'club_id' => $club_id,
'comment_date' => new Zend_Db_Expr('NOW()'),
);
$this->insert($data);
}
public function deleteComment($id) {
$this->delete('id =' . (int) $id);
}
}
The view:
<div id="view-comments">
<?php foreach($this->comments as $comments) : ?>
<p id="individual-comment">
<?php echo $this->escape($comments->comment);?> -
<i><?php echo $this->escape($comments->comment_date);?></i>
</p>
<?php endforeach; ?>
</div>
I realise I am going to have to use the getComment(); function in my model and query it by the id but I'm getting confused on exactly how...
Thanks
It's been a while since I used Db_Table but I think you want to create a select object, which allows you to build a query that will select comments with the correct club_id:
$comments = new Application_Model_DbTable_Comments();
$select = $comments->select();
$select->where('club_id = ?', $id);
$this->view->comments = $comments->fetchAll($select);
you may want to order the comments by date, if so, you can do this by adding an order clause to the select:
$select->order('comment_date ASC');
take a look at the docs for Zend_Db_Table_Select, which has quite a few examples: http://framework.zend.com/manual/en/zend.db.table.html#zend.db.table.fetch-all
In your controller you are calling
$this->view->comments = $comments->fetchAll();
it should be
$this->view->comments = $comments->getComment($this->_request->getParam('club_id'));
where id variable will be fetched from url.
Here is the working controller:
public function indexAction() {
//authorisation
$this->authoriseUser();
//to get the paramter club_id to query for specific club information
$id = (int) $this->_request->getParam('club_id', 0);
//submit a comment
$form = new Application_Form_Comment();
$form->submit->setLabel('Comment');
$this->view->form = $form;
if ($this->getRequest()->isPost()) {
$formData = $this->getRequest()->getPost();
if ($form->isValid($formData)) {
$comment = new Application_Model_DbTable_Comments();
$comment->addComment($formData['comment'], $id);
} else {
$form->populate($formData);
}
}
//initialise table
$clubs = new Application_Model_DbTable_Clubs();
$clubs = $clubs->getClub($id);
$this->view->clubs = $clubs;
//to get the comments for the club
$comments = new Application_Model_DbTable_Comments();
$select = $comments->select();
$select->where('club_id = ?', $id);
$select->order('comment_date ASC');
$this->view->comments = $comments->fetchAll($select);
}

Zend Form addFilter StripTags not stripping tags

I need a little help clearing something up with Zend_Form and adding filters to an element. Now I was under the impression that when you add a filter to the form that, when the form is posted that filter was executed as part of dispatch in the controller.
However when testing my form to my horror the filter StripTags doesn't seem to be running and I am getting the data with the HTML tags in the data.
My Form element looks like this.
$address1 = new Zend_Form_Element_Textarea('address1');
$address1->addFilter('StripTags')
->addFilter('StringTrim')
->setAttrib('cols', 30)
->setAttrib('rows', 5)
->removeDecorator('DtDdWrapper')
->removeDecorator('label')
->removeDecorator('HtmlTag')
However if I put in the text area the some data with html tags in it and then check the form is valid using
$formData = $this->_request->getPost();
if($form->isValid($formData){
...
The data comes back with the tags in it. It only removed when I pass the data through the strip_tags() function.
I suppose my question is should the StipTags filter if so why isn't it? What am I missing here.
You didn't post code on how you're accessing the data after calling isValid. IIRC the filters will only take effect if you access the data via $form->getValue('someElement') or something along those lines.
Sorry, i know i'm late but in case any one faced the same problem,
I have faced this problem today and i found few ways to solve this problem:
first my code is:
This is the form class
class Application_Form_UserForm extends Zend_Form
{
public function init()
{
/* Form Elements & Other Definitions Here ... */
$this->setMethod('POST');
$fname = new Zend_Form_Element_Text('fname');
$fname->setLabel('First Name: ');
$fname->setAttribs(Array(
'placeholder'=>'Example: Eslam',
'class'=>'form-control'
));
$fname->setRequired();
$fname->addValidator('StringLength', false, Array(4,20));
$fname->addFilter('StringTrim');
$fname->addFilter('StripTags');
$fname->removeDecorator('DtDdWrapper');
$fname->removeDecorator('label');
$fname->removeDecorator('HtmlTag');
$lname = new Zend_Form_Element_Text('lname');
$lname->setLabel('Last Name: ');
$lname->setAttribs(Array(
'placeholder'=>'Example: Khoga',
'class'=>'form-control'
));
$lname->setRequired();
$lname->addValidator('StringLength', false, Array(4,20));
$lname->addFilter('StringTrim');
$lname->addFilter('StripTags');
$lname->removeDecorator('DtDdWrapper');
$lname->removeDecorator('label');
$lname->removeDecorator('HtmlTag');
$email = new Zend_Form_Element_Text('email');
$email->setLabel('Email: ');
$email->setAttribs(Array(
'placeholder'=>'Example#Example.com',
'class'=>'form-control'
));
$email->setRequired();
$email->addValidator('StringLength', false, Array(5,250));
$email->addFilter('StringTrim');
$email->addFilter('StripTags');
$email->removeDecorator('DtDdWrapper');
$email->removeDecorator('label');
$email->removeDecorator('HtmlTag');
$gender = new Zend_Form_Element_Select('gender');
$gender->setRequired();
$gender->addMultiOption('male','Male')->
addMultiOption('female','Female')->
addMultiOption('none','Prefer not to mention');
$gender->setAttrib('class', 'form-control');
$track_obj = new Application_Model_Track();
$allTracks = $track_obj->listAll();
$track = new Zend_Form_element_Select('track');
foreach($allTracks as $key=>$value)
{
$track->addMultiOption($value['id'], $value['name']);
}
$submit= new Zend_Form_Element_Submit('submit');
$submit->setAttribs(array('class'=>'btn btn-success'));
$reset= new Zend_Form_Element_Submit('reset');
$reset->setAttribs(array('class'=>'btn btn-danger'));
$this->addElements(array(
$fname,
$lname,
$email,
$gender,
$track,
$submit,
$reset
));
}
}
This is controller class
class UserController extends Zend_Controller_Action{
public function init()
{
/* Initialize action controller here */
}
public function indexAction()
{
// action body
}
public function listAction()
{
// action body
$user_model = new Application_Model_User();
$this->view->users = $user_model->listUsers();
$track_form = new Application_Form_Track();
$this->view->track_form = $track_form;
$track_model = new Application_Model_Track();
$request = $this->getRequest();
if($request->isPost())
{
if($track_form->isValid($request->getPost())){
$track_model-> addTrack($request->getParams());
$this->redirect('/user/add');
}
}
}
public function detailsAction()
{
// action body
$user_model = new Application_Model_User();
$us_id = $this->_request->getParam("uid");
$user = $user_model->userDetails($us_id);
$trackModel = new Application_Model_Track();
$track = $trackModel->getTrackName($user[0]['track']);
$user[0]['track'] = $track[0]['name'];
$this->view->user = $user[0];
}
public function deleteAction()
{
// action body
$user_model = new Application_Model_User();
$us_id = $this->_request->getParam("uid");
$user_model->deleteUser($us_id);
$this->redirect("/user/list");
}
public function addAction()
{
// action body
$form = new Application_Form_UserForm();
$request = $this->getRequest();
if($request->isPost()){
if($form->isValid($request->getPost())){
/*echo "<pre>";
print_r($form);
echo "</pre>";
exit;*/
$userData['fname'] = $form->getValue('fname');
$userData['lname'] = $form->getValue('lname');
$userData['email'] = $form->getValue('email');
$userData['gender'] = $form->getValue('gender');
$userData['track'] = $form->getValue('track');
$user_model = new Application_Model_User();
$user_model-> addNewUser($userData);
$this->redirect('/user/list');
}
}
$this->view->user_form = $form;
}
public function editAction()
{
// action body
$form = new Application_Form_UserForm();
$user_model = new Application_Model_User ();
$id = $this->_request->getParam('uid');
$user_data = $user_model-> userDetails($id)[0];
$form->populate($user_data);
$this->view->userName = $user_data['fname']." ".$user_data['lname'];
$this->view->user_form = $form;
$request = $this->getRequest();
if($request->isPost()){
if($form->isValid($request->getPost())){
$userData['fname'] = $form->getValue('fname');
$userData['lname'] = $form->getValue('lname');
$userData['email'] = $form->getValue('email');
$userData['gender'] = $form->getValue('gender');
$userData['track'] = $form->getValue('track');
$user_model-> updateUser($id, $userData);
$this->redirect('/user/list');
}
}
}
}
First Solution:
i used filter on Form elements in the form class,
but i retrieved data from $form object in the controller,
as i found that method
addFilter()
doesn't change in the $_POST array values, so i have retrieved the data from $form object and then passed it as array to Model.
Second Solution:
i have tried to apply the filter on the values in the controller, not in the form by creating object from filter class and apply needed filter
Third Solution:
is to use method
addValidator()
with regex which affects on $_POST values.