How do I loop over json data - laravel

I am using FlutterWave as my payment gateway, I want to loop through a transaction whenever a customer finish making payment and check for the chargeamount which the user paid. the return data is in json format. Here is my code.
public function callback(Request $request)
{
$resp = $request->resp;
$body = json_decode($resp, true);
$txRef = $body['data']['data']['txRef'];
$data = Rave::verifyTransaction($txRef);
dd($data);
return redirect()->route('success');
}
I want to loop and check for the chargedamount but I couldn't. Thanks for your help

Seems like you are dumping an object. I don't think you need a loop to access the data you need. According to your image dump, to access the chargedamount attribute:
dd($data->data->chargedamount);
The data name here repeats, perhaps $payload in this case, its a better name.
public function callback(Request $request)
{
$resp = $request->resp;
$body = json_decode($resp, true);
$txRef = $body['data']['data']['txRef'];
$payload = Rave::verifyTransaction($txRef);
dd($payload->data->chargedamount);
return redirect()->route('success');
}
Some clean up:
public function callback(Request $request)
{
$json = json_decode($request->resp);
$payload = Rave::verifyTransaction($json->data->data->txRef);
dd($payload->data->chargedamount);
return redirect()->route('success');
}
Again that data->data repeating stuff, but in this case, nothing we can do, its in the API.

Related

How do I console/inspect the JSON response of a Laravel Resource in PHPUnit?

How do I inspect the JSON response in the terminal exactly how it would be returned from the ConversationResource?
Controller
public function show(Conversation $conversation)
{
$conversation->load('participants');
$messages = $conversation
->messages()
->with('sender')
->latest()
->paginate(10);
return new ConversationResource($conversation);
}
Test
/** #test */
public function a_user_can_create_conversation_if_one_doesnt_exist()
{
$this->withoutExceptionHandling();
$this->actingAs($user = User::factory()->create());
$friend = User::factory()->create();
$response = $this->json('GET', '/api/conversation/'. $friend->id)
->assertStatus(201);
dd($response->original);
}
You assign $response to result of assertStatus(). I have no idea what assertStatus returns but likely it does not have json content. I would try to assing to a variable result of this
$response = $this->json('GET', '/api/conversation/'. $friend->id);
and then
dd($response);
Also it would be good to setup xdebug and step trough code, but it is not that easy especially for tests.
If that does not work, then just call same url with https://www.php.net/manual/en/function.file-get-contents.php
and assing to variable and see what it has.

how to build a Laravel command that loops through users is sends unique emails to each user

I have a command that I'll run nightly using the Forge scheduler. The command simply loops through and sends emails to each user who qualifies for one.
COMMAND:
public function handle()
{
//Get all users
$users = User::all();
$data = [];
$renewalEmail = '';
foreach($users as $user)
{
//Check each users next_biling_date and see if is less than 72 hours from now, if so send reminder email
$nextBillingDate = ($user->hasSubscription())? $user->getSubscriptionData()->current_period_end : false;
$now = strtotime(now());
$threeDaysFromNow = 60*60*24*3;
//($user->hasSubscription())? $this->updateNextBillingDate($user) : false;//TODO: remove after working: follow up
if($user->hasSubscription() && $nextBillingDate-$now<=$threeDaysFromNow)
{
$data = [
'name' => $user->name,
'billingdate' => date('n/j/Y',strtotime($user->next_billing_date)),
];
// Log::info(print_r($data,true));
$renewalEmail = Mail::to('my#email.com')->send(new SubscriptionRenewalReminder($data));
// Log::info(print_r($renewalEmail,true));
}
}
return true;
}
My Mailable is pretty straight forward:
public function __construct($data)
{
$this->data = $data;
}
/**
* Build the message.
*
* #return $this
*/
public function build()
{
Log::info('SubscriptionRenewalReminder Email build() called: ');
$firstName = explode(' ',$this->data['name'])[0];
$billingDate = $this->data['billingdate'];
Log::info('firstname: '.$firstName);
Log::info('billingDate: '.$billingDate);
return $this->view('emails.subscription-renewal-reminder')
->from('my#email.com', 'Project')
->subject('Project Subscription Is About To Renew')
->withName($firstName)
->withBillingdate($billingDate);
}
All of my Log::info's dump out the right information. I have 3 test users who all qualify to get the email.
In my testing, all three emails show the first user's name and billing date. Instead of unique emails, they are all identical.
I may move this into a queue but on a small set of users this should work fine. TIA

