Render a template with a specific status code - php

Since I've read that Chrome is having trouble looping an HTML5 video if the response code isn't 206, I'd like to render my template with a 206 code.
Yet I've not found anywhere how to specify an html code when rendering a template... Did anyone already tried that and succeeded ?

In the controller you can create and return a Response object with the content and the specified return code, as example:
return new Response(
$this->renderView('AcmeDemoBundle:Default:video.html.twig', array(
'param1' => $param1,
'param2' => $param2,
)),
206 // return code
);
Hope this help

You can pass a response object with your renderResponse that has the necessary status code.
$response = new Response('', 206);
return $this->renderResponse(
// Or return $this->container->get('templating')
'AcmeBundle:Video:show.html.twig',
array('video' => video),
$response
);
If you do not pass in a Response with your renderResponse one will be generated automatically. If you pass one then it's content is just set to that of the rendered template (as you can see in the code)

New implementation
protected function renderError(array $parameters, $statusCode = 500)
{
return $this->render(
'default/error.html.twig',
$parameters,
new Response('', $statusCode)
);
}

I think I you at this before you are rendering the template you will get the desired result:
$this->getContext()->getResponse()->setStatusCode(206);
btw.
The class Symfony\Component\HttpFoundation\Response provides constants for all valid HTTP-states

Related

OneNote error creating a page in Laravel using Microsoft Graph

i'm using Microsoft Graph in my Laravel application.
It works perfectly adding events to the user's calendar, getting events, creating OneNote's notebook.
The problem occurs when i try to add a page, i'm getting the next error:
The code i'm using is:
public function createNewNote()
{
$graph = $this->getGraph();
// Build the event
$newEvent = [
'body' => [
'content' => 'New page in default notebook',
'contentType' => 'text/html'
]
];
// POST /me/onenote/notebooks DEFAULT NOTEBOOK
$response = $graph->createRequest('POST', '/me/onenote/pages')
->attachBody($newEvent)
->setReturnType(Model\Notebook::class)
->execute();
dd("Success");
// return redirect('/calendar');
}
The next code works fine:
public function createNewNotebook()
{
$graph = $this->getGraph();
$newEvent = [
'displayName' => 'Creating new notebook'
];
// POST /me/onenote/notebooks DEFAULT NOTEBOOK
$response = $graph->createRequest('POST', '/me/onenote/notebooks')
->attachBody($newEvent)
->setReturnType(Model\Notebook::class)
->execute();
dd("Notebook Created");
// return redirect('/calendar');
}
I can't find the exact array or json structure for the body. What am i doing wrong? I also tried setting the text directly:
public function createNewNote()
{
$graph = $this->getGraph();
// POST /me/onenote/notebooks DEFAULT NOTEBOOK
$response = $graph->createRequest('POST', '/me/onenote/pages')
->attachBody('<div>Content</div>')
->setReturnType(Model\Notebook::class)
->execute();
dd("Success");
// return redirect('/calendar');
}
And getting this error:
[![enter image description here][1]][2]
As i said i can create events (calendar) and notebooks (onenote) but i can't add a page with simple html or text.
Thank you so much for your help!
As specified in the document since you are putting the HTML data in attachBody directly without specifying the content type.
That's the reason the other API calls work as they have JSON data specified properly.
As specified here in the example they have specified the content type.
I have tested the same with POSTMAN as shown below where you can see the content-type I have mentioned as text/html as the content we give is a div tag and it worked.

How do I get response from object sent via a request with wordpress api

