Laravel - Using Stream with the new Http client - laravel

I'm migrating my old system to the new version of Laravel, and I'm having problems with one of my requests...
Basically on this request I receive any file and simply forward it to the user. Here is the old version using Guzzle:
use Symfony\Component\HttpFoundation\StreamedResponse;
public function getMedia($media)
{
try {
$response = $this->client->get('media/' . $media, [
'stream' => true
]
);
$contentType = $response->getHeader('Content-Type');
$body = $response->getBody();
$stream = new StreamedResponse(function () use ($body) {
while (!$body->eof()) {
echo $body->read(1024);
}
});
$stream->headers->set('Content-Type', $contentType);
return $stream;
} catch (ClientException $e) {
return response()->json([
'errors' => json_decode($e->getResponse()->getBody()->getContents())->errors,
'message' => 'Unfortunately we could not find the requested file'
], 404);
}
}
And the new code that I tried to write, without success:
use Symfony\Component\HttpFoundation\StreamedResponse;
public function getMedia($media)
{
$response = Http::withOptions([
'stream' => true
])->get("media/{$media}");
$contentType = $response->header('Content-Type');
$body = $response->body();
$stream = new StreamedResponse(function () use ($body) {
while (!$body->eof()) {
echo $body->read(1024);
}
});
$stream->headers->set('Content-Type', $contentType);
return $stream;
}
Does anyone have any idea how to solve this? I don't know what to do anymore...

I know, 2 years late, but i'm doing something similar, you should access to the response via the psr
instead of:
$body = $response->body(); // This try to return an string
Use this:
$body = $response->toPsrResponse()->getBody(); // the guzzle response
Then you can use your normal code
I hope someone can find this useful,

Related

How to flash validation errors to session in Laravel

The built in behavior for flashing back validation errors in Laravel does not seem to be working for my use case.
I have a (React) form that posts it's data via fetch API using this method, which reloads or redirects the page with (hopefully) any session data after the response is returned:
fetch(props.register_route, {
method: 'POST',
headers: {
'X-CSRF-Token': props.csrf,
},
body: data,
})
.then((result) => {
return result.json();
})
.then((result) => {
console.log(result);
window.location.href = result.url;
},
(error) => {
console.log(error);
});
In my controller, I validate this data but if I structure it as follows, the errors are not available as $errors in the resulting page
if ($validator->fails()) {
return redirect()->back()->withErrors($validator);
}
However if I manually flash the errors to the session and return a url instead of a redirect, suddenly the behavior works.
if ($validator->fails()) {
Session::flash('errors', $validator->errors());
return response->json([
'url' => route('register'),
], Response::HTTP_NOT_ACCEPTABLE);
}
I feel as if I must be doing something incorrectly here to have to use this workaround. I could also manually send the errors back in the response, which may be the right way to structure things in the long run.
when you are calling api from javascript or front end applications like Reactjs,Angular,android etc.. .So it expect return result should be in json format so it should be like
if ($validator->fails()) {
return response()->json( $validator->errors(),422);
}
if you not calling Method from direct laravel blade then pass response in JOSN Format.
like
https://laravel.com/docs/8.x/responses#json-responses
Or
make one ResponseManager File
<?PHP
namespace App\Libraries\utils;
class ResponseManager {
public static $response = array('flag' => true, 'data' => '', 'message' => '', 'code' => 01,);
public static function getError($data = '', $code = 10, $message = '', $flag = false) {
self::$response['flag'] = $flag;
self::$response['code'] = $code;
self::$response['data'] = $data;
self::$response['message'] = $message;
return self::$response;
}
public static function getResult($data = '', $code = 10, $message = '', $flag = true) {
self::$response['flag'] = $flag;
self::$response['code'] = $code;
self::$response['data'] = $data;
self::$response['message'] = $message;
return self::$response;
}}
Define in config/app.php
//custom class
'ResponseManager' => App\Libraries\utils\ResponseManager::class,
and then use in whole project
Error Message Like
if ($validation->fails()) {
$message = $validation->messages()->first();
return Response()->json(ResponseManager::getError('', 1, $message));
}
Success Message Like
return Response()->json(ResponseManager::getResult(null, 10, "Success"));

