I'm trying to implement the queue that system will be restored back a deleted record. Now my code is working without error but the record will not restore back after deleted.
public function delete_invoice($job, $data)
{
Debugbar::info("invoiceSale");
try {
return DB::transaction(function ()use ($job,$data) {
});
} catch (TransactionException $e) {
# reestore function
extract($data);
$data = $Class::withTrashed()->find($id);
$data->restore();
Debugbar::info($data->toArray());
return Response::json(['errors' => array_flatten($e->getErrors())], 400);
}
}
This is the function from controller
public function destroy($id, $message = '')
{
Debugbar::info("ok");
Queue::push('IQueue#delete_invoice', [
'id' => $id,
'Class' => $this->Class,
]);
return parent::destroy($id, trans("$this->class.invoice")); <--delete invoice
}
you can use the following code hope it will help you.
public function destroy(Trip $trip)
{
$trip->delete();
flash()->warning('Trip '.$trip->id.' successfully deleted! <a href=trips/'.$trip->id.'/restore>UNDO</a>');
return redirect('trips');
}
public function restore(Request $request)
{
$trip = Trip::withTrashed()->where('id', $request['id'])->restore();
return redirect ('trips');
}
I'm assuming your code deletes the record somewhere else and the code you presented here is supposed to restore that record, based on the model class and record id passed via the $data array as ['Class' => ..., 'id' => ...].
Then what is your transaction meant to do? Is there any code you did not paste in? Otherwise catch is never called as there is no exception thrown and hence you code is not executed.
So just remove the try and catch.
Related
I am new at PHP. We are creating REST API in Phalcon and I've created a put request. It already works, but I would like to check if update has really happened before sending a success response. So I've created a conditional for that ( if (!$product->update()) ), but it always returns 'true'. How can I check if any field has changed in a record?
public function put()
{
$id = $this->getParam('id');
$input = $this->getRawData();
$product = Product::findFirst([
'conditions' => 'id = :id:',
'bind' => ['id' => $id]
]);
if ($product === null){
throw new NotFoundException();
}
$product->assign($input);
$product->update();
if (!$product->update()) {
$this->errorResponse($product->getMessages());
} else {
$this->successResponse($product->toArray($product->update()));
}
}
You can use Model Events, i.e. afterUpdate and notSaved, like:
use Phalcon\Mvc\Model;
use Phalcon\Http\Response;
class ModelBase extends Model
{
public function afterUpdate()
{
$response = new Response();
$response->setJsonContent([
'success' => true,
'message' => "Record updated"
])->send();
}
public function notSaved()
{
$response = new Response();
$response->setJsonContent([
'success' => false,
'message' => 'Record not saved'
])->send();
}
}
The Product and all other models will extend ModelBase. Then your code could be:
public function put()
{
$id = $this->getParam('id');
$input = $this->getRawData();
$product = Product::findFirst([
'conditions' => 'id = :id:',
'bind' => ['id' => $id]
]);
if ($product === null){
throw new NotFoundException();
}
$product->assign($input);
$product->update();
}
And Phalcon event will respond if the model was updated or not. If you prefer, you can also use custom http response codes for update or notSaved. More information about Model Events in the documentation
You are calling $product->update() three times. You do it once after the assign, then again for your if test, which is why it's always returning TRUE there I believe, and once inside the toArray() which may not actually return anything since the second and third updates don't have any data to update (not sure about that though).
I would code this as follows:
$product->assign($input);
$results = $product->update();
if (!results) {
$this->errorResponse($product->getMessages());
} else {
$this->successResponse($results->toArray());
}
I am assuming that the $product->assign($input); statement is working as expected to update the $product data for you. I don't use that. I prefer to do direct assignments for updates so nothing is left to chance, ie. $product->whatever = $input['whatever'];.
Give this a try and hopefully it will work as expected for you.
Hey Guys I have the following Scenario and I can't think of a better way. Maybe you guys can provide a more DRY method
So update method BaseController from Laravel Voyager
public function update(Request $request, $id)
{
// Update Logic Here
// Redirect Logic
if (auth()->user()->can('browse', app($dataType->model_name))) {
$redirect = redirect()->route("voyager.{$dataType->slug}.index");
} else {
$redirect = redirect()->back();
}
}
return $redirect->with([
'message' => __('voyager::generic.successfully_updated')." {$dataType->getTranslatedAttribute('display_name_singular')}",
'alert-type' => 'success',
]);
Custom Controller that extends the above Base Controller
public function update(Request $request, $id)
{
// Update Logic Copied and Pasted from Base ( Yuck :( )
// Small Change to the Redirect Logic
if (auth()->user()->can('browse', app($dataType->model_name))) {
$redirect = redirect()->route("voyager.{$dataType->slug}.index");
} else {
$redirect = redirect()->route("voyager.{$dataType->slug}.show",$id);
}
}
return $redirect->with([
'message' => __('voyager::generic.successfully_updated')." {$dataType->getTranslatedAttribute('display_name_singular')}",
'alert-type' => 'success',
]);
So my question is with the current structure of the Base Controller Is there any other way to override the redirect logic without literally copying and pasting the whole lot of code
I do not want to edit the BaseController as it will stop me from updating the package
Any thoughts would be great
Cheer
Simply use smaller functions to extract that logic and override it, similar approaches with overriding function through inheritance for changing logic, is used by Laravel on Models see getRouteKey() for example.
In your BaseController.php, i would split it up like so.
{
if (auth()->user()->can('browse', app($dataType->model_name))) {
$redirect = redirect()->route("voyager.{$dataType->slug}.index");
} else {
$redirect = $this->browseRedirectLocation();
}
}
return $redirect->with([
'message' => __('voyager::generic.successfully_updated')." {$dataType->getTranslatedAttribute('display_name_singular')}",
'alert-type' => 'success',
]);
}
protected function browseRedirectLocation() {
{
return $redirect = redirect()->back();
}
Now you should be able to override redirect location in your CustomController.php, instead of the whole function in your implementation class. As i could see it was only the redirect that was changed.
protected function browseRedirectLocation() {
{
return redirect()->route("voyager.{$dataType->slug}.show",$id);
}
I will try to insert & also update data using session in Codeigniter, but data not inserted into the database even its print save successfully.
Here is my controller:
public function save($user_id)
{
$this->load->model('Users');
$code=$this->input->post('code');
$name=$this->input->post('name');
$address=$this->input->post('address');
$user_data= array(
'code' =>$code,
'name'=>$name,
'address'=>$address,
'active'=>1
);
if($this->Users->save($user_data,$user_id))
{
$this->session->set_flashdata('msg',"save sucesss");
}else {
$this->session->set_flashdata('msg',"not save");
}
redirect('home');
}
& this is my model:
public function save($data,$id)
{
if (id=='') {
// code...
$this->db->insert('user',$data);
return true;
}else
{
$this->db->where('id',$id)
->update('user',$data);
return true;
}
return false;
}
Data insert if I removed if in model!
You have the model always returning true no matter the outcome of the database operation. You should use the return value from insert() or update() so the "message" reports what actually happens.
Note that the argument to save has a default value. Now you can call the save URL without an argument and it will automatically do an insert.
public function save($user_id = NULL)
{
$this->load->model('users');
$user_data = array(
'code' => $this->input->post('code'),
'name' => $this->input->post('name'),
'address' => $this->input->post('address'),
'active' => 1
);
if($this->Users->save($user_data, $user_id))
{
$msg = "save sucesss";
}
else
{
$msg = "not save";
}
$this->session->set_flashdata('msg', $msg);
redirect('home');
}
public function save($data, $id)
{
if(empty($id))
{
// code...
// insert returns TRUE on success, FALSE on failure
return $this->db->insert('user', $data);
}
// update() accepts a third argument, a "where" array
// and returns TRUE on success, FALSE on failure
return $this->db->update('user', $data, array('id' => $id));
}
Now have an accurate report on the database operations.
the first check is data is coming in save controller or not if it's not getting the data then fix it. If coming then pass it in a model in the correct format and it will definitely be inserted in the database.
use following printing data
echo $data;
var_dump($data);
print($data);
print_r($data);
First thing is to rename your model calling eg:
$this->load->model('users');
and use this to call your method:
$this->users->save($user_data,$user_id)
your model should look like this then:
public function save($data, $id) {
if ($id) {
$this->db->where('id', $id)
->update('user', $data);
return true;
}
$this->db->insert('user', $data);
return true;
}
if you want to use your flashdata on the next request, use this:
$this->session->keep_flashdata('item');
$this->session->keep_flashdata(array('item1', 'item2', 'item3'));
because flashdata is only for the next request:
CodeIgniter supports “flashdata”, or session data that will only be available for the next request, and is then automatically cleared.
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;
}
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.