Yii not allowing to insert same data - php

I'm using yii framework. I have made a condition where users are not allowed to insert a same data.
here is my code
model
public function rules()
{
// NOTE: you should only define rules for those attributes that
// will receive user inputs.
return array(
array('DEP_CD', 'length', 'max'=>5),
array('DEP_CD', 'required'),
array('DEP_CD', 'cekPK'),
);
}
public function cekPK()
{
$model = self::findByPk(array($this->DEP_CD));
if ($model)
$this->addError('field1', 'Data sudah ada');
}
this code works for not allowing user to insert a same data. but when they edit/update the data, it keep saying that data is exist. I need to make users allowed to edit but not inserting the same data only
thanks

A work around could be:
public function cekPK()
{
if ($this->isNewRecord)
{
$model = self::findByPk(array($this->DEP_CD));
if ($model)
$this->addError('field1', 'Data sudah ada');
}
}

Related

Laravel 5.5 Check User exist with three param in two tables

I develop the register module , i want to check users registered in my web app with email , nationalCode or mobile , i have two tables , users and userInfo , i store email in users table and i store nationalCode and mobile in userInfo table , i want to write code to detect if email or nationalCode or mobile of the user exist in my two tables , i show warning text that user have registered in my site, please help me to do this job,
I use step form and i write ajax to call method to do this task,
note that it may be possible teh user have three matches or just one of them is matched
thanks for your helps :)
Here is the ajax code :
$.ajax({
url: url',
type: 'POST',
data: {
_token: CSRF_TOKEN ,
code:code,
email:email,
mobile:mobile,
},
dataType: 'JSON',
success:function(data) {
//return data
}
});
and here is my method is controller
public function checkUser(Request $request)
{
$email = $request->email;
$mobile = $request->mobile;
$code = $request->code;
//here the query to detect user exist with three params
}
Let's say you have your relationships defined as follows:
class User extends Model
{
public function info()
{
return $this->hasOne(UserInfo::class);
}
}
class UserInfo extends Model
{
public function user()
{
return $this->belongsTo(User::class);
}
}
... then you can check the existence of this user with something like this.
$user = User::where('email', $request->email)
->whereHas('info', function($query) use($request) {
$query->where('mobile', $request->mobile)
->where('code', $request->code);
})
->exists();
// user will be false if there's no record matching those parameters
Alternatively, if you don't have your relationships defined, then you probably need to do something like this instead.
$user = User::where('email', $request->email)->exists();
$info = UserInfo::where([
'mobile' => $request->mobile,
'code' => $request->code
])->exists();
if($user && $info) {
// user exists
}
I would still prefer to go with option one :)
If you put unique identifier in you table, database will automatically detect it and return the error, but its not good practice to let database to handle that,
If you want to use Eloquent then the query would look like this
public function checkUser(Request $request)
{
$email = $request->email;
$mobile = $request->mobile;
$code = $request->code;
$user = User::query()->where('email', '=', $email)->orWhere('mobile','=',$mobile)
->orWhere('code', '=',$code)->get();
if($user) {
// User already exits
return;
}
}
But this validation for me is not good, Better is to use Laravel Requests
https://laravel.com/docs/5.7/validation#form-request-validation
To generate custom request use this command (php artisan make:request RequestName)
public function rules()
{
return [
'title' => 'required|unique:users',
'mobile' => 'required|unique:users',
'code' => 'required|unique:users',
];
}
Using the request is simple
public function checkUser(YourCustomRequest $request)
{
// Laravel will take care of all fields and check them if they exist in the database
}

Hash password before saving with Laravel Backpacker

A simple question: how do I modify (hash) the request value before saving it with Laravel Backpacker CRUD admin?
As far as i understand, it should be done somewhere before these methods are executed in the crud controller:
public function store(StoreRequest $request)
{
return parent::storeCrud();
}
public function update(UpdateRequest $request)
{
return parent::updateCrud();
}
but I have no idea how to do it correctly.
Edit: the request is not a Request object, but rather StoreRequest or UpdateRequest that looks something like this:
Fix:
public function update(UpdateRequest $request)
{
// Hash password before save
if (!empty($request->password)) {
$request->offsetSet('password', Hash::make($request->password));
}
return parent::updateCrud($request); // <-- Pass the modified request, otherwise the CRUD reads it again from post data
}
You can update $request values using the offsetSet method
$request->offsetSet('name', $newName);
Edit: To update user password you can do something like this:
public function update_password(Request $request)
{
$user = User::find(Auth::user()->id);
if (Hash::check($request->old_password, $user->password)) {
$user->fill([
'password' => Hash::make($request->password)
])->update();
return redirect()->back()->with('message' => 'Your password has been updated.');
}
else {
return redirect()->back()->with('message' => 'The password entered do not match our records.');
}
}
I did not check the code but it should work. Now update it to your needs.
If you're asking about how to modify data in $request variable, you can just do this:
$request->property = 'New value';
Also, you can add data to reuqest itself (not into variable):
request()->request->add(['key' => 'value']);