laravel 5.7 how to pass request of controller to model and save

I am trying to pass $request from a function in controller to a function in model.
THis is my controller function:
PostController.php
public function store(Request $request, post $post)
{
$post->title = $request->title;
$post->description = $request->description;
$post->save();
return redirect(route('post.index'));
}
how save data in model Post.php?
I want the controller to only be in the role of sending information. Information is sent to the model. All calculations and storage are performed in the model
Thanks
You can make it even easier. Laravel has it's own helper "request()", which can be called anywhere in your code.
So, generally, you can do this:
PostController.php
public function store()
{
$post_model = new Post;
// for queries it's better to use transactions to handle errors
\DB::beginTransaction();
try {
$post_model->postStore();
\DB::commit(); // if there was no errors, your query will be executed
} catch (\Exception $e) {
\DB::rollback(); // either it won't execute any statements and rollback your database to previous state
abort(500);
}
// you don't need any if statements anymore. If you're here, it means all data has been saved successfully
return redirect(route('post.index'));
}
Post.php
public function postStore()
{
$request = request(); //save helper result to variable, so it can be reused
$this->title = $request->title;
$this->description = $request->description;
$this->save();
}
I'll show you full best practice example for update and create:
web.php
Route::post('store/post/{post?}', 'PostController#post')->name('post.store');
yourform.blade.php - can be used for update and create
<form action='{{ route('post.store', ['post' => $post->id ?? null]))'>
<!-- some inputs here -->
<!-- some inputs here -->
</form>
PostController.php
public function update(Post $post) {
// $post - if you sent null, in this variable will be 'new Post' result
// either laravel will try to find id you provided in your view, like Post::findOrFail(1). Of course, if it can't, it'll abort(404)
// then you can call your method postStore and it'll update or create for your new post.
// anyway, I'd recommend you to do next
\DB::beginTransaction();
try {
$post->fill(request()->all())->save();
\DB::commit();
} catch (\Exception $e) {
\DB::rollback();
abort(500);
}
return redirect(route('post.index'));
}
Based on description, not sure what you want exactly but assuming you want a clean controller and model . Here is one way
Model - Post
class Post {
$fillable = array(
'title', 'description'
);
}
PostController
class PostController extend Controller {
// store function normally don't get Casted Objects as `Post`
function store(\Request $request) {
$parameters = $request->all(); // get all your request data as an array
$post = \Post::create($parameters); // create method expect an array of fields mentioned in $fillable and returns a save dinstance
// OR
$post = new \Post();
$post->fill($parameters);
}
}
I hope it helps
You need to create new model simply by instantiating it:
$post = new Post; //Post is your model
then put content in record
$post->title = $request->title;
$post->description = $request->description;
and finally save it to db later:
$post->save();
To save all data in model using create method.You need to setup Mass Assignments when using create and set columns in fillable property in model.
protected $fillable = [ 'title', 'description' ];
and then call this with input
$post = Post::create([ 'parametername' => 'parametervalue' ]);
and if request has unwanted entries like token then us except on request before passing.
$post = Post::create([ $request->except(['_token']) ]);
Hope this helps.
I find to answer my question :
pass $request to my_method in model Post.php :
PostController.php:
public function store(Request $request)
{
$post_model = new Post;
$saved = $post_model->postStore($request);
//$saved = response of my_method in model
if($saved){
return redirect(route('post.index'));
}
}
and save data in the model :
Post.php
we can return instance or boolean to the controller .
I returned bool (save method response) to controller :
public function postStore($request)
{
$this->title = $request->title;
$this->description = $request->description;
$saved = $this->save();
//save method response bool
return $saved;
}
in this way, all calculations and storage are performed in the model (best way to save data in MVC)
public function store(Request $request)
{
$book = new Song();
$book->title = $request['title'];
$book->artist = $request['artist'];
$book->rating = $request['rating'];
$book->album_id = $request['album_id'];
$result= $book->save();
}

