How to implement data model with this code - zend-framework

I am new to zend frame work . I am trying to learn zf create db-table tblename,zf create model tblname,zf create model tblnameMapper.
add user.php (form)
<?php
class Application_Form_Adduser extends Zend_Form
{
public function init()
{
$this->setMethod('post');
$username = $this->createElement('text','username');
$username->setLabel('Username:')
->setAttrib('size',10);
$password=$this->createElement('text','password');
$password->setLabel('Password')
->setAttrib('size',10);
$reg=$this->createElement('submit','submit');
$reg->setLabel('save');
$this->addElements(array(
$username,
$password,
$reg
));
return $this;
}
add user view:
<?php
echo 'Add user';
echo "<br />" .$this->a;
echo $this->form;
?>
admin controller:
<?php
class AdminController extends Zend_Controller_Action
{
public function adduserAction(){
$form = new Application_Form_Auth();
$this->view->form = $form;
$this->view->assign('a','Entere new user:');
if($this->getRequest()->isPost()){
$formData = $this->_request->getPost();
$uname=$formData['username'];
$pass=$formData['password'];
$msg=$uname." added to database successfully";
$this->view->assign('a',$msg);
$db= Zend_Db_Table_Abstract::getDefaultAdapter();
$query="INSERT INTO `user` ( `id` , `uname` , `password` )
VALUES ('', '{$uname}', '{$pass}');";
$db->query($query);
}}
i want to implement db-table with the above code .i am new to zend frame work i spend some time on reading programmers guide but in vain .It is very hard to get things from manual.So please some one explain step by step procedure for implementing the same .Thanks in advanced.

Ok here is a quick example:
Create DbTable Model (Basically an adapter for each table in your database):
at the command line: zf create db-table User user add -m moduleName if you want this in a module. This command will create a file name User.php at /application/models/DbTable that looks like:
class Application_Model_DbTable_User extends Zend_Db_Table_Abstract {
protected $_name = 'user'; //this is the database tablename (Optional, automatically created by Zend_Tool)
protected $_primary = 'id'; //this is the primary key of the table (Optional, but a good idea)
}
now to create a method in your DbTable model that executes the query from your controller, add a method similar to:
public function insertUser(array $data) {
$Idata = array(
'name' => $data['name'] ,
'password' => $data['passowrd']
);
$this->insert($Idata); //returns the primary key of the new row.
}
To use in your controller:
public function adduserAction(){
$form = new Application_Form_Auth(); //prepare form
try{
if($this->getRequest()->isPost()){//if is post
if ($form->isValid($this->getRequest()_>getPost()){ //if form is valid
$data = $form->getValues(); //get filtered and validated form values
$db= new Application_Model_DbTable_User(); //instantiate model
$db->insertUser($data); //save data, fix the data in the model not the controller
//do more stuff if required
}
}
$this->view->form = $form; //if not post view form
$this->view->assign('a','Entere new user:');
} catch(Zend_Exception $e) { //catach and handle exception
$this->_helper->flashMessenger->addMessage($e->getMessage());//send exception to flash messenger
$this->_redirect($this->getRequest()->getRequestUri()); //redirect to same page
}
}
This is about as simple as it gets. I have barely scratched the surface of what can be accomplished in simple applications with Zend_Db and a DbTable model. However you will likely find as I have, that at some point you will need more. That would be the time to explore the domain model and mappers.
For a really good basic tutrial that includes all of this and more please check out Rob Allen's ZF 1.x tutorial
I hope this helps.

Related

Zend_Form_Element requires each element to have a name

I'm trying to create a form in ZF 1.Here's my form class
class Application_Form_Album extends Zend_Form
{
public function init()
{
$this->setName('album');
#artist
$artist = new Zend_Form_Element_Text('artist');
$artist->setLabel('Artist')->setRequired(true)->addValidator('NotEmpty');
#title
$title = new Zend_Form_Element_Text('title');
$title->setLabel('Title')->setRequired(true)->addValidator('NotEmpty');
#submit
$submit = new Zend_Form_Element_Submit();
$submit->setAttribute('id','submitbutton');
$this->addElements(array($artist,$title,$submit));
}
}
and my controller action
public function addAction()
{
$form = new Application_Form_Album();
$form->submit->setLabel('Add');
$this->view->form = $form;
}
and my add.phtml
<?php echo $this->form;?>
But I'm getting this error.
Message: Zend_Form_Element requires each element to have a name
Not sure what I missed.Could anyone help me?
You should give a name for each form element. Missing name of submit. Zend Form generate id and name html tags from given name
For example:
$submit = new Zend_Form_Element_Submit('submitbutton');
And remove
$submit->setAttribute('id','submitbutton');
line.

Zend Form Registration with

I am new in Zend.
I have tried to create registration form in Zend.
I have get an array of form but it return false.
It returns me every time bye .
I don't know why???
It's Simple:
First, create your registration form under application/forms or use zend tool
zf enable form
zf create form registration
this will create a file under application/forms entitled Registration.php
class Application_Form_Registration extends Zend_Form
{
public function init()
{
$firstname = $this->createElement('text','firstname');
$firstname->setLabel('First Name:')
->setRequired(false);
$lastname = $this->createElement('text','lastname');
$lastname->setLabel('Last Name:')
->setRequired(false);
$email = $this->createElement('text','email');
$email->setLabel('Email: *')
->setRequired(false);
$username = $this->createElement('text','username');
$username->setLabel('Username: *')
->setRequired(true);
$password = $this->createElement('password','password');
$password->setLabel('Password: *')
->setRequired(true);
$confirmPassword = $this->createElement('password','confirmPassword');
$confirmPassword->setLabel('Confirm Password: *')
->setRequired(true);
$register = $this->createElement('submit','register');
$register->setLabel('Sign up')
->setIgnore(true);
$this->addElements(array(
$firstname,
$lastname,
$email,
$username,
$password,
$confirmPassword,
$register
));
}
}
This is a simple form with limited validation (only validation for fields that are required!)
Then you have to render the form in a view using the corresponding action:
as example in your UserController add action called
public function registerAction() {
//send the form to the view (register)
$userForm = new Application_Form_Registration();
$this->view->form = $userForm;
//check if the user entered data and submitted it
if ($this->getRequest()->isPost()) {
//check the form validation if not valid error message will appear under every required field
if ($userForm->isValid($this->getRequest()->getParams())) {
//send data to the model to store it
$userModel = new Application_Model_User();
$userId = $userModel->addUser($userForm->getValues());
}
}
}
The last two, is to render the form in the view called register
using
<?= $this->form ?>
and add method in your model called addUser() to handle the insertion of data into the database

non-object error on Doctrine 2 entity manager object

I'm trying to learn the zend framework by reading through a book. So far all the code in it has worked, but now I'm having trouble authenticating users. The book suggests doing this through an action helper and doctrine 2's entity managers.
here's the code i'm using for this
my authenticate helper class...
public function init()
{
// Initialize the errors array
Zend_Layout::getMvcInstance()->getView()->errors = array();
$auth = Zend_Auth::getInstance();
$em = $this->getActionController()->getInvokeArg('bootstrap')->getResource('entityManager');
if ($auth->hasIdentity()) {
$identity = $auth->getIdentity();
if (isset($identity)) {
$user = $em->getRepository('Entities\User')->findOneByEmail($identity);
Zend_Layout::getMvcInstance()->getView()->user = $user;
}
}
}
the entity repository function...
public function findOneByEmail($email)
{
$rsm = new ResultSetMapping;
$rsm->addEntityResult('Entities\User', 'a');
$rsm->addFieldResult('a', 'id', 'id');
$rsm->addFieldResult('a', 'email', 'email');
$rsm->addFieldResult('a', 'fname', 'fname');
$query = $this->_em->createNativeQuery(
'SELECT a.id, a.fname, a.email FROM users a
WHERE a.email = :email',
$rsm
);
$query->setParameter('email', $email);
return $query->getResult();
}
On the page view, i'm using the following code to check that the user is logged in:
<?php
if($this->user){
?>Welcome back, <?php echo $this->user->fname; ?> • Logout<?php
} ?>
the if condition passes when i'm logged in, but it won't print the user's name.
here's the error message I get on it:
Notice: Trying to get property of non-object in C:\Program Files (x86)\Zend\Apache2\htdocs\dev.test.com\application\views\scripts\user\index.phtml on line 3
Can anyone help me fix this?
I think part of the problem is here:
if (isset($identity)) {
$user = $em->getRepository('Entities\User')->findOneByEmail($identity);
Zend_Layout::getMvcInstance()->getView()->user = $user;
}
It looks like findOneByEmail expects the email address as the parameter but the whole identity object is being passed.
That probably causes return $query->getResult(); to return null or false so $view->user is not an object and has no property fname.
I think in findOneByEmail you need to do something like $user = $em->getRepository('Entities\User')->findOneByEmail($identity->email); where $identity->email is the property that contains the email address.

Validate a set of fields / group of fields in Zend Form

Is there any good solution for the following requirements:
A form with one field for zip code and default validators like number, length, etc.
After submission, the form is checked against a database.
If the zip code is not unique we have to ask for an city.
Examples:
Case 1: Submited zip code is unique in database. Everything is okay. Process form
Case 2: Submited zip code is not unique. Add a second field for city to the form. Go back to form.
We want to handle this in an generic way (not inside an controller). We need this logic for
a lot of forms. First thought was to add it to isValid() to every form or write a
validator with logic to add fields to the form. Subforms are not possible for us, because we need this for different fields (e.g. name and street).
Currently I'm using isValid method inside my forms for an User Form to verify the password and confirm password field. Also, when the form is displayed in a New Action, there are no modifications, but when displayed in an Edit Action, a new field is added to the form.
I think that is a good option work on the isValid method and add the field when the validation return false, and if you want something more maintainable, you should write your own validatator for that purpose.
Take a look at my code:
class Admin_Form_User extends Zf_Form
{
public function __construct($options = NULL)
{
parent::__construct($options);
$this->setName('user');
$id = new Zend_Form_Element_Hidden('id');
$user = new Zend_Form_Element_Text('user');
$user->setLabel('User:')
->addFilter('stripTags')
->addFilter('StringTrim')
->setAllowEmpty(false)
->setRequired(true);
$passwordChange = new Zend_Form_Element_Radio('changePassword');
$passwordChange->setLabel('Would you like to change the password?')
->addMultiOptions(array(1 => 'Sim', 2 => 'Não'))
->setValue(2)
->setSeparator('');
$password = new Zend_Form_Element_Password('password');
$password->setLabel('Password:')
->addFilter('stripTags')
->addFilter('StringTrim')
->setRequired(true);
$confirm_password = new Zend_Form_Element_Password('confirm_password');
$confirm_password->setLabel('Confirm the password:')
->addFilter('stripTags')
->addFilter('StringTrim')
->addValidator('Identical')
->setRequired(true);
$submit = new Zend_Form_Element_Submit('submit');
$submit->setLabel('Save');
$this->addElements(array($id,$name,$lastname,$group,$user,$passwordChange,$password,$confirm_password,$submit));
$this->addDisplayGroup(array('password','confirm_password'),'passwordGroup');
$this->submit->setOrder(8);
$this->setDisplayGroupDecorators(array(
'FormElements',
array('HtmlTag', array('tag' => 'div','id' => 'div-password'))
)
);
$passwordChange->clearDecorators();
}
public function addPasswordOption()
{
$this->changePassword->loadDefaultDecorators();
$this->getDisplayGroup('passwordGroup')
->addDecorators(array(
array('HtmlTag', array('tag' => 'div','id' => 'div-password'))
)
);
$this->password->setRequired(false);
$this->confirm_password->setRequired(false);
}
public function setPasswordRequired($flag = true)
{
$this->password->setRequired($flag);
$this->confirm_password->setRequired($flag);
}
public function isValid($data)
{
$confirm = $this->getElement('confirm_password');
$confirm->getValidator('Identical')->setToken($data['password']);
return parent::isValid($data);
}
}
So, in my controller:
public function newAction()
{
$this->view->title = "New user";
$this->view->headTitle($this->view->title, 'PREPEND');
$form = $this->getForm();
if($this->getRequest()->isPost())
{
$formData = $this->_request->getPost();
if($form->isValid($formData))
{
$Model = $this->getModel();
$id = $Model->insert($formData);
$this->_helper->flashMessenger('The user data has beed updated.');
$this->_helper->redirector('list');
}
}
$this->view->form = $form;
}
public function editAction()
{
$this->view->title = "Edit user";
$this->view->headTitle($this->view->title, 'PREPEND');
$id = $this->getRequest()->getParam('id');
$form = $this->getForm();
// Add yes or no password change option
$form->addPasswordOption();
$Model = $this->getModel();
if($this->getRequest()->isPost())
{
$formData = $this->getRequest()->getPost();
// Change password?
if($formData['changePassword'] == 2) $form->setPasswordRequired(false);
if($form->isValid($formData))
{
$Model->update($formData);
$this->_helper->flashMessenger('The user data has beed updated.');
$this->_helper->redirector('list');
}
}
$data = $Model->getById($id)->toArray();
$form->populate($data);
$this->view->form = $form;
}
You will probably need a Javascript form validator for that. In the submit function perform an AJAX call to check if the zipcode is unique. If not, show an extra city field.
But you still have to perform the validation server side: never trust user input, even if it's validated on the client side.

Extending Zend_View_Helper_FormElement

I have created this file at My/View/Helper/FormElement.php
<?php
abstract class My_View_Helper_FormElement extends Zend_View_Helper_FormElement
{
protected function _getInfo($name, $value = null, $attribs = null,
$options = null, $listsep = null
) {
$info = parent::_getInfo($name, $value, $attribs, $options, $listsep);
$info['id'] = 'My new ID';
return $info;
}
}
How can i get the normal form elements to use this instead?
Why i want this?
Say that i use the same form multiple times on a page, the 'id='-tag of the formelements will apear multiple times, this is not w3c-valid. So initially i want to prefix the id with the id of the form.
Any better ideas or ways to do this is much apreciated.
Update: Just realized it's the same problem with the decorators :( Don't think this is the right path i've taken.
Create new form class extending Zend_Form and in the init() method use variable $ns to add prefix/suffix to all elements. You can set $ns variable through form constructor.
class Form_Test extends Zend_Form
{
protected $ns;
public function init()
{
$this->setAttrib('id', $this->ns . 'testForm');
$name = new Zend_Form_Element_Text('name');
$name->setAttrib('id', $this->ns . 'name');
$name->setLabel('Name: *')->setRequired(true);
$submit = new Zend_Form_Element_Submit('submit');
$submit->setAttrib('id', $this->ns . 'submitbutton');
$submit->setLabel('Add')->setIgnore(true);
$this->addElements(array($name, $submit));
}
public function setNs($data)
{
$this->ns = $data;
}
}
In the controller or wherever you are calling this forms specify each form instance:
$form1 = new Form_Test(array('ns' => 'prefix1'));
$this->view->form1 = $form1;
$form2 = new Form_Test(array('ns' => 'prefix2'));
$this->view->form2 = $form2;
// Validation if calling from the controller
if ($form1->isValid()) ...
Using multiple instances of same forms on a page can be validated if used as subform.
SubForms prefix all id's with the name/identifier of the subform.