I have registered a api request the following way in the code, then in postman I call that request and add some params, but when I run the api request endpoint it returns null.
How do I return the data that's being sent?
/**
* This is our callback
* function that embeds our phrase in a WP_REST_Response
*/
function addProductFromCRM($data) {
//$name = $data['name'];
// rest_ensure_response() wraps the data we want to return into a WP_REST_Response, and ensures it will be properly returned.
return rest_ensure_response($data);
}
/**
* This function is where we register our routes for our example endpoint.
*/
function wp_register_crm_routes() {
// register_rest_route() handles more arguments but we are going to stick to the basics for now.
register_rest_route('crm/v1', '/addproduct/', array(
// By using this constant we ensure that when the WP_REST_Server changes our readable endpoints will work as intended.
'methods' => 'POST',
// Here we register our callback. The callback is fired when this endpoint is matched by the WP_REST_Server class.
'callback' => 'addProductFromCRM',
));
}
add_action('rest_api_init', 'wp_register_crm_routes');
What addproduct endpoint should return? JSON? You can do something like this:
function addProductFromCRM($request) {
wp_send_json($request->get_params());
}
You can use below code snippet as per you need like on isset($_POST) or any other callback function. You must have the idea of your Register Route URL and must be working. you can use wp_remote_get or wp_remote_post as per your need. for more reference please check WordPress official site
$response = wp_remote_get("URL TO YOUR REGISTER ROUTE");
if ( is_array( $response ) ) {
$response_code = wp_remote_retrieve_response_code( $response );
$body = wp_remote_retrieve_body( $response );
$body_data = json_decode($body);
}

Getting Wordpress REST-API content data inside a plugin with embed data

I'm creating my own routes for the wodpress api. At some point I need the rest content of the post and pages, to do this i have this function:
function get_rest_content($id, $type)
{
if ($id > 0) {
$request = new WP_REST_Request('GET', '/wp/v2/'.$type.'/' . $id);
$response = rest_do_request($request)->data;
} else {
$response = null;
}
if (empty($response)) {
return new WP_Error('wpse-error',
esc_html__('No '.$type. 'found', 'wpse'),
['status' => 404]);
}
return $response;
}
$post_1 = get_rest_content(1,'posts') // give me the rest content of the post with id=1
but if I want to have the post content with embed data I change:
new WP_REST_Request('GET', '/wp/v2/'.$type.'/' . $id);
to
new WP_REST_Request('GET', '/wp/v2/'.$type.'/' . $id . '?_embed=true');
but this new request returns rest_no_route error
I have read the source code and now understand. The second parameter of new WP_REST_Request() is the route only without query parameters. The query parameters are specified in another method. E.g.,
$request = new WP_REST_Request( 'GET', 'wp/v2/posts/999' );
$request->set_query_params( [ '_embed' => '1' ] );
However, this will not work as '_embed' is a special query parameter. It is not handled by WP_REST_Server::dispatch(), which means rest_do_request() will not handle '_embed' as rest_do_request() is just a wrapper of WP_REST_Server::dispatch().
The reason '_embed' works from a URL is that URLs are processed by WP_REST_Server::serve_request() which calls WP_REST_Server::dispatch() but also calls WP_REST_Server::response_to_data() which calls WP_REST_Server::embed_links().
If you want '_embed' to work in your get_rest_content() you will need to add the code for WP_REST_Server::embed_links().
I found a Github issue but the workaround is not working for me (at least for my code+WordPress version): https://github.com/WP-API/WP-API/issues/2857
Did you try adding the embeddable links to the response?
//get the post
$response = rest_do_request($request)->get_data();
//add the embeddable links
$results_with_embed = rest_ensure_response(rest_get_server()->response_to_data( $response, true ));

How do I inspect response headers in laravel 4 for unit testing?