Write function in controller below controller class?

Is that a good practice to wrap some code from controller class method because it's too long and put that code in another custom function below controller class.
Here is controller method:
public function store(UploadRequest $request)
{
//Provjera duljine imena slike (max 20 znakova)
if(!is_valid_name($request->file('file'))) {
return redirect()->back()->withErrors(['File name can\'t be longer than 20 characters.']);
}
$user = Auth::user();
$time = time();
$image = $request->file('file');
//Dodaj trenutno vrijeme prije imena slike kako bi se slika mogla identificirati
$image_name = $time . $image->getClientOriginalName();
//Ako je slika png spremi ju bez konverzije
if($image->getClientOriginalExtension() == "png")
{
Storage::put('public/images/'.$user->id.'/png/'.$image_name, file_get_contents($image));
save_image_to_database($image, $user, $time);
}
Save_image_to_database() is my custom function that is written below controller class:
function save_image_to_database($image, $user, $time){
$db_image = new Image();
if($image->extension() == 'png')
{
$db_image->path = $time . $image->getClientOriginalName();
$db_image->png_size = $image->getClientOriginalSize();
}
else
{
$path = $time . pathinfo($image->getClientOriginalName(), PATHINFO_FILENAME).'.png';
$png_size = Storage::size('/public/images/'.$user->id.'/png/'.$path);
$db_image->path = $path;
$db_image->png_size = $png_size;
}
$db_image->user_id = $user->id;
$db_image->extension = $image->extension();
$db_image->size = $image->getClientSize();
$db_image->save();
return redirect('/images');
}
Problem is that redirect() method in custom function is not working, it redirects to blank window but the path in browser "localhost:8000/images" is correct.When I manually refresh the site then it works and the view is returned. If I move that redirect() method from custom function to controller store() then it works well.
Your function returns Response object but controller doesn't use it
The most simple solution for you will be to return the response of helper function like
return save_image_to_database($image, $user, $time);
However I would at least wrap it in try-catch to handle inability to save file like
try {
save_image_to_database($image, $user, $time);
} catch (\Exception $e) {
// return error response
}
// if we got here image was successfully saved
return redirect('/images');
Now back to your question about if its a good experience to handle image as another controller method.. I'd say no, you want to keep your controllers very skinny and have only methods that are used by Router
I'd either move it into a Trait (Traits in PHP) and use that trait in the controller or make an Image Service and use it via dependency injection.

Make an Ajax request in Symfony2

My problem is that the method doesn't return a true result.
I want to test if the email of input exists in my entity or not.
Here is the controller:
public function verificationAction(Request $request)
{
if ($this->container->get('request')->isXmlHttpRequest()) {
$email=$request->request->get('email');
$em=$this->getDoctrine()->getEntityManager();
$resp= $em->getRepository("CMSiteBundle:Prospect")->findBy(array('email'=>$email));
$response =new Response(json_encode($resp));
$response->headers->set('Content-Type', 'application/json');
return $response;
}
}
You could try an old-trick. Since in Symfony Controller Actions, You must return a Response why not fake a DEAD RESPONSE like so:
<?php
class ABCController {
public function verificationAction(Request $request) {
if ($this->container->get('request')->isXmlHttpRequest()) {
$email = $request->request->get('email');
$em = $this->getDoctrine()->getEntityManager();
$resp = $em->getRepository("CMSiteBundle:Prospect")
->findBy(array('email' => $email));
//$response = new Response(json_encode($resp));
//$response->headers->set('Content-Type', 'application/json');
// THE TRICK IS THAT DIE RUNS FIRST
// THUS SENDS YOUR RESPONSE YOU THEREBY
// STOPPING THE RETURN FROM FIRING... ;-)
return die(json_encode($resp));
}
}
}
Perhaps this very Old Trick still works for you... ;-)

Resources