how to get back to own profile after searching for an invalid username in the URL

I am new to laravel.I have a controller called userController to mangae user in my application.Here i have a user authentication and profile system.It will send the user to its own profile after login.Sometimes user may wish to search for a random username or id field in the url to search for a user.If desired user is found ,their profile info will be shown in the profile section.But if no user is found i want my application to get the current logged in user and show his/her info instead.How i can do that?
if my user name is 'zim' i can write the url mydomain/user/zim ,it will get my profile,But if i search an invalid name say 'zi' mydomain/user/zi , i want my application to return mydomain/user/zim again
All i can manage here is to show a flash message if no user is found.Can't figure out how to retrieve the current logged user.Tried to use the Request class but seems not working
loginUser function():
public function loginUser(Request $request){
$data = $request->all();
$rules = array(
'name' => 'required',
'password'=>'required'
);
// Create a new validator instance.
$validator = Validator::make($data, $rules);
if($validator->fails()){
$errors=$validator->messages();
return redirect()->back()->withErrors($validator);
}else{
if(Auth::attempt(['name'=>$request['name'],'password'=>$request['password']])){
return redirect()->route('user.show',[$request['name']]);
}else{
return redirect()->back()->with('data', 'wrong username or password');
}
}
}
show() method in userController:
public function show($user,Request $request) // tried with Request but failed
{
//
$indicator=is_numeric($user)?'id':'name';
$info=userModel::where($indicator,'=',$user)->get()->first();
if($info){
return View::make('user.show')->with('user',$info);
}else{
session()->flash('message','no user');
return View::make('user.show');
}
}
You just need to change your show method slightly.
public function show($user,Request $request)
{
$indicator=is_numeric($user)?'id':'name';
$info=userModel::where($indicator,'=',$user)->get()->first();
if(empty($info)){
return View::make('user.show')->with('user',$info);
}else{
session()->flash('message','no user but here is your info :)');
return View::make('user.show')->with('user', Auth::user());
}
}
Edited for better logic.
public function show($username)
{
$info = userModel::where(username, $username)->get()->first();
if($info != null){
return View::make('user.show')->with('user', $info);
}
else{
session()->flash('message','No user found! But here is your info!');
return View::make('user.show')->with('user',Auth::user());
}
}
Here is a much simplified option. (Always allow the URL to collect only one type instead of checking if its id or username)

Unique email values from a Yii 1.1 dynamic form

