OneNote error creating a page in Laravel using Microsoft Graph - php

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.

Related

How to open the PDF generated in new tab

I have a Leave application project that generates a PDF file.
this is the code that generates the pdf after I click submit.
$id = DB::table('leave')->where('user_id', auth()->user()->id)->max('id');
$data = leave::where('id', $id)->select('*')->get();
$filename = auth()->user()->name." - S - ". "LEAVE - ".$randomString->randomString(8)."-".$request->filing_date.".pdf";
$path = storage_path('app/leave_file/'.$filename);
PDF::loadView('pdf_views.leave_pdf', $data[0])->setPaper('legal')->save($path);
if(file_exists($path)){
DB::table('leave_files')->insert([
'filename' => $filename,
'leave_id' => DB::table('leave')->where('user_id', auth()->user()->id)->max('id'),
]);
}
return redirect()->route('leave')->with('success', "success");
I wonder if I can make the newly generated pdf open in the new tab after I click submit on my leave application. thank you to anyone who can help
According to the Laravel docs this is what you need: https://laravel.com/docs/9.x/responses#file-responses
File Responses
The file method may be used to display a file, such as an image or PDF, directly in the user's browser instead of initiating a download. This method accepts the path to the file as its first argument and an array of headers as its second argument:
return response()->file($pathToFile);
return response()->file($pathToFile, $headers);
Use the Cache Facade, to store the generated pdf temporary.
$uuid = Str::uuid();
return response()->stream(function () use ($uuid) {
echo Cache::remember($uuid, 300, function() {
return 'genertated pdf content'
});
}, 200, [
'Content-Type' => 'application/pdf',
'Content-Disposition' => sprintf('attachment; filename=%s;', $uuid),
]);
Create a route to access to cached file. Name the route.
Now you can open it in a new tab from you frontend e.g. Generate the route with route('routename', ['param' => 123]) and pass it to your FE with a REST endpoint for example.
window.open(url,'_blank');

Finding User with Auth - Laravel

I am trying to find the logged in user in my application using Auth but i get trying to get property of non-object which i understand clearly that it is returning null.
In my code below, an event triggers my webhook and post is sent to the address below. The function orderCreateWebhook triggers but that is where the error comes from..
The line $get_template = Order::where('id', Auth::user()->id);. Why is Auth returning null please? I am logged as well because i use auth in this same controller for another function which works fine.
Is it because it a webhook ?
Controller
public function registerOrderCreateWebhook(Request $request)
{
$shop = "feas.myshopify.com";
$token = "8f43d89a64e922d7d343c1173f6d";
$shopify = Shopify::setShopUrl($shop)->setAccessToken($token);
Shopify::setShopUrl($shop)->setAccessToken($token)->post("admin/webhooks.json", ['webhook' =>
['topic' => 'orders/create',
'address' => 'https://larashop.domain.com/order-create-webhook',
'format' => 'json'
]
]);
}
public function orderCreateWebhook(Request $request)
{
$get_template = Order::where('id', Auth::user()->id);
$baseurl = "https://apps.domain.net/smsapi";
$query = "?key=7e3e4d4a6cfebc08eadc&to=number&msg=message&sender_id=Shopify";
$final_uri = $baseurl.$query;
$response = file_get_contents($final_uri);
header ("Content-Type:text/xml");
}
In your function registerOrderCreateWebhook you appear to be making a request to shopify api and providing your webhook as the address which shopify will redirect the user to upon success. If this is correct, that request does not know about the user who generated the original request that made the api request since the request is coming from a completely different origin.
You would need to pass some key along with the url and then obtain the user within orderCreateWebhook. Something like:
Shopify::setShopUrl($shop)->setAccessToken($token)->post("admin/webhooks.json",
['webhook' =>
['topic' => 'orders/create',
'address' => 'https://larashop.domain.com/order-create-webhook/some-unique-key',
'format' => 'json'
]
]);
My suggestion would be to have a unique hash stored somewhere that relates back to the user in your system, perhaps a column in your users table. I wouldn't use the user_id for security reasons. So you would end up with something like:
//route
Route::get('/order-create-webhook/{uniqueKey}', 'YourController#orderCreateWebhook');
//or
Route::post('/order-create-webhook/{uniqueKey}', 'YourController#orderCreateWebhook');
// depending on the request type used by api which calls this endpoint
// controller function
public function orderCreateWebhook($uniqueKey, Request $request)
{
$user = User::where('unique_key', $uniqueKey)->first();
$get_template = Order::where('id', Auth::user()->id);
$baseurl = "https://apps.domain.net/smsapi";
$query = "?key=7e3e4d4a6cfebc08eadc&to=number&msg=message&sender_id=Shopify";
$final_uri = $baseurl.$query;
$response = file_get_contents($final_uri);
header ("Content-Type:text/xml");
}
Is it because it a webhook ?
Yes, you can't use sessions in a webhook. It's the shopify server which is making the call. You should read the doc, it may exist a way to give an unique identifier in your call to shopify api and get it back in the webhook to find your user associated.
just use this to get authenticated user
use the facade in your class/Controller
use Illuminate\Support\Facades\Auth
public function getAuthUser(){
$user = Auth::user()
if(!is_null($user)
{
//user is authenticated
}
else
{
// no user
}
}

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 ));

PHP vTiger Issue creating tickets with vtwsclib

I am trying to figure out how to programmatically create a "HelpDesk" ticket in vTiger using its Web Services api. I am currently using the official vtwsclib v1.5 php library. The log in, appears to succeed and I can also successfully perform a doDescribe on the module, however doCreate returns 'false' no matter what I do. Sample below. Am I missing anything?
$url = 'http://vtiger.mydomain.com/';
$client = new Vtiger_WSClient($url);
$login = $client -> doLogin('systemuser', 'O8nFgnotrealkey');
if (!$login)
echo 'Login Failed';
else {
$module = "HelpDesk";
$record = $client -> doCreate($module, Array(
'assigned_user_id' => "21",
'parent_id' => "91",
'ticket_title' => "test",
'ticketstatus' => "Open"
));
if ($record) {
$recordid = $client -> getRecordId($record['id']);
}
}
Retruns:
$record: bool(false)
Found it:
Looks like if you leave 'assigned_user_id' blank, it will populate it with the correct 'assigned_user_id' for yourself. The 'assigned_user_id' can also be retrieved for your own account from the login response and it appears like this {module_id}x{user_id}. ie: "3x16".
All id's ('parent_id', 'assigned_user_id', 'related_to' etc etc etc) appear to be in a 'NxN' format.

Render a template with a specific status code

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

Categories