Use transaction in laravel - laravel

I'm creating new user after that sending notification to user, i don't want to send notifications if user not created whether server side error occurs or on failure of database query. I'm trying to use transaction, but do not have idea where to place transaction code so that if user not created then it should not move to next code block.
$save = new newUser;
if($save->save()){
// Notification block
return response()->json(['status' => true, 'title' => 'Created' , 'message' => 'Data Saved Successfully'],200);
}
else
{
return response()->json(['status' => false ,'title' => 'Error' , 'message' => 'Data Not Saved'],200);
}
Any help is highly appreciated

You can use continue & break in your if else Condition.
If they have user exist then continue otherwise break it.

If there is some error while saving the user, e.g. error in database insert query or some other error, then the $save->save() will throw an exception. So you can handle it like this:
try {
$save->save();
return response()->json(['status' => true, 'title' => 'Created' , 'message' => 'Data Saved Successfully'],200);
} catch (\Exception $e) {
report($e);
return response()->json(['status' => false ,'title' => 'Error' , 'message' => 'Data Not Saved'],200);
}
Furthermore, you can try to catch a particular exception and send an appropriate notification for that failure.

Related

How to remove console error 422 (Unprocessable Content)

I write validation for email in my controller
public function store(Request $request)
{
/*
* validate request
*/
$request->validate([
'email' => ['required', 'unique:leads', 'email'],
]);
return response()->json([],422);
if (\App\Models\Lead::where(['email' => $request->get('email')])->count() > 0) {
// user found
return response()->json([ 'data' => [
'message' => 'lindirizzo email è già registrato'
]], 200);
}
else {
// Register the new user or whatever.
$client = \App\Models\Lead::create(['email' => $request->get('email'),]);
return response()->json([ 'data' => [
'message' => 'Registrato con successo!'
]], 201);
}
}
And when i write the same email in front i get error POST http://127.0.0.1:8000/api/register/leads 422 (Unprocessable Content)
My network respons its ok,
{"message":"validation.unique","errors":{"email":["validation.unique"]}}
But i dont want to show error in console
This line of code is unnecessary.
// ...
return response()->json([],422);
// ...
Remove it.
Writing The Validation Logic
... if the validation fails, the proper response will automatically be
generated. If the validation passes, our controller will continue
executing normally.
Addendum
The block of code below is unnecessary as well since the validation rule 'unique:leads' is sufficient:
// ...
if (\App\Models\Lead::where(['email' => $request->get('email')])->count() > 0) {
// user found
return response()->json([ 'data' => [
'message' => 'lindirizzo email è già registrato'
]], 200);
}
// ...
Remove it as well!
If you wish to have a custom message for the "unique email" validation, add it as the second parameter of the ->validate(...) method:
$request->validate([
'email' => ['required', 'unique:leads', 'email'],
], [
'email.unique' => 'lindirizzo email è già registrato'
]);
First, you need to check is there any email is available already or not in the table.
If you found any count of that email then simply ignore creating a record else you can add that email with a new entry inside the database.
if (Lead::where(['email' => $request->get('email')])->count() > 0) {
return response()->json([ 'data' => [
'message' => 'User data get successfully'
]], 200);
}else{
// Add a user with new email and send json response
}
}

add a number with the current number in database with Laravel Eloquent

I have this code to update a payment record if it already exists, if not, just create new one, and it is working ..... but I need to add a new amount to the existing amount for the update case:
try {
Payment::updateOrCreate([
'user_id' => $request->users,
], [
'amount' => $request->amount,
'date' => $mytime,
'number' => $number++,
]);
} catch (\Exception $ex) {
return redirect()->back()->with('status', 'you cannot insert this record');
}
What about using firstOrNew and doing something like this?
https://laravel.com/docs/9.x/eloquent#retrieving-or-creating-models
try {
$payment = Payment::firstOrNew([
'user_id' => $request->users,
], [
'amount' => $request->amount,
'date' => $mytime,
'number' => $number++,
]);
if ($payment->id) {
$payment->amount = $payment->amount + $new_amount;
}
$payment->save();
} catch (\Exception $ex) {
return redirect()->back()->with('status', 'you cannot insert this record');
}
In case a model is found, you will have a payment instance id, then you manipulate the amount.
For new Payment the model instance doesn't have an id then you just save the model.
Note that the model returned by firstOrNew has not yet been persisted to the database. You will need to manually call the save method to persist it.

