1
votes

So after a bit of struggle to get the authentication working with graph.microsoft.com i can now read the sharepoint sites and lists.

I can also read the drives and i managed to create a folder and file in the teamsite with REST calls, go me!. The problem is that although i can "create a file" and it shows up on my.sharepoint.com it has 0 content length.

I used this page to guide me through it: https://developer.microsoft.com/en-us/graph/docs/api-reference/beta/api/listitem_create

The code i used to create a file is as follows

  $currentFile = new File($file);
  $contents = $currentFile->read();
  $currentFile->close();

  $url = 'https://graph.microsoft.com/beta/sharePoint/site/drives/'.$this->driveId.'/'.$location.'/items/'.$parent_id.'/children';

  $tempData = $this->Controller->Temp->read('Office');
  $headers = array('Authorization' => 'Bearer '.$tempData['token']['access_token'], 'Content-Type' => 'application/json');
  $data = json_encode(array('name' => basename($file), 'file' => new stdClass()));

  $sckt = new HttpSocket(array('ssl_verify_host' => false));
  $apiData = $sckt->post($url, $data, array('header' => $headers));

You are right to see i am not sending the $contents var allong with the json request because this will break the request. And i started doing some digging around and saw that in the OneDrive section the file contents is send as a binary formatted string through json

So i tried putting 'content' => $blob (i am guesing im supposed to use content here) in the json array, but i just get "malformed request". I also tried to post as text/plain but it only accepts json requests. Form/multipart also didn't work so i've been trying al sorts of options and array keys but nothing seems to get my file contents to sharepoint.

I also tried the same with "Columnset" (https://developer.microsoft.com/en-us/graph/docs/api-reference/beta/api/listitem_update).

So in summary: I can now make a file, make a folder, change it, update and create meta data, change the names. But i can't get the file contents uploaded!!!

At the moment i'm hoping it's just something stupid i'm not seeing, so you can laugh at me and give me some awesome advise after you're done laughing ofc. Because i get the feeling it's not something that works in the beta yet which would be kinda weird.

3

3 Answers

1
votes

So after many trials and errors and some reading i found that i'm kinda dumb but t.b.h. the documentation is not very helpfull on this and very lacking but it is in beta so yeah...

The answer was quite easy once you figure it out. The way to upload or create a file on sharepoint with the graph.microsoft.com REST api is that you have to create a 0 size file holder first as shown above. Then use code below the upload/apply the file contents.

Notice the /content part in the url.

  $currentFile = new File($file);
  $contents = $currentFile->read();
  $currentFile->close();

  $url = 'https://graph.microsoft.com/beta/sharePoint/site/drives/'.$this->driveId.'/items/'.$parent_id.'/children/'.basename($file).'/content';

  $tempData = $this->Controller->Temp->read('Office');
  $headers = array('Authorization' => 'Bearer '.$tempData['token']['access_token'], 'Content-Length' => strlen($contents),  'Content-Type' => 'text/plain');

  $sckt = new HttpSocket(array('ssl_verify_host' => false));
  $apiData = $sckt->put($url, $contents, array('header' => $headers));

And now it does accept a text/plain request as input !

Hope this helps someone else :)

1
votes

It turns out you need to add a colon after the filename and it should work.

$url = 'https://graph.microsoft.com/beta/sharePoint/site/drives/'.$this->driveId.'/items/'.$parent_id.'/children/'.basename($file).':/content';
0
votes

Few tweaks needed. In headers make sure to include Content-Length via $contents.strlen in headers. Set Content-Type to text/plain, and lastly the body of the post should be $contents.