I have a Yii form accept first name, last name and email from user. Using an add more link, users can add multiple rows of those three elements.
For email validation, unique and required are set in model rules and everything works fine. I am using JavaScript to create addition row on clicking add more link.
Problem
On the first row my values are John, Newman, johnnewman#gmail.com and the second row, i'm entering Mathew, Heyden, johnnewman#gmail.com. In this case email address is duplicated. None of the validation rules (require and unique) is capable of validating this. Can some one suggest a better method to validate this ?
Update:
I created a custom validation function and i guess this is enough to solve my problem. Can someone tell me how to access the whole form data / post data in a custom validation function ?
public function uniqueOnForm($attribute){
// This post data is not working
error_log($_REQUEST, true);
$this->addError($attribute, 'Sorry, email address shouldn\'t be repeated');
}
You can try this:
<?php
public function rules()
{
return array(
array('first_name', 'checkUser')
);
}
public function checkUser($attribute)
{
if($this->first_name == $this->other_first_name){
$this->addError($attribute, 'Please select another first name');
}
}
?>
You can also look into this extension
You can write custom validator:
//protected/extensions/validators
class UniqueMailValidator extends CValidator
{
/**
* #inheritdoc
*/
protected function validateAttribute($object, $attribute)
{
$record = YourModel::model()->findAllByAttributes(array('email' => $object->$attribute));
if ($record) {
$object->addError($attribute, 'Email are exists in db.');
}
}
}
// in your model
public function rules()
{
return array(
array('email', 'ext.validators.UniqueMailValidator'),
...
Or better try to use THIS
public function rules(){
return array(
//other rules
array('email', 'validEmail'),
)
}
public function validEmail($attribute, $params){
if(!empty($this->email) && is_array($this->email)){
$isduplicate = $this->isDuplicate($this->email);
if($isduplicate){
$this->addError('email', 'Email address must be unique!');
}
}
}
private function isDuplicate($arr){
if(count(array_unique($arr)) < count($arr)){
return true;
}
else {
return false;
}
}
because you are using tabular input (multiple row) , so make sure input field as an array. might be like this :
<?php echo $form->textField($model, 'email[]'); ?>

Yii custom validation rule not called on validate()

When a user registers for my application the following validation rules are called before submission:
public function rules()
{
return array(
array('email, firstName, lastName, password, passwordConfirm, telephone', 'required'),
array('club, email, firstName, lastName, level, password, telephone', 'length', 'max'=>45),
array('passwordConfirm', 'compare', 'compareAttribute'=>'password', 'on'=>'register'),
array('email', 'isUniqueEmailAddress'),
);
}
The first three validation rules complete successfully, but the fourth (a custom validation method) does not. It should call the function 'isUniqueEmailAddress' and perform the following:
/*
* Returns true if there doesn't exist a user in the database with the submitted email
*/
public function isUniqueEmailAddress($attribute, $params)
{
//if (User::model()->find('email=:email', array(':email'=>$this->email)) !== null)
//{
$this->addError('email', 'Email account already exists');
//}
}
As you can see, I've even commented out all logic to simply ensure that a validation error is sent back to the registration form, but no errors are returned on validation(). I've read Yii's Documentation and scoured the forums but cannot understand why my custom validation method is not being called?
I ran into this problem when attempting to set a flash message in a controller after calling $model->save(). It was a code formatting issue which caused a logic error.
For example, in the model I had something like this:
public function validateNumItems($attribute, $params) {
$this->addError($attribute, 'Validate Items Failed');
}
In theory this should have caused the form submission to fail every time for debugging purposes. But it never did.
My controller's update action looked like this:
public function actionUpdate($id) {
$model = $this->loadModel($id);
// Uncomment the following line if AJAX validation is needed
// $this->performAjaxValidation($model);
if (isset($_POST['Collection']))
{
$model->attributes = $_POST['Collection'];
if ($model->save())
Yii::app()->user->setFlash('success', "Data saved!");
$this->redirect(array('index'));
}
$this->render('update', array('model' => $model, ));
}
The missing brackets around the $model->save() test created by Gii caused a logic error when I added new lines. Putting the brackets in place fixed things.
public function actionUpdate($id) {
$model = $this->loadModel($id);
// Uncomment the following line if AJAX validation is needed
// $this->performAjaxValidation($model);
if (isset($_POST['Collection'])) {
$model->attributes = $_POST['Collection'];
if ($model->save()) {
Yii::app()->user->setFlash('success', "Data saved!");
$this->redirect(array('index'));
}
}
$this->render('update', array('model' => $model, ));
}
array('email', 'exist')
like this.
public function rules()
{
return array(
array('email, firstName, lastName, password, passwordConfirm, telephone', 'required'),
array('club, email, firstName, lastName, level, password, telephone', 'length', 'max'=>45),
array('passwordConfirm', 'compare', 'compareAttribute'=>'password', 'on'=>'register'),
array('email', 'exist')
);
}
I commented with some possible reasons your code isn't working (it looks right), but in this case you can just use the Unique validator.
array('email', 'unique') will do it.
try this, it's working fine -
public function rules()
{
return array(
array('email, firstName, lastName, password, passwordConfirm, telephone', 'required'),
array('email', 'email','message'=>"The email isn't correct"),
array('email', 'uniqueEmail'),
);
}
your custom function, write into same model -
public function uniqueEmail($attribute, $params)
{
if($user = User::model()->exists('email=:email',array(':email'=>$this->email)))
$this->addError($attribute, 'Email already exists!');
}

Categories