Not getting data for authenticated user from database in Laravel for setting stripe

I've been trying to get the saved customer id for stripe from database but with no luck.
It works everywhere else, I could get it and save it again if I wanted, but whenever I try to use it in payment intent to automatically renew a subscription, it gives me this error: Trying to get property 'stripecustomerid' of non-object.
this is the bit of the stripe code for recurring charge where the error happens:
public function renew($subscription)
{
\Stripe\Stripe::setApiKey('sk_test_XXXXXXXX');
header('Content-Type: application/json');
try {
$json_str = file_get_contents('php://input');
$json_obj = json_decode($json_str);
$user = \Auth::user();
$payment_methods = \Stripe\PaymentMethod::all([
'customer' => $user->stripecustomerid,
'type' => 'card'
]);
$payment_intent = \Stripe\PaymentIntent::create([
'amount' => $subscription->plan->stripePrice(),
'currency' => 'usd',
'customer' => $user->stripecustomerid,
'payment_method' => $payment_methods->data[0]->id,
'off_session' => true,
'confirm' => true,
]);
echo json_encode([
'paymentIntent' => $payment_intent,
]);
}
catch (\Exception $e) {
http_response_code(500);
echo json_encode(['error' => $e->getMessage()]);
}
}
and stripecustomerid is the name of the column where I saved the customer id.
I can print it in another function, and it works when I use GET, but it just doesn't work when the subscription tries to renew.

Handling error thrown by resource controller's method

I' working with Laravel 5.6 and i've decided to create a resource controller to handle one of my models. Right know im trying to destroy a record from the database like this:
public function destroy(Role $role)
{
$role->delete();
return response([
'alert' => [
'type' => 'success',
'title' => 'Role destroyed!'
]
], 200);
}
It works just fine as longs as the $role exists. My problem is that i want to handle the response myself in the case that $role does not exist to do something like this:
return response([
'alert' => [
'type' => 'ups!',
'title' => 'There is no role with the provided id!'
]
], 400);
But instead, i'm getting a error like this:
"No query results for model [App\\Models\\Role]."
And that is something I don't want.
Thanks in advance!
The "No query results for model [App\\Models\\Role]." is the standard response message for a ModelNotFound exception in Laravel.
The best way to change the response for an exception like this is to use the exception handler's render function to respond with whatever message you want.
For example you could do
if ($e instanceof ModelNotFoundException) {
$response['type'] = "ups!;
$response['message'] = "Could not find what you're looking for";
$response['status'] = Response::HTTP_NOT_FOUND
}
return response()->json(['alert' => $response], $response['status']);
The alternative is to ensure that the ModelNotFound exception does not get thrown (So use ->find() rather than ->findOrFail() when querying the model)
and then using the abort helper like so if no results are returned:
abort(400, 'Role not found');
or
return response(['alert' => [
'type' => 'ups!',
'title' => 'There is no role with the provided id!']
],400);

how to create Custom Validation Rule for during Update a record in CakePHP

I have added a rule to check the previous password on update user record, but the rule also applies to creating a record, I have added 'update' but still, it's not working.
$validator
->scalar('password')
->maxLength('password', 25)
->notEmpty('password', 'Password is required', 'create')
->allowEmpty('password', 'update')
->add('password', 'validFormat', [
'rule' => ['custom', '/^(?=.*[!#$])(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9]).{6,16}$/i'],
'message' => __('Minimum 6 character & alphanumeric with one symbol(!#$) is Required.'),
'allowEmpty' => true
])
->add('password', 'custom', [
'rule' => function($value, $context){
$user = $this->get($context['data']['id']);
if ($user) {
if (!(new DefaultPasswordHasher)->check($value, $user->password)) {
return true;
}
}
return false;
},
'message' => 'You cannot use your previous password',
'allowEmpty' => true
], 'update');
Adding updated does not do anything as it is not something that CakePHP supports there.
If you read Custom Validation Rules you will see that you can use $context['newRecord'] to determine if this is an update or create.
So, the first line in your validation function could be something like
if ($context['newRecord']){
return true; //new passwords are always valid!
}
Alternative way would be to check the $user variable and add an else branch
if($user){
//you already have code here
}else{
//add this else to return TRUE because for new user, new password is OK
return true;
}

Resources