Yii2 - Bad Request (#400) - Missing required parameters: id - php

CommentController:
public function actionCreate()
{
$model = new Comment();
var_dump(Yii::$app->request->post());
if ($model->load(Yii::$app->request->post()))
{
$model->user_id = Yii::$app->user->getId();
$model->created_at = time();
$model->updated_at = time();
$model->save();
return $this->redirect(Url::to(['post/view', 'id'=>$model->post_id]));
}
return $this->redirect(Url::to(['/post/index']));
}
If I pass as false to $model->save() the data gets stored in the database with no value in the foreign key field 'post_id' but still doesn't redirect me to the correct page.
New to yii and relatively new to software development, any help would be massively appreciated.

It redirects you to post/view - means PostController - actionView($id), but without param $id, which is required in actionView($id). That's why you get 400 missing param error. You have to add this param - for now if you add false to save() method and it is saved without post_id - you can't redirect user to post/view because you didn't passed id of this object in GET
To avoid such things you should check if $model is really saved by if($model->save()) and if, redirect user to view.

you need to do like below in your controller.If id exist this will keep the id value otherwise it defines and keep it as empty.
public function actionView($id='') {
//
}

Related

Copy one row from one table to another

I need a little help and I can’t find an answer. I would like to replicate a row from one data table to another. My code is:
public function getClone($id) {
$item = Post::find($id);
$clone = $item->replicate();
unset($clone['name'],$clone['price']);
$data = json_decode($clone, true);
Order::create($data);
$orders = Order::orderBy('price', 'asc')->paginate(5);
return redirect ('/orders')->with('success', 'Success');
}
and i got an error :
"Missing argument 1 for
App\Http\Controllers\OrdersController::getClone()"
.
I have two models: Post and Order. After trying to walk around and write something like this:
public function getClone(Post $id) {
...
}
I got another error
Method replicate does not exist.
Where‘s my mistake? What wrong have i done? Maybe i should use another function? Do i need any additional file or code snippet used for json_decode ?
First of all, make sure your controller gets the $id parameter - you can read more about how routing works in Laravel here: https://laravel.com/docs/5.4/routing
Route::get('getClone/{id}','YourController#getClone');
Then, call the URL that contains the ID, e.g.:
localhost:8000/getClone/5
If you want to create an Order object based on a Post object, the following code will do the trick:
public function getClone($id) {
// find post with given ID
$post = Post::findOrFail($id);
// get all Post attributes
$data = $post->attributesToArray();
// remove name and price attributes
$data = array_except($data, ['name', 'price']);
// create new Order based on Post's data
$order = Order::create($data);
return redirect ('/orders')->with('success', 'Success');
}
By writing
public function getClone(Post $id)
you are telling the script that this function needs a variable $id from class Post, so you can rewrite this code like this :
public function getClone(){
$id = new Post;
}
However, in your case this does not make any sence, because you need and integer, from which you can find the required model.
To make things correct, you should look at your routes, because the url that executes this function is not correct, for example, if you have defined a route like this :
Route::get('getClone/{id}','YourController#getClone');
then the Url you are looking for is something like this :
localhost:8000/getClone/5
So that "5" is the actual ID of the post, and if its correct, then Post::find($id) will return the post and you will be able to replicate it, if not, it will return null and you will not be able to do so.
$item = Post::find($id);
if(!$item){
abort(404)
}
Using this will make a 404 page not found error, meaning that the ID is incorrect.

Models load() usage

Can someone enligthen me ,what is the real usage of load method if setting post params can be directly set to models attributes? Thanks
$model->load(Yii::$app->request->post());
vs
$model->attributes = Yii::$app->request->post();
As you can easy see in http://www.yiiframework.com/doc-2.0/yii-base-model.html#load()-detail
load Populates the model with input data. load() gets the 'FormName'
from the model's formName() method (which you may override), unless
the $formName parameter is given.
the data being populated is subject to the safety check by setAttributes().
see also http://www.yiiframework.com/doc-2.0/guide-structure-models.html
The main purpose of load($data, $formName) is to return boolean true if the expected $formName is found in $data. Thus, you can bypass the following:
if (isset($_POST['FormName'])) {
$model->attributes = $_POST['FormName'];
do_something_here;
}
with
$post = Yii::$app->request->post();
if ($model->load($post)) {
do_something_here;
}
It's interesting for more, different kind of models:
$post = Yii::$app->request->post();
if ($modelA->load($post) && $modelB->load($post) && $modelC->load($post)) {
do_something_if_all_models_are_loaded;
}
load() will only assign attributes that have got validation rules assigned to them in current scenario so you are able to verify them.
not sure if you have gone through this or not .. .but it's pretty much clear here : www.yiiframework.com/doc-2.0/yii-base-model.html#load()-detail

How do I get current action parameter?

I'm using a yii\filters\PageCache filter for my action and I want to define a cache dependency based on action parameter.
E.g. I want to use yii\caching\DbDependency to select updated_at column of the row with id from the request. How can I reference the id parameter of the action?
Yii::$app->request->get('id');
If you want to add dependency in your cache then try this
$db = Yii::$app->db; // or Category::getDb()
$dep = new DbDependency();
$dep->sql = 'SELECT max(update_at) FROM table';
$model = $db->cache(function ($db) {
return model::find()->asArray()->orderBy('id ASC')->all();
},expirytime, $dep);
The code will check your data in cache if it exist will load from cache otherwise create it and cached it.it will also check your update_at filed if its value is changed then it will update your cache,you don't need to worry about that
and if you want to access current action in yii then try this code
Yii::$app->controller->id; //will return current controller//
Yii::$app->controller->action->id; //will return current action//
Yii::$app->controller->module->id; //will return current module//
i hope this will help you

Yii deleteAll() records with condition

I've set up a log in process where a verification code is generated, and when successful, is then removed. However, i want to make sure that if there's multiple verification codes for the same user, upon log in success, delete all records for that user.
Here's my code
if ($model->validate() && $model->login()) {
//delete this verification code
$verificationCode->delete();
//delete all existing codes for user_id
VerificationCode::model()->deleteAll('user_id',$user->id);
Yii::app()->user->setReturnUrl(array('/system/admin/'));
$this->redirect(Yii::app()->user->returnUrl);
}
However, this seems to just delete all the records, regardless on different user_id's in table. Can anyone see where I'm going wrong?
If you want to delete record with specified attributes, the cleanest way for this is to use deleteAllByAttributes():
VerificationCode::model()->deleteAllByAttributes(['user_id' => $user->id]);
Seems you call the function delete() in wrong way ... try passing value this way
VerificationCode::model()->deleteAll('user_id = :user_id', array(':user_id' => $user->id));
For Yii2, the documented way is to use the function deleteAll().
I normally pass the arguments as an array, like so:
VerificationCode::deleteAll(['user_id' => $user->id]);
Also, you can use the afterDelete method, to make sure that everytime or everywhere someone deletes one verificationCode, your application will also delete every userVerificationCode. Put this in your verificationCode model class:
protected function afterDelete()
{
parent::afterDelete();
VerificationCode::model()->deleteAll('user_id = :user:id',[':user_id' =>$this->user_id]);
//... any other logic here
}
You can use below method for deleting all user_id entry from database:
$criteria = new CDbCriteria;
// secure way for add a new condition
$criteria->condition = "user_id = :user_id ";
$criteria->params[":user_id"] = $user->id;
// remove user related all entry from database
$model = VerificationCode::model()->deleteAll($criteria);
or you can use another method directly in controller action
VerificationCode::model()->deleteAll("user_id= :user_id", [":user_id"
=>$user->id]);
use below method for redirecting a URL
$this->c()->redirect(Yii::app()->createUrl('/system/admin/'));

How to link my controller and values from the user?

I am new to practicing CakePHP, I want to get value from the webuser and my controller will search that value from the DB. I am just wondering how I insert my $_post value add it to following code?
class DataviewsController extends AppController {
public $components = array('RequestHandler');
public function customer($id = null) {
$this->loadModel('Customer','Stock');
if (!$this->Customer->exists($id)) {
throw new NotFoundException(__('Invalid customer'));
}
$options = array('conditions' => array('Customer.' . $this->Customer->primaryKey => $id));
// Send the customer to the view
$this->set('customer', $this->Customer->find('first', $options));
$this->set('_serialize',array('customer'));
}
You can access post data in $this->request->data and get data in $this->request->query. As for your second question, I'm not sure what you are asking when it refers to the code you posted.
yes you can do with cakephp request handler object
here is very good example to create form and taking user data input and search from particular table. from that you can have very good idea how to implement in your application
just go throw this link Or this one for cakephp 2.0 and let me know if you need any more help

Categories