I have seen many examples on how to set headers on a response but I cannot find a way to inspect the headers of a response.
For example in a test case I have:
public function testGetJson()
{
$response = $this->action('GET', 'LocationTypeController#index', null, array('Accept' => 'application/json'));
$this->assertResponseStatus(200);
//some code here to test that the response content-type is 'application/json'
}
public function testGetXml()
{
$response = $this->action('GET', 'LocationTypeController#index', null, array('Accept' => 'text/xml'));
$this->assertResponseStatus(200);
//some code here to test that the response content-type is 'text/xml'
}
How would I go about testing that the content-type header is 'application/json' or any other content-type? Maybe I'm misunderstanding something?
The controllers I have can do content negation with the Accept header and I want to make sure the content type in the response is correct.
Thanks!
After some digging around in the Symfony and Laravel docs I was able to figure it out...
public function testGetJson()
{
// Symfony interally prefixes headers with "HTTP", so
// just Accept would not work. I also had the method signature wrong...
$response = $this->action('GET', 'LocationTypeController#index',
array(), array(), array(), array('HTTP_Accept' => 'application/json'));
$this->assertResponseStatus(200);
// I just needed to access the public
// headers var (which is a Symfony ResponseHeaderBag object)
$this->assertEquals('application/json',
$response->headers->get('Content-Type'));
}
While not specifically about testing, a nice way of getting at Laravel's response object is to register a 'Finish' callback. These are executed just after the response is delivered, right before the app closes. The callback receives the request and the response objects as arguments.
App::finish(function($request, $response) {
if (Str::contains($response->headers->get('content-type'), 'text/xml') {
// Response is XML
}
}
Take a look at the laravel documentation
Request::header('accept'); // or
Response::header('accept');
Retrieving A Request Header
$value = Request::header('Content-Type');
Another way would be to use getallheaders() :
var_dump(getallheaders());
// array(8) {
// ["Accept"]=>
// string(63) "text/html[...]"
// ["Accept-Charset"]=> ...
For debugging purposes You could simply use this:
var_dump($response->headers);

Laravel - POST data is null when using external request

I'm new to laravel, and I'm trying to implement a simple rest api.
I have the controller implemented, and tested via unit testing.
My problem is with the POST request.
Via the tests Input:json has data, via an external rest client it returns null.
This is the code on the unit test
$newMenu = array(
'name'=>'Christmas Menu',
'description'=>'Christmas Menu',
'img_url'=>'http://www.example.com',
'type_id'=>1,
);
Request::setMethod('POST');
Input::$json = $newMenu;
$response = Controller::call('menu#index');
What am I doing wrong?
UPDATE:
This is realy driving me crazy
I've instanciated a new laravel project and just have this code:
Routes
Route::get('test', 'home#index');
Route::post('test', 'home#index');
Controller:
class Home_Controller extends Base_Controller {
public $restful = true;
public function get_index()
{
return Response::json(['test'=>'hello world']);
}
public function post_index()
{
return Response::json(['test'=>Input::all()]);
}
}
CURL call:
curl -H "Accept:application/json" -H"Content-type: application/json" -X POST -d '{"title":"world"}' http://localhost/laravel-post/public/test
response:
{"test":[]}
Can anyone point me to what is wrong.
This is really preventing me to use laravel, and I really liked the concept.
Because you are posting JSON as your HTTP body you don't get it with Input::all();
You should use:
$postInput = file_get_contents('php://input');
$data = json_decode($postInput, true);
$response = array('test' => $data);
return Response::json($response);
Also you can use
Route::any('test', 'home#index');
instead of
Route::get('test', 'home#index');
Route::post('test', 'home#index');
Remove header Content-type: application/json if you are sending it as key value pairs and not a json
If you use : Route::post('test', 'XYZController#test');
Send data format : Content-type : application/json
For example : {"data":"foo bar"}
And you can get the post (any others:get, put...etc) data with :
Input::get('data');
This is clearly written in here : http://laravel.com/docs/requests
. Correct Content-type is very important!
I am not sure your CURL call is correct. Maybe this can be helpful : How to POST JSON data with Curl from Terminal/Commandline to Test Spring REST?
I am using Input::get('data') and it works.
I was facing this problem, my response of post was always null. To solve that I put the body key in guzzle object, like this
$client = new Client([
'headers' => [
'Content-Type' => 'application/json',
'Authorization' => config('app.callisto_token'),
]
]);
$body = [
'firstResult'=> 0,
'data' => '05/05/2022'
];
$response = $client->post('http://'.$this->ip.'/IntegracaoERP'.'/status_pedido',
['body' => json_encode($body)]
);
Don't forget the json_encode in body key.
Hope this helps.

Categories