While trying to request data from en external API, I want to control how the response is being passed to my view or database. However what would be the correct way to write the code below, so instead of simply echoing the data onto the view I would like to store it inside an object that I can pass to my view or model in a more controlled way?
public function index()
{
$contents = $this->saveApiData();
return View::make('stats.index')->with('contents', $contents);
}
public function saveApiData()
{
$client = new Client(['base_uri' => 'https://owapi.net/api/v3/u/']);
$res = $client->request('GET', "data" . "/blob");
echo $res->getStatusCode();
echo $res->getBody();
}
Just put them together in an array and return it. You never echo data in a function to return them.
public function saveApiData()
{
$client = new Client(['base_uri' => 'https://owapi.net/api/v3/u/']);
$res = $client->request('GET', "data" . "/blob");
$contents = [
'status' => $res->getStatusCode(),
'body' => $res->getBody()
];
return $contents;
}
Related
In my controller i have this function
public function GetStatusDetails()
{
$response = Http::get('https://exemple.exemple.com/fr/api/<token>/availability/<Id>/getStatusDetails?format=json');
$StatusDetails = json_decode($response->body(), true);
//dd($data);
return view('ControlmAPI.netvigie', [
'StatusDetails' => $StatusDetails
]);
}
public function GetStatus()
{
$response = Http::get('https://exemple.exemple.com/fr/api/<token>/availability/<Id>/getStatus?format=json');
$Status = json_decode($response->body(), true);
//dd($data);
return view('ControlmAPI.netvigie', [
'Status' => $Status
]);
}
Is not the same call api but when i want to use StatusDetails in my blade i can't but Status i can so my question is how to pass multiple data to my blade and use it separately.
the dd of them is DD so in my blade i do {{$Status[0]['status']}} it work but when i want to do for "StatusDetails" it doesn't but if i do only for "StatusDetails" it works but not for both someone have the solution please ?
You can simply pass them as an array
public function GetStatus()
{
$statusResponse = Http::get('https://exemple.exemple.com/fr/api/<token>/availability/<Id>/getStatus?format=json');
$statusDetailsResponse = Http::get('https://exemple.exemple.com/fr/api/<token>/availability/<Id>/getStatusDetails?format=json');
$Status = json_decode($statusResponse->body(), true);
$StatusDetails = json_decode($statusDetailsResponse->body(), true);
return view('ControlmAPI.netvigie', [
'Status' => $Status,
'StatusDetails' => $StatusDetails,
]);
}
Is there any sample/tutorial working with both Aura router and dispatcher? I found a sample code on the documentation page:
// dispatch the request to the route handler.
// (consider using https://github.com/auraphp/Aura.Dispatcher
// in place of the one callable below.)
$callable = $route->handler;
$response = $callable($request);
// emit the response
foreach ($response->getHeaders() as $name => $values) {
foreach ($values as $value) {
header(sprintf('%s: %s', $name, $value), false);
}
}
http_response_code($response->getStatusCode());
echo $response->getBody();
and I wanna know how can I integrate the Aura dispatcher with this sample code.
The second question is when we want to retrieve a GET request using Aura router, we use something like this:
// add a route to the map, and a handler for it
$map->get('blog.read', '/blog/{id}', function ($request) {
$id = (int) $request->getAttribute('id');
$response = new Zend\Diactoros\Response();
$response->getBody()->write("You asked for blog entry {$id}.");
return $response;
});
How about the POST method? I tried the following code, but it cannot retrieve the firstname in a similar way:
$map->post('profile', '/profile', function ($request) {
$firstname = $request->getAttribute('firstname');
$response = new Zend\Diactoros\Response();
$response->getBody()->write("first name is {$firstname}");
return $response;
});
The output is missing the $firstname value:
first name is
There are multiple ways you can use Aura.Dispatcher. The example provided below is one way.
$route = $matcher->match($request);
So once you match the request, there can be a route or null.
If there is a route, you can get the $route->handler;. This can be either a callable or string.
It is your implementation that tells how the Dispatcher can be invoked. From https://gist.github.com/harikt/8671136
<?php
require dirname(__DIR__) . '/vendor/autoload.php';
use Aura\Dispatcher\Dispatcher;
use Aura\Router\RouterContainer;
use Zend\Diactoros\Response;
use Zend\Diactoros\ServerRequest;
class Blog
{
public function browse(ServerRequest $request)
{
$response = new Response();
$response->getBody()->write("Browse all posts!");
return $response;
}
public function read(ServerRequest $request, $id)
{
$id = (int) $request->getAttribute('id');
$response = new Response();
$response->getBody()->write("Read blog entry $id");
return $response;
}
public function edit(ServerRequest $request, $id)
{
$response = new Response();
$response->getBody()->write("Edit blog entry $id");
return $response;
}
}
$dispatcher = new Dispatcher;
$dispatcher->setObjectParam('controller');
$dispatcher->setMethodParam('action');
$dispatcher->setObject('blog', new Blog());
$routerContainer = new RouterContainer();
$map = $routerContainer->getMap();
// NB : You can use # sign as in Laravel. So blog#browse
$map->get('blog.browse', '/blog', 'blog::browse');
$map->get('blog.read', '/blog/{id}', 'blog::read');
$request = Zend\Diactoros\ServerRequestFactory::fromGlobals(
$_SERVER,
$_GET,
$_POST,
$_COOKIE,
$_FILES
);
$matcher = $routerContainer->getMatcher();
$route = $matcher->match($request);
if ($route) {
foreach ($route->attributes as $key => $val) {
$request = $request->withAttribute($key, $val);
}
// Take special attention, how I am using the handler.
// Do what you want with the handler
list($controller, $action) = explode('::', $route->handler);
$params = [
'controller' => $controller,
'action' => $action,
'request' => $request,
// This is not needed, just showing for demo purpose
'id' => $request->getAttribute('id'),
];
$response = $dispatcher($params);
// emit the response
foreach ($response->getHeaders() as $name => $values) {
foreach ($values as $value) {
header(sprintf('%s: %s', $name, $value), false);
}
}
http_response_code($response->getStatusCode());
echo $response->getBody();
} else {
echo "No route found";
}
I repeat this is not the only way. There are other better ways, read https://github.com/auraphp/Aura.Web_Kernel if you are really interested to learn more.
Regarding your question about getting value from POST. No there is no other way. The router is not handling the POST values. I think probably PSR-7 could have improved a bit in those areas :-) .
I am writing some tests for my controllers but one of my tests doesn't work. It's supossed to search and get the results back to the page. But it's actually redirecting to the home page. Here is my code:
use DatabaseMigrations;
protected $user;
public function setUp()
{
parent::setUp();
$this->seed();
$this->user = factory(User::class)->create(['role_id' => 3]);
}
/** #test */
public function test_manage_search_user()
{
$response = $this->followingRedirects()->actingAs($this->user)->get('/manage/users/search', [
'choices' => 'username',
'search' => $this->user->username,
]);
$response->assertViewIs('manage.users');
$response->assertSuccessful();
$response->assertSee($this->user->email);
}
The URL you should get to make it work look like this:
http://localhost/manage/users/search?choices=username&search=Test
I checked again and it looks like it's not given in the parameters with the get request. How can I fix this?
I had the same issue trying to test GET Requests, you actually can't pass parameter with the $this->get('uri', [header]) but you can by using $this->call, if you check in MakesHttpRequests.php you can see that this->get() is actually using call method.
By adding an array to get method, you are changing the request headers, this is why you are not getting your parameters.
public function get($uri, array $headers = [])
{
$server = $this->transformHeadersToServerVars($headers);
return $this->call('GET', $uri, [], [], [], $server);
}
public function call($method, $uri, $parameters = [], $cookies = [], $files = [], $server = [], $content = null)
{
$kernel = $this->app->make(HttpKernel::class);
$files = array_merge($files, $this->extractFilesFromDataArray($parameters));
$symfonyRequest = SymfonyRequest::create(
$this->prepareUrlForRequest($uri), $method, $parameters,
$cookies, $files, array_replace($this->serverVariables, $server), $content
);
$response = $kernel->handle(
$request = Request::createFromBase($symfonyRequest)
);
if ($this->followRedirects) {
$response = $this->followRedirects($response);
}
$kernel->terminate($request, $response);
return $this->createTestResponse($response);
}
So if you want to test a GET Request you will have to do this:
$request = $this->call('GET', '/myController', ["test"=>"test"]);
In your controller you should be able to get theses parameters like so:
public function myController(Request $request)
{
$requestContent = $request->all();
$parameter = $requestContent['test'];
}
I'm using Laravel 5.X (more precisely 5.6), you can pass custom parameters using:
$response = $this->json('GET', '/url/endpoint',['params'=>'value']);
You can use the route helper to build a url with query string. in your case i would do something like this. Assuming the route name is manage.users.search
$route = route('manage.users.search', [
'choices'=> 'username',
'search' => $this->user->username,
]);
$response = $this->followingRedirects()
->actingAs($this->user)
->get($route);
In order to send parameters with GET requests.
If you use the route() method then you can pass the data as the second parameter.
$response = $this->get(route('route_name', ['key' => value]));
If you using URL directly, you could use like this
$response = $this->get('url?' . Arr::query(['key' => value]));
Do whatever you want to do with $response.
You could use the request helper to merge in http get parameters as such:
/** #var \Illuminate\Http\Request $request */
$request = request();
$request->merge([
'choices' => 'username',
'search' => 'Test'
]);
This worked for me simply pass the parameter as part of the url as follows:
$response = $this->get('api/endpoint?parameter1='.$this->dynamicParam);
Add a helper function:
if (!function_exists('extend_url_with_query_data')) {
function extend_url_with_query_data(string $url, array $queryData): string
{
if ($queryData == []) {
return $url;
}
$glue = mb_strpos($url, '?') === false ? '?' : '&';
$queryString = http_build_query($queryData);
return "{$url}{$glue}{$queryString}";
}
}
Usage:
$queryData = [
'works' => true,
];
$this->get(
extend_url_with_query_data('/api/v1/example', $queryData)
);
I would do it like this:
$this->actingAs($this->user);
$response = $this->get('/manage/users/search', [
'choices' => 'username',
'search' => $this->user->username,
]);
$response->assertViewIs('manage.users');
$response->assertSuccessful();
$response->assertSee($this->user->email);
I want to pull channel information based on a username or channel id. This information is derived from the URL used to view that channel.
EX: https://www.youtube.com/user/csga5000, or, https://www.youtube.com/channel/some-channel-id
I have this code:
$this->load->library('APIs/YouTube');
echo "[";
echo json_encode($this->youtube->getId('channel/UCkklJA9WbtJM5-g21xHI3yA'),false);
echo "\n]";
The function called is:
public function getId($url) {
$id = explode('/', $url);
echo json_encode($id).',';
//User's channel
if ($id[0] === 'user') {
$response = $this->youtube->channels->listChannels('id,snippet',array(
'forUsername' => $id[1]
));
}
//Channel id
else {
$response = $this->youtube->channels->listChannels('id,snippet',array(
'id' => $id[1],
'maxResults' => 2
));
}
return $response;
}
Here is the construct function for the youtube class:
public function __construct()
{
$this->client = new Google_Client();
$this->client->setDeveloperKey($this->api_key);
$this->client->setClientId($this->client_id);
$this->client->setClientSecret($this->client_secret);
$this->client->setScopes(array(
Google_Service_Oauth2::PLUS_LOGIN,
Google_Service_Oauth2::PLUS_ME,
Google_Service_Oauth2::USERINFO_EMAIL,
Google_Service_Oauth2::USERINFO_PROFILE,
Google_Service_YouTube::YOUTUBE
));
$ci =& get_instance();
$this->client->setRedirectUri($ci->config->item('base_url').'auth/youtube/');
$this->oauth = new Google_Service_Oauth2($this->client);
$this->youtube = new Google_Service_YouTube($this->client);
}
Calling the function with 'user/csga5000' doesn't work either
The results printed are:
[
[
"channel",
"UCkklJA9WbtJM5-g21xHI3yA"
],
{
"etag":"\"IHLB7Mi__JPvvG2zLQWAg8l36UU\/KcPrlZVHCJ9bAKurpGOj1BBEH6g\"",
"eventId":null,
"kind":"youtube#channelListResponse",
"nextPageToken":null,
"prevPageToken":null,
"visitorId":null
}
]
I just want results like this:
https://www.googleapis.com/youtube/v3/channels?part=id%2Csnippet&id=UCkklJA9WbtJM5-g21xHI3yA&key={YOUR_API_KEY}
or
https://www.googleapis.com/youtube/v3/channels?part=id%2Csnippet&forUsername=csga5000&key={YOUR_API_KEY}
Which you can test here:
https://developers.google.com/youtube/v3/docs/channels/list#try-it
With forUsername csga5000 or id UCkklJA9WbtJM5-g21xHI3yA
All the examples I found used "mine => true" and oauth to load this data, so nothing on google, or stack overflow seemed helpful.
I was just missing something silly, I'd been super confused by the response.
I needed the line:
$response->getItems();
I have been searching all over stackoverflow and Google for a solution to my problem.
I have created two projects with Zend Framework - Project1 and Project2 - and I want to implement web services on one of them. The idea is to send a JSON-string to Project1 and receive back a JSON with all the details associated with that variable using POST. Now I have created a TestController on Project2:
public function indexAction(){
$uri = 'http://project1.com/WebService/data';
$config = array(
'adapter' => 'Zend_Http_Client_Adapter_Curl',
'curloptions' => array(CURLOPT_FOLLOWLOCATION => true),
);
$client = new Zend_Http_Client($uri, $config);
$request = $client->request('POST');
print_r($request->getBody());
exit();
}
The above code works. It reads the dataAction from the Project1 controller and gives me an output of whatever is echoed. But when I try this:
public function indexAction(){
$uri = 'http://project1.com/WebService/data';
$config = array(
'adapter' => 'Zend_Http_Client_Adapter_Curl',
'curloptions' => array(CURLOPT_FOLLOWLOCATION => true),
);
$client = new Zend_Http_Client($uri, $config);
$data = array(
'userID' => 'TEST TEST',
'value' => 1,
'description' => 'ABCDEFG',
);
$request = $client->request('POST');
$json = json_encode($data);
$client->setRawData($json, 'application/json')->request('POST');
exit();
}
And on the server side when I try displaying inside dataAction:
public function dataAction(){
var_dump($this->getRequest()->getParam('var-name'));
var_dump($_POST);
die();
}
I get an output of this: NULL array(0) { } .... I get the same output when I try it on the client side. Also to mention.. I also tried opening the php://input file but got an empty string...
What am I missing??? I have frustrated myself searching on it since morning but got no solution.
Thanks in advance for response.
Here is what you are missing:
$json = json_encode($data);
$client->setRawData($json, 'application/json')->request('POST');
sends a POST request but the data in the POST body is not a url-encoded string, instead it is just raw JSON.
Calling $this->getRequest()->getParam('foo') looks at the PHP superglobals $_GET and $_POST which will not contain any of the JSON parameters. The reason it will be empty is because PHP couldn't parse the POST data since it was JSON and not HTTP url-encoded content.
The solution is to use something like this in the dataAction if you want to receive JSON data in the POST body.
$post = $this->getRequest()->getRawBody();
try {
$json = Zend_Json::decode($post);
// now access parameters from $json array
} catch (Zend_Json_Exception $ex) {
echo "Failed to decode request, POST did not contain valid JSON.";
}
Edit: Here is the full code you can mess with.
public function requestAction()
{
// CHANGE THIS
$uri = 'http://playground/zendapp/public/index/data';
$config = array(
'adapter' => 'Zend_Http_Client_Adapter_Curl',
'curloptions' => array(CURLOPT_FOLLOWLOCATION => true),
);
$client = new Zend_Http_Client($uri, $config);
$data = array(
'userID' => 'TEST TEST',
'value' => 1,
'description' => 'ABCDEFG',
);
$json = json_encode($data);
$resp = $client->setRawData($json, 'application/json')->request('POST');
var_dump($resp->getBody());
exit();
}
public function dataAction()
{
$post = $this->getRequest()->getRawBody();
try {
$json = Zend_Json::decode($post);
print_r($json);
} catch (Exception $ex) {
echo "failed to decode json";
}
exit;
}