extend larasap/fb post method

I'm trying to extend the functionality of a method from this package:
https://github.com/toolkito/laravel-social-auto-posting
Because the usage from mine controller is so simple, and others package makes a big mess even for basic operation like the one I need to achieve!
Goal: -posting text over a fb page with some tags of users that have allready puted a like to the same page.
So I Start from this call:
SendTo::Facebook(
‘link’,
[
‘link’ => ‘https://github.com/toolkito/laravel-social-auto-posting',
‘message’ => ‘Laravel social auto posting’
]
);
If I simply cut the link part, the message part can be my text of the post, and all works easy.
If I try to add user's tag on the 'message' part with the notation:
#[userId]
thats not works and the tag part is cutted and only the text is showed:
If I send 'text'=>'some text #[mineuserid] more text''
only
'some text more text'
is showed on the wall.
So I move to copy and extend the methods.
If I well understand from fb documentation I can tags user with the field tags but needs to be specified even the field places (in that case if I well understand my page's id)
So I start to explore into package, and trying to mods over sends link of the package:
public static function Facebook($type, $data)
{
switch ($type) {
case 'link':
$message = isset($data['message']) ? $data['message'] : '';
$result = FacebookApi::sendLink($data['link'], $data['message']);
break;
case 'postolo':
$message = isset($data['message']) ? $data['message'] :'';
$tags =isset($data['tags']) ? $data['tags'] : '';
$places =isset($data['places']) ? $data['places'] : '';
$result = FacebookApi::sendPostolo( $message, $tags,$places);
break;
Mine part is "postolo"
Then I found sendLink:
public static function sendLink($link, $message = '')
{
self::initialize();
$data = compact('link', 'message');
try {
$response = self::$fb->post('/me/feed', $data, self::$page_access_token);
} catch(Facebook\Exceptions\FacebookResponseException $e) {
throw new \Exception('Graph returned an error: '.$e->getMessage());
} catch(Facebook\Exceptions\FacebookSDKException $e) {
throw new \Exception('Facebook SDK returned an error: '.$e->getMessage());
}
$graphNode = $response->getGraphNode();
return $graphNode['id'];
}
If I foolishly copy this and adapts it to my needs is something like:
public static function sendPostolo($link, $message = '',$tags='',$places='')
{
self::initialize();
$data = compact( 'tags','message','places');
try {
$response = self::$fb->post('/me/feed', $data, self::$page_access_token);
} catch(Facebook\Exceptions\FacebookResponseException $e) {
throw new \Exception('Graph returned an error: '.$e->getMessage());
} catch(Facebook\Exceptions\FacebookSDKException $e) {
throw new \Exception('Facebook SDK returned an error: '.$e->getMessage());
}
$graphNode = $response->getGraphNode();
return $graphNode['id'];
}
But at the end the method $fb->post() not works as espect to me, and just publishs the first data of my array $data = compact( 'tags','message','places'); so in that case 'tags' and not as tags but predictably as plain text...
this is post() on fb package:
public function post($endpoint, array $params = [], $accessToken = null, $eTag = null, $graphVersion = null)
{
return $this->sendRequest(
'POST',
$endpoint,
$params,
$accessToken,
$eTag,
$graphVersion
);
}

Rollback not working in laravel multiple database in 5.2

Rollback not working in laravel multiple database in 5.2. What can i do? please help me. Advance thanks.
public function TestingRegistration(){
$now=date('Y-m-d H:i:s');
$faculty_user_account=array(
'user_id' =>'466297',
'name' => 'Hello',
);
\DB::beginTransaction();
try{
$save_registration=\DB::table('users')->insert($faculty_user_account);
$view2= \DB::connection('mysql_2')->table('users')->insert($faculty_user_account);
$view3 = \DB::connection('mysql_3')->table('users')->insert($faculty_user_account);
\DB::commit();
return \Redirect::back()->with('message',"Faculty Registration Successfull!");
}catch(\Exception $e){
\DB::rollback();
$message = "Message : ".$e->getMessage().", File : ".$e->getFile().", Line : ".$e->getLine();
return \Redirect::back()->with('errormessage',$message);
}
}
The easy way to do transaction is to use it as a callback, this way it will be handle it automatically for you.
public function TestingRegistration(){
$now = \Carbon::now(); // Where is this use?
$faculty_user_account = [
'user_id' => '466297',
'name' => 'Hello',
];
$success = \DB::transaction(function () use ($faculty_user_account) {
$save_registration = \DB::table('users')->insert($faculty_user_account);
$view2 = \DB::connection('mysql_2')->table('users')->insert($faculty_user_account);
$view3 = \DB::connection('mysql_3')->table('users')->insert($faculty_user_account);
return (bool) $view2 && $view3;
});
if (! $success) {
return \Redirect::back()->with('errormessage', 'Unable to save.');
}
return \Redirect::back()->with('message',"Faculty Registration Successfull!");
}
PS: I can't remember what insert returns, let me check later to make sure it can be use like that for testing success.

How to insert into couchDB in laravel

How to insert the records to couchDB in laravel. i have done the retrieval part but now I want to do insert, update and delete .
My retrieval code is below.
class couchdbcontroller extends Controller
{
public function getdata()
{
$content =null;
try {
$client = new Client();
$apiRequest = $client->request('GET','http://localhost:5984/user/_design/userdesign/_view/user-view?limit=20&reduce=false');
$code = $apiRequest->getBody()->getContents();
} catch (RequestException $re) {
//For handling exception
return $re->error;
}
return $code;
//return response()->json($code);
}
}
Inserting code below:
public function guzzle_insert_doc()
{
$client = new Client();
$res = $client->request('PUT', 'http://localhost:5984/login/new_doc',[
'uname' => 'admin',
'password' => 'admin123',
]);
//return $res;
}
Error: Client error: PUT http://localhost:5984/login/new_doc resulted in a 400 Bad Request response:
{"error":"bad_request","reason":"invalid UTF-8 JSON"}
From my google search, you could do something like this :
<?php
$client = new Client();
$doc = ['title'=>'This is a new doc'];
$res = $client->request('PUT', 'http://localhost:5984/db/new_doc',['json' => $doc]);
I assume you're using Guzzle (If I am wrong, tell us what your are using)
I didn't test my code since I don't have time to setup a laravel project with Guzzle. See documentation for further help.

How can I process a Response directly in Laravel?

I'm writing code in my Laravel Controller and I want to trap some exceptions firing a response directly without returning something to the routes.
For example, I wrote a method for returning a 404 response:
public static function respondNotFound( $message = null, $instantResponse = false )
{
$message = $message ? $message : "Not Found";
$statusCode = self::STATUS_NOTFOUND;
return self::makeResponse( array( 'status' => $statusCode, 'message' => $message ), $statusCode );
}
This method calls another one for building an Illuminate Response
protected static function makeResponse( $data, $statusCode = self::STATUS_OK, $instantResponse = false )
{
$response = Illuminate\Support\Facades\Response::json( $data, $statusCode );
$response->setCallback( Input::get( 'callback' ) );
if( $instantResponse ) {
//..... I want to fire my Response here!
}
else {
return $response;
}
}
Referring to the method above, I want to specify that my response must be fired directly rather than being returned outside, avoiding a "waterfall of return".
My solution is to set up some php headers and then kill the script, but I think that it's a bit rough.
Can someone help me?
Thanks in advance.
I'm confused - why dont you just use the App::missing() filter and handle your 404 in there?
In 'app/start/global.php' add:
App::missing(function($exception)
{
if (Request::ajax())
{
return Response::json( ['status' => 'error', 'msg' => 'There was an error. I could not find what you were looking for.'] );
}
elseif ( ! Config::get('app.debug'))
{
return Response::view('errors.404', array(), 404);
}
});
From looking at your code - you seem to be duplicating the response class. I dont understand why you are doing all of that, when you can just do
return Response::view('error', $message, $statuscode);
anywhere in your application...
Edit: you could also do
App::abort(404);
And then catch the abort filter in your app. You can change the 404 to be any HTTP response code you want.

Resources