I am trying to check if a book is already in the db to avoid duplication. The code below is popping up for both existing and the one not in the database.
public function actionCreate($book_id = 'book_id')
{
$checkmodel = Books::find()->where(['book_id' => $book_id])->one();
if ($checkmodel) {
Yii::$app->session->setFlash('error', 'The book has been borrowed, Please look for another one.');
return $this->redirect(Yii::$app->request->referrer);
}
$model = new Books();
if ($model->load(Yii::$app->request->post()) && $checkmodel->save()) {
Yii::$app->session->setFlash('Success','You have successfully borrowed the book');
return $this->redirect(['view' => 'book_id', $model->book_id]);
}
return $this->render('create', [
'model' => $model,
]);
}
You could avoid the check adding a proper validation rule in you model
anyway for your code you shou,d try checking for not null $checkmodel
if (!is_null($checkmodel) {
Yii::$app->session->setFlash('error', 'The book has been borrowed, Please look for another one.');
return $this->redirect(Yii::$app->request->referrer);
}
https://www.yiiframework.com/doc/api/2.0/yii-validators-uniquevalidator
https://www.yiiframework.com/doc/guide/2.0/en/input-validation
public function actionCreate($book_id = 'book_id')
{
$model = new Books();
// check if post request
if ( $model->load(Yii::$app->request->post()) ) {
// check if book_id exists in table
if ( ! Books::find()->where(['book_id' => $book_id])->one() ) {
// save new record to model
if ( ! $model->save() ) {
// set error message and redirect to 'create' page
Yii::$app->session->setFlash('Error','There was some error in processing your request');
return $this->redirect(Yii::$app->request->referrer);
}
// if model is saved successfully, redirect to 'view' page
Yii::$app->session->setFlash('Success','You have successfully borrowed the book');
return $this->redirect(['view', 'book_id' => $model->book_id]);
} else {
// if book_id exist in table, show error message
Yii::$app->session->setFlash('error', 'The book has been borrowed, Please look for another one.');
return $this->redirect(Yii::$app->request->referrer);
}
}
return $this->render('create', [
'model' => $model,
]);
}
It's always better to check "false" condition in if statements than true. Helps us write cleaner code.
Also there was a syntax error in your redirect to view statement
Related
why did I get this bad request (#400) error after submitting my update on my 'news' section :
Missing required parameters: id
This is my update function
php
public function actionUpdate($id)
{
$model = $this->findModel($id);
$oldFile = $model->getImageFile();
$currentImage=$model->image;
if ($model->load(Yii::$app->request->post())) {
// process uploaded image file instance
$image = $model->uploadImage();
// revert back if no valid file instance uploaded
if ($image === false) {
$model->image = $currentImage;
}
if ($model->save()) {
// upload only if valid uploaded file instance found
if ($image !== false && unlink($oldFile)) { // delete old and overwrite
$path = $model->getImageFile();
$image->saveAs($path);
}
return $this->redirect(['view', ['id'=>$model->id,'image'=>$model->image],
]);
}
} else {
return $this->render('update', [
'model'=>$model,
]);
}
}
public function actionView($id)
{
return $this->render('view', [
'model' => $this->findModel($id),
]);
}
Please note that the updating and uploading image process were actually a success (that's why I didn't show my model's method code that my actionUpdate called). If I go directly to view the recently updated page and view the content, it clearly displays the updated contents along with the image without problem. The error only occurs just right after the update is submitted. I thought I had pass the parameter after the update by this line :
return $this->redirect(['view', ['id'=>$model->id,'image'=>$model->image],
Right before that line I even echo $model->id to test and it echoed out the id.
I've looked for similar problem in StackOverflow and find someone suggested this :
php
if($model->save())
{
$lastInsertID = $model->getPrimaryKey();
return $this->redirect(['view', 'id' => $lastInsertID]);
}
But it didn't work. Any idea?
You should pass URL as flat array:
return $this->redirect(['view', 'id' => $model->id,'image' => $model->image]);
I have two separate APIs calls. One for click on edit page and another for update page:
The controller method when the user hits edit link:
public function EditList($page_id)
{
$listEdit= DB::table('page_master')->where('id',$page_id)->first();
return view('edit-list',compact('listEdit'));
}
and its route:
$router->get('/edit-List/{id}', 'AjaxController#EditList');
The above code successfully shows me the edit page where I will perform the update.
My next step is update record:
The controller method
public function updatePage($id)
{
$updatePage = $this->page->updatePage($id);
if(!$updatePage)
{
$resultArray = ['status' => 0, 'message' => 'Page not exist!'];
return Response::json( $resultArray, 400);
}
else{
$resultArray = ['status' => 1, 'message' => 'Page updated !'];
return Response::json($resultArray, 200);
}
}
and its routes:
Route::post('update/list/{id}',['uses' => 'ApiController#updatePage']);
Now when i click on update record it shows me the page does not exist even though the page is there in database but always showing the page does not exist page.
What should I change to make the routes work properly?
public function updatePage($id)
{
$updatePage = self::find($id);
if (is_null($updatePage)) {
return false;
}
$input = Input::all();
$updatePage->fill($input);
$updatePage->save();
return $updatePage;
}
My Controller:
public function actionCreate()
{
$model = new SuratMasuk(['scenario' => 'create']);
if ($model->load(Yii::$app->request->post()))
{
try
{
$picture = UploadedFile::getInstance($model, 'imageFile');
$model->imageFile = $_POST['SuratMasuk']['id_suratmasuk'].'.'.$picture->extension;
if($model->save())
{
$picture->saveAs('uploads/' . $model->id_suratmasuk.'.'.$picture->extension);
Yii::$app->getSession()->setFlash('success','Data saved!');
return $this->redirect(['view','id'=>$model->id_suratmasuk]);
}
else
{
Yii::$app->getSession()->setFlash('error','Data not saved!');
return $this->render('create', [
'model' => $model,
]);
}
}
catch(Exception $e)
{
Yii::$app->getSession()->setFlash('error',"{$e->getMessage()}");
}
}
else
{
return $this->render('create', [
'model' => $model,
]);
}
}
getting this error message when i try to save my post. and it just uploads the text not images. i've tried $model->save(false); but not working
i'm newbie on yii, i'll appreciate your help
I guess this is because you try to pass id here:
return $this->redirect(['view', 'id' => $model->id_suratmasuk]);
and since actionView almost for sure requires id as parameter you get this error because $model->id_suratmasuk is empty.
You need to set proper rules() in SuratMasuk model.
Do not use POST variables directly, this is asking for being hacked.
Do not use save(false) if you need to save anything that comes from user (validation is a must!).
Add rules() for all attributes so there will be no surprises like with this id_suratmasuk being empty.
Check result of saveAs() on UploadedFile instance - this can go false as well.
I'm completely lost as to why this is happening, and it happens about 50% of the time.
I have a check to see if a user exists by email and last name, and if they do, run some code. If the user doesn't exist, then create the user, and then run some code.
I've done various testing with dummy data, and even if a user doesn't exist, it first creates them, but then runs the code in the "if" block.
Here's what I have.
if (User::existsByEmailAndLastName($params->email, $params->lastName)) {
var_dump('user already exists');
} else {
User::createNew($params);
var_dump("Creating a new user...");
}
And here are the respective methods:
public static function existsByEmailAndLastName($email, $lastName) {
return User::find()->where([
'email' => $email,
])->andWhere([
'last_name' => $lastName
])->one();
}
public static function createNew($params) {
$user = new User;
$user->first_name = $params->firstName;
$user->last_name = $params->lastName;
$user->email = $params->email;
$user->address = $params->address;
$user->address_2 = $params->address_2;
$user->city = $params->city;
$user->province = $params->province;
$user->country = $params->country;
$user->phone = $params->phone;
$user->postal_code = $params->postal_code;
return $user->insert();
}
I've tried flushing the cache. I've tried it with raw SQL queries using Yii::$app->db->createCommand(), but nothing seems to be working. I'm totally stumped.
Does anyone know why it would first create the user, and then do the check in the if statement?
Editing with controller code:
public function actionComplete()
{
if (Yii::$app->basket->isEmpty()) {
return $this->redirect('basket', 302);
}
$guest = Yii::$app->request->get('guest');
$params = new CompletePaymentForm;
$post = Yii::$app->request->post();
if ($this->userInfo || $guest) {
if ($params->load($post) && $params->validate()) {
if (!User::isEmailValid($params->email)) {
throw new UserException('Please provide a valid email.');
}
if (!User::existsByEmailAndLastName($params->email, $params->lastName)) {
User::createNew($params);
echo "creating new user";
} else {
echo "user already exists";
}
}
return $this->render('complete', [
'model' => $completeDonationForm
]);
}
return $this->render('complete-login-or-guest');
}
Here's the answer after multiple tries:
Passing an 'ajaxParam' parameters with the ActiveForm widget to define the name of the GET parameter that will be sent if the request is an ajax request. I named my parameter "ajax".
Here's what the beginning of the ActiveForm looks like:
$form = ActiveForm::begin([
'id' => 'complete-form',
'ajaxParam' => 'ajax'
])
And then I added this check in my controller:
if (Yii::$app->request->get('ajax') || Yii::$app->request->isAjax) {
return false;
}
It was an ajax issue, so thanks a bunch to Yupik for pointing me towards it (accepting his answer since it lead me here).
You can put validation like below in your model:
public function rules() { return [ [['email'], 'functionName'], [['lastname'], 'functionforlastName'], ];}
public function functionName($attribute, $params) {
$usercheck=User::find()->where(['email' => $email])->one();
if($usercheck)
{
$this->addError($attribute, 'Email already exists!');
}
}
and create/apply same function for lastname.
put in form fields email and lastname => ['enableAjaxValidation' => true]
In Create function in controller
use yii\web\Response;
if (Yii::$app->request->isAjax && $model->load(Yii::$app->request->post())) {
Yii::$app->response->format = Response::FORMAT_JSON;
return ActiveForm::validate($model);
}
else if ($model->load(Yii::$app->request->post()))
{
//place your code here
}
Add 'enableAjaxValidation' => false to your ActiveForm params in view. It happens because yii sends request to your action to validate this model, but it's not handled before your if statement.
I'd like some help please. I have a post page that has the full post and below the post a small form for adding comments. The uri of the post page is: site/posts/1, so it is in posts controller, and the form action is form_open(site_url('comments/add/'.$post->post_id)).
This is my add() function inside comments controller:
public function add($post_id){
// if nothing posted redirect
if (!$this->input->post()) {
redirect(site_url());
}
// TODO: save comment in database
$result = $this->comment_model->add($post_id);
if ($result !== false) {
redirect('posts/'.$post_id);
}
// TODO:load the view if required
}
and this is the add() function inside the comment model
public function add($post_id){
$post_data = array(
'post_id' => $post_id,
'username' => $this->input->post('username'),
'email' => $this->input->post('email'),
'comment' => $this->input->post('comment')
);
if ($this->validate($post_data)) {
$this->db->insert('comments', $post_data);
if ($this->db->affected_rows()) {
return $this->db->insert_id();
}
return false;
} else {
return false;
}
}
What I'm trying to do is if the $result = $this->comment_model->add($post_id); fails the validation to display the validation errors in my post view, else insert the comment and redirect to the same post page (site/posts/1).
The problem is that when I hit submit the form action goes in the comments/add/1, as expected, but doesn't do any these above.
Any ideas how can I fix this??
EDIT
I did a small change to the code without the 'confusing' validate() function. Maybe this is more helpful.
Comment controller:
public function add($post_id){
// if nothing posted redirect
if (!$this->input->post()) {
redirect(site_url());
}
// TODO: save comment in database
$this->form_validation->set_rules($this->comment_model->rules);
if ($this->form_validation->run() == true) {
echo "Ok! TODO save the comment.";
// $this->comment_model->add($post_id);
// redirect('posts/'.$post_id);
} else {
echo "Validation Failed! TODO: show validation errors!";
}
// TODO:load the view if required
}
Comment model:
public function add($post_id){
$post_data = array(
'post_id' => $post_id,
'username' => $this->input->post('username'),
'email' => $this->input->post('email'),
'comment' => $this->input->post('comment')
);
$this->db->insert('comments', $post_data);
if ($this->db->affected_rows()) {
return $this->db->insert_id();
}
return false;
}
You need away of passing validation_errors() back to your Posts controller. At the minute, when you perform the redirect in your add function (when the validation fails), you loose the validation errors thrown.
I would consider using flashdata (http://ellislab.com/codeigniter/user-guide/libraries/sessions.html) to pass a success/error message from your Comments controller back to your Posts controller. Something similar to the below:
Comments Controller:
public function add($post_id) {
// if nothing posted redirect
if (!$this->input->post()) {
redirect(site_url());
}
// TODO: save comment in database
$this->form_validation->set_rules($this->comment_model->rules);
if ($this->form_validation->run() == true) {
// Store the success message in flash data
$this->session->set_flashdata('message', 'Ok! TODO save the comment.');
// Redirect back to posts page
redirect('posts/'.$post_id, 'refresh');
} else {
// Store the error message in flash data
$this->session->set_flashdata('message', validation_errors());
// Redirect back to posts page
redirect('posts/'.$post_id, 'refresh');
}
}
Posts Controller:
public function index($post_id) {
$this->data['message'] = $this->session->flashdata('message');
$this->load->view('posts', $this->data);
}
Posts View:
echo $message;
Might not be perfect but hope it helps...