I am working on a project based on Zend framework. In user registration I have to check for unique email. My code is working fine when I register a user for the first time, but when I try to update the user information and press the update button, it gives the error message:
Email already taken
Please help me to solve this problem. My code is attached below:
$this->addElement('text', 'email', array(
'label' => 'Your email address:',
'required' => true,
'filters' => array('StringTrim'),
'validators' => array(
'EmailAddress',
array('Db_NoRecordExists', true, array(
'table' => 'users',
'field' => 'email',
'messages' => array(
'recordFound' => 'Email already taken'
)
)
)
)
));
I have changed my controller to this:
public function addAction()
{
$modelUsers = new Model_Users();
$userId = $this->_getParam('userId');
$form = $this->_getAddForm();
if ($userId) {
$populateData = array();
$user = $modelUsers->fetch($userId);
if ($user instanceof Model_User) {
$populateData = $user->toArray();
}
$form->populate($populateData);
}
$request = $this->getRequest();
if ($request->isPost()) {
$email = $this->getRequest()->getParam('email');
if (strtolower(trim($email)) == $modelUsers->fetchByEmail($email)) {
// change $this->_user->getAccount()->getEmail() to retrieve the user's current email address
// remove validator from form
$form->getElement('email')->removeValidator('Db_NoRecordExists');
}
$post = $request->getPost();
if ($form->isValid($post)) {
$values = $form->getValidValues($post);
$data = array(
'firstName' => $values['firstName'],
'userTypeId' => 2,
'lastName' => $values['lastName'],
'email' => $values['email'],
'userName' => $values['userName'],
'password' => $values['password'],
'role' => $values['role']
);
if ($userId) {
$user = $modelUsers->fetch($userId);
if ($user instanceof Model_User) {
$user->setFromArray($data);
$success = $user->save();
if ($success) {
echo Zend_Json::encode(array('status' => self::STATUS_SUCCESS, 'message' => 'Successfully updated the user!'));
exit;
}
}
} else {
$user = $modelUsers->createRow($data);
$success = $user->save();
if ($success) {
echo Zend_Json::encode(array('status' => self::STATUS_SUCCESS, 'message' => 'Successfully added the user!'));
exit;
}
}
echo Zend_Json::encode(array('status' => self::STATUS_FAILED, 'message' => 'user not added'));
exit;
} else {
$errors = array();
$errors = $form->errors();
echo Zend_Json::encode(array('status' => self::STATUS_ERROR, 'data' => $errors));
exit;
}
}
$this->view->form = $form;
$this->_helper->layout->disableLayout();
}
Model:
public function fetchByEmail($email)
{
$email=fetchOne('SELECT email FROM users WHERE email = $email');
//$select->where('email=?',$email) ;
//$student = $this->fetchRow($select);
return $email;
}
But still this is not working
One simple way you can solve this problem is to remove the validator from that form element when the form is being edited. You may also want to keep the validator if they are attempting to change their email address since they shouldn't be able to change their email to one that already exists in the database.
Leave the validator in your Zend_Form class, add this code only when a user is being edited.
if ($this->getRequest->isPost()) {
$email = $this->getRequest()->getParam('email'); // get email from form
// if email address has not changed, remove validator from form
if (strtolower(trim($email)) == $this->_user->getAccount()->getEmail()) {
// change $this->_user->getAccount()->getEmail() to retrieve the user's current email address
// remove validator from form
$form->getElement('email')->removeValidator('Db_NoRecordExists');
}
// validate form
if ($form->isValid($this->getRequest()->getPost()) {
//...
}
}
So what you are doing is removing the Db_NoRecordExists validator from the form element when the form is being edited, and only if they are not attempting to change their email address if they are allowed to do so.
It will give you allways this error because you are using validation , that email is present in DB table or not.
But the email is existing in database that's why it is giving error.
Remove this validation , it will help you.
if(isset($_SESSION['session_id']))
{
// code for update query
}
else
{
// code for insert query
}
Related
I have a function in user controller in laravel that allows users to enter their name and email in a form and send an email to administrator. But when I try to the variable containing them in the MailTo function, it gives error. Here is my code:
public function send_email_contact_us(){
$name = Input::get('name');
$email = Input::get('email');
$message_contact = Input::get('message');
$sender_email = Input::get('email');
$sender_name = Input::get('name');
$validator = Validator::make(
array(
'name' => $name,
'email' => $email
), array(
'name' => 'required',
'email' => 'required',
)
);
if ($validator->fails())
{
$error_messages = $validator->messages()->all();
return Redirect::back()->with('flash_errors',"Message not sent, please try again.");
}
else
{
$data=array("name"=>$name,"email"=>$email,"message_contact"=>$message_contact);
Mail::send('emails.contactus',$data, function($message)
{
$message->from($sender_email, $sender_name); // THIS GIVES ERROR
$message->to("admin#admin.com")->subject('Contact Us');
});
return Redirect::back()->with('flash_success',"Message sent successfully.");
}
}
Any help would be highly appreciated.
change to this
Mail::send('emails.contactus',$data, function($message) use($sender_email,$sender_name)
{
$message->from($sender_email, $sender_name);
$message->to("admin#admin.com")->subject('Contact Us');
});
To use external variables in a closure you have to import the variable into the closure by using the use keyword
I am working in laravel 5.1 and my update profile was working but will not encrypted and not working now.
When I try to update the user table will also password_confirmation field and causes a conflict in the database. I do not understand.
In the form says successfully but the database does not update any
Code
public function updatePassword() {
$passwordData = Input::except('_token');
$validation = Validator::make($passwordData, User::$passwordData);
if ($validation->passes()) {
array_forget($passwordData,'password_confirmation');
User::where(array(
'password' => Hash::make(Input::get('password'))
));
Session::flash('password', 'Perfil editado com sucesso');
return Redirect::to('backend/perfil/password');
} else {
return Redirect::to('backend/perfil/password')->withInput()->withErrors($validation);
}
}
user
public static $passwordData = array(
'password' => 'required|confirmed',
'password_confirmation' => 'required'
);
Follow this simple steps to get rid of anything
Step 1 : Get the password from the form
$PasswordData = Input::all();
Step 2 : Validate your password
Validator::extend('pwdvalidation', function($field, $value, $parameters) {
return Hash::check($value, Auth::user()->password);
});
Step 3 : Define the validation rule in your User Model
public static $rulespwd = array('OldPassword' => 'required|pwdvalidation',
'NewPassword' => 'required|confirmed|alphaNum|min:5|max:10',
'NewPassword_confirmation' => 'required',
);
Note : You shall define your own rule according to your need
Step 4 : If the rule is passed, then update else throw error messages to your view
$validator = Validator::make($PasswordData, User::$rulespwd, $messages);
if ($validator->passes()) {
$user = User::find(Auth::user()->id);
$user->password = Input::get('NewPassword');
$user->save();
return Redirect::to(Session::get('urlpath') . '/changepassword')->withInput()->with('Messages', 'The Password Information was Updated');
} else {
return Redirect::to(Session::get('urlpath') . '/changepassword')->withInput()->withErrors($validator);
}
I'm currently working on a project using the Phalcon Framework that has pages with complex forms and a lot of inputs, to break it down nicely I'm dividing the forms into a step-by-step process.
How would one validate the form on each step before going to the next step and then save the whole form on the final step?
I can't seem to find anything documented about this sort of process as it likes to validate the form in it's entirety if I use the form builder.
Simple, just create a custom methods in your form class to validate any step, and the posted data from some step save into message class and store it into session by "stepX", when posted data is not valid just set defaults from post. When valid save it into session as i describe above.
For example how i mean "controller"
<?php
class MyController extends BaseController {
public function processStep1Action(){
$form = new MyForm();
if($this->request->isPost()){//im using my custom request class
if(!$form->isValid($this->request->getPost()){
//error messages goes here
$form->setDefaultsFromRequest($this->request); // it will set the filled data
}
else {
$messageClass = new MyMessageContainer();
$messageClass->setData($this->request);//inside parse requested data into message class, or parse it as $messageClass->name = $this->request->getPost('name');
$this->session->save('step1',$messageClass); //maybe it would be want to serialize it
//then redirect to the step 2 or x
}
}
}
}
So in the next step you can access data from sessions $this->session->get('step1'); so you can in final step load all posted data and store it into DB.
I hope this helps! :)
here is my form maybe it can be helpful for you.
<?php
namespace Manager\Library\Forms\User;
use Phalcon\Forms\Form,
Phalcon\Forms\Element\Email,
Phalcon\Forms\Element\Select,
Phalcon\Forms\Element\Password,
Phalcon\Forms\Element\Check,
Phalcon\Validation\Validator\Confirmation,
Phalcon\Validation\Validator\StringLength,
Phalcon\Forms\Element\Submit,
Phalcon\Validation\Validator\PresenceOf,
Model\Group;
class AddUser extends Form {
public function initialize()
{
$email = new Email('email');
$email->addValidators(array(
new \Phalcon\Validation\Validator\Email(array(
'message' => 'Nezadali jste email nebo má nesprávny tvar(email#domena.tld).'
))
));
$this->add($email);
$this->initGroupElement();
$password = new Password('password');
$password
->addValidator(new StringLength(array('min' => 6,'messageMinimum' => 'Nezadali jste heslo nebo je příliš krátke, minimální počet znaků je 6.')))
->addValidator(new Confirmation(array('with' => 'password-again',"message" => "Zadané hesla se neshodují.")));
$this->add($password);
$repeatPassword = new Password('password-again');
$this->add($repeatPassword);
$this->initializeProfileElements();
$active = new Check('active',array('value' => 1));
$this->add($active);
$this->add( new Submit('save') );
\Phalcon\Tag::setDefault('password', '');
\Phalcon\Tag::setDefault('password-again', '');
}
public function initializeEdit(){
$email = new Email('email');
$email->addValidators(array(
new \Phalcon\Validation\Validator\Email(array(
'message' => 'Nezadali jste email nebo má nesprávny tvar(email#domena.tld).'
))
));
$this->add($email);
$this->initGroupElement();
$password = new Password('password');
$this->add($password);
$repeatPassword = new Password('password-again');
$this->add($repeatPassword);
$this->initializeProfileElements();
$active = new Check('active',array('value' => 1));
$this->add($active);
$this->add( new Submit('save') );
\Phalcon\Tag::setDefault('password', '');
\Phalcon\Tag::setDefault('password-again', '');
}
protected function initGroupElement(){
$auth = \Core\Auth::getIdentity();
$groups = new Group();
// $groups->addColumns(array('id','name'));
//set global condition about Super Admin
$groups->addFilter('id', 1,'<>');
if($auth){
//set restrictions for main groups
if((int)$auth->group_id === 1){ //super admingroup
//no filter
}
else if((int)$auth->group_id === 2){ //admin group
$groups->addFilter('id', 1,'>');
}
else if((int)$auth->group_id === 6){//Provozovatel group
$groups->addFilter('id',array(3,6,7));
$groups->addFilter('public', 1,'=',true);
}
else { // other groups
$groups->addFilter('public', 1);
}
}
$groups = $groups->findFiltered();
$groupElement = new Select('group');
foreach($groups as $group){
$groupElement->addOption(array($group->id => $group->name));
}
$this->add($groupElement);
}
protected function initializeProfileElements(){
$forename = new \Phalcon\Forms\Element\Text('forename');
$this->add($forename);
$surname = new \Phalcon\Forms\Element\Text('surname');
$this->add($surname);
$street = new \Phalcon\Forms\Element\Text('street');
$this->add($street);
$postal = new \Phalcon\Forms\Element\Text('postal');
$this->add($postal);
$city = new \Phalcon\Forms\Element\Text('city');
$this->add($city);
$ic = new \Phalcon\Forms\Element\Text('ic');
$this->add($ic);
$dic = new \Phalcon\Forms\Element\Text('dic');
$this->add($dic);
}
public function setDefault($fieldName,$value){
\Phalcon\Tag::setDefault($fieldName, $value);
}
public function setDefaults($object){
if($object instanceof \Model\User){
$this->setDefaultsFromObject($object);
}
else if($object instanceof \Phalcon\Http\Request){
$this->setDefaultsFromRequest($object);
}
}
protected function setDefaultsFromObject(\Model\User $user){
$profile = $user->getRelated('\Model\Profile');
\Phalcon\Tag::setDefaults(array(
'email' => $user->email,
'group' => $user->group_id,
'active' => $user->active,
'forename' => $profile->forename,
'surname' => $profile->surname,
'street' => $profile->street,
'city' => $profile->city,
'postal' => $profile->postal,
'ic' => $profile->IC,
'dic' => $profile->DIC
));
}
protected function setDefaultsFromRequest(\Phalcon\Http\Request $request){
\Phalcon\Tag::setDefaults(array(
'email' => $request->getPost('email'),
'group' => $request->getPost('group'),
'active' => $request->getPost('active')
));
\Phalcon\Tag::setDefaults(array(
'forename' => $request->getPost('forename'),
'surname' => $request->getPost('surname'),
'street' => $request->getPost('street'),
'city' => $request->getPost('city'),
'postal' => $request->getPost('postal'),
'ic' => $request->getPost('ic'),
'dic' => $request->getPost('dic')
));
}
}
In addition to Kamil's answer, another option to consider is to use Javascript on the front-end to handle your multi-step form. This will add some complexity as you will need to have the javascript to handle the form steps and do preliminary validation, but it only requires a single submit where you can validate content within a single method.
After reading the post: logging without password
I made a personal attempt:
AppController:
function beforeFilter(){
$this->Auth->loginError = "This message shows up when the wrong credentials are
used";
//$this->Auth->authError = "This error shows up with the user tries to access a part
of the website that is protected.";
//$this->Auth->authError = "";
$this->Auth->fields = array(
'username' => 'username',
'password' => null
);
UsersController, inside add():
// Save new user
if ($this->User->save(array('username' => $this->request->data['User']['username'],
'password' => $this->Auth->password(null),
'name' => $this->request->data['User']['name'],
'surname' => $this->request->data['User']['surname'],
'chosenLayout' => $this->request->data['User']['chosenLayout'],
'dateCreated' => $this->request->data['User']['dateCreated'],
'dateModified' => $this->request->data['User']['dateModified'],
'role_id' =>$this->request->data['User']['role_id']
))) {
$this->Session->setFlash(__('message_success_user_added',
array($this->request->data['User']['username'])), 'default', array(), 'success');
$this->redirect(array('action' => 'index'));
}
else {
// Validation error
$this->Session->setFlash(__('message_fail_validation'), 'default', array(), 'fail');
}
Then entered as admin and created some dummy users with null or random password.
Checking the database encrypted passwords were all the same ( a hashed null string) which means the modification in add() function worked...
Inside UsersController login():
// Login User
public function login() {
// Check if the user is already logged in
if ($this->Session->check('Auth.User.id')){
// Redirect to login page
$this->redirect($this->Auth->loginRedirect);
}
else{
// If the user is not logged in
session_set_cookie_params(0);
// If the request is a POST request
if ($this->request->is('post')) {
//get credentials
$this->username = $this->request->data['User']['username'];
$this->password = $this->request->data['User']['password'];
$this->domain = $this->request->data['User']['domain'];
//debug($this->username);
debug($this->domain) ;
//Check if username exists in local DB
//debug($this->User->findByUsername( $this->username ));
if ($this->Auth->login(
array(
'username'=> $this->username,
'password'=> null)
)){
// debug($this->Auth->login(array(
// 'username'=> $this->username,
// 'password'=> null
// )));
// Successful login
// Get all the user information and store in Session
//debug($this->Auth);
$this->User->id = $this->Auth->user('id');
debug($this->User->id);
debug($this->User);
$this->User->contain(array('User', 'Role' => array('Ui', 'Action.name')));
$this->Session->write('User', $this->User->read());
$actions = array();
foreach ($this->Session->read('User.Role.Action') as $key => $value){
array_push($actions, $value['name']);
}
$this->Session->write('User.Role.Action', $actions);
debug($actions);
// Render different layout depending on user type
if($this->Session->read('User.Role.Ui.name') == Configure::read('usertype.msp')){
$this->Session->write('SessionValues.ui', Configure::read('usertype.msp'));
$this->Auth->loginRedirect = array('controller' => 'PortStats', 'action' =>
'index');
}
else if($this->Session->read('User.Role.Ui.name') ==
Configure::read('usertype.tsc')){
$this->Session->write('SessionValues.ui', Configure::read('usertype.tsc'));
$this->Auth->loginRedirect = array('controller' => 'PortStats', 'action' =>
'index');
}
else if($this->Session->read('User.Role.Ui.name') ==
Configure::read('usertype.superAdminUserType')){
$this->Auth->loginRedirect = array('controller' => 'Uis', 'action' => 'index');
}
// Redirect to main login page
$this->redirect($this->Auth->loginRedirect);
}
else {
// Failed login user
session_destroy();
$this->Session->setFlash(__('Login failed:
access not granted'), 'default', array(), 'fail');
}
}
}
}
Then I try to login with my new users.I get the failed login message.
Which means $this->Auth->login returns false.
It must be as easy as that but something is going wrong.
In the meantime my debug trace:
Warning (2): Invalid argument supplied for foreach()
[APP\Controller\UsersController.php, line 85]
Simplify it. It is not a login, but a registration process, so don't confuse those two totally different things.
You just
create the user including proper validation
on success use Auth->login($user['User']) to set the auth session manually
only then redirect manually to where you want the user to go after a registration here
For a live example see https://github.com/dereuromark/cakefest/blob/master/Controller/AccountController.php#L166
In laravel, when a new user is registering to my site and the email they use already exist in the database. how can tell the user that the email already exist ?. I am new to laravel framework. A sample code would be nice too.
The validation feature built into Laravel lets you check lots of things, including if a value already exists in the database. Here's an overly simplified version of what you need. In reality you'd probably want to redirect back to the view with the form and show some error messages.
// Get the value from the form
$input['email'] = Input::get('email');
// Must not already exist in the `email` column of `users` table
$rules = array('email' => 'unique:users,email');
$validator = Validator::make($input, $rules);
if ($validator->fails()) {
echo 'That email address is already registered. You sure you don\'t have an account?';
}
else {
// Register the new user or whatever.
}
);
Laravel has built-in human readable error messages for all its validation. You can get an array of the these messages via: $validator->messages();
You can learn more about validation and what all you can do with it in the Laravel Docs.
Basic Usage Of Unique Rule
'email' => 'unique:users'
Specifying A Custom Column Name
'email' => 'unique:users,email_address'
Forcing A Unique Rule To Ignore A Given ID
'email' => 'unique:users,email_address,10'
Adding Additional Where Clauses
You may also specify more conditions that will be added as "where" clauses to the query:
'email' => 'unique:users,email_address,NULL,id,account_id,1'
The above is from the documentation of Laravel
You could add:
public static $rules = [
'email' => 'unique:users,email'
];
You can add more rules to the $rules like:
public static $rules = [
'email' => 'required|unique:users,email'
];
It will automatically produce the error messages
and add:
public static function isValid($data)
{
$validation = Validator::make($data, static::$rules);
if ($validation->passes())
{
return true;
}
static::$errors = $validation->messages();
return false;
}
to the model User.php
Then in the function you're using to register, you could add:
if ( ! User::isValid(Input::all()))
{
return Redirect::back()->withInput()->withErrors(User::$errors);
}
if(sizeof(Users::where('email','=',Input::get('email'))->get()) > 0) return 'Error : User email exists';
The great resource is only Laravel Documentation #
enter link description here
I also did like below when integrating user management system
$user = Input::get('username');
$email = Input::get('email');
$validator = Validator::make(
array(
'username' => $user,
'email' => $email
),
array(
'username' => 'required',
'email' => 'required|email|unique:users'
)
);
if ($validator->fails())
{
// The given data did not pass validation
echo 'invalid credentials;';
// we can also return same page and then displaying in Bootstap Warning Well
}
else {
// Register the new user or whatever.
$user = new User;
$user->email = Input::get('email');
$user->username = Input::get('username');
$user->password = Hash::make(Input::get('password'));
$user->save();
$theEmail = Input::get('email');
// passing data to thanks view
return View::make('thanks')->With('displayEmail', $theEmail);
}
public function userSignup(Request $request, User $data){
# check user if match with database user
$users = User::where('email', $request->email)->get();
# check if email is more than 1
if(sizeof($users) > 0){
# tell user not to duplicate same email
$msg = 'This user already signed up !';
Session::flash('userExistError', $msg);
return back();
}
// create new files
$data = new User;
$data->name = $request->name;
$data->email = $request->email;
$data->password = md5($request->password);
$data->save();
//return back
Session::flash('status', 'Thanks, you have successfully signup');
Session::flash('name', $request->name);
# after every logic redirect back
return back();
}
I think when u try something like this you earn a smooth check using Model
We can use the Validator.
In your Controller.
$validator = $request->validate([
'name' => 'required',
'phone' => 'required',
'email' => 'required|email|unique:users',
'password' => 'required',
]);
In View
#error('email') <span class="text-danger error">{{ $message }}</span>#enderror
$this->validate($request, [
'fname' => 'required',
'lname' => 'required',
'email' => 'required|min:4|email|unique:users',
'password' => 'required',
]);
Try This