How to upload, remove and download files from Microsoft SharePoint using MS Graph API in Laravel
In this post, you will be learning how to upload a file to Microsoft SharePoint, how to remove or delete a file from Microsoft SharePoint, how to download a file from Microsoft SharePoint using Microsoft Graph API.
Before we dive into the code, you need to ensure you have the following prerequisites:
The File upload, remove and download are managed from the root directory/folder of Microsoft SharePoint.
Step 1: Create a controller named FileUploadController.php and paste the below code
<?php
namespace App\Http\Controllers\Api\V1;
use App\Models\FileDetail;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Auth;
use App\Services\MicrosoftGraphService;
class FileUploadController extends Controller
{
public function store(Request $request)
{
if(MicrosoftGraphService::sharepointFileUploadEnabledCheck())
{
if($request->hasFile('file')) {
$file = $request->file('file');
$user = Auth::user();
$uploadResponse = MicrosoftGraphService::uploadFileToSharepoint($file, $user->msAccessToken->access_token);
if ($uploadResponse['status_code'] == 201) {
FileDetail::create([
'download_url' => $uploadResponse['download_url'],
'web_url' => $uploadResponse['web_url'],
'file_type' => $uploadResponse['file_type'],
'storage_location' => $uploadResponse['storage_location'],
]);
} else {
return response()->json([
'error' => $uploadResponse['error'],
'details' => $uploadResponse['details']
], $uploadResponse['status_code']);
}
}
}
else
{
return response()->json([
'message' => 'Access token not found',
],401);
}
}
public function update(Request $request, $fileUploadId)
{
$fileDetail = FileDetail::where('id',$fileUploadId)->first();
if(MicrosoftGraphService::sharepointFileUploadEnabledCheck())
{
if($request->hasFile('file')) {
//Lets remove the Old file
if($fileDetail->storage_location == 'sharepoint'){
$queryString = parse_url($fileDetail->download_url, PHP_URL_QUERY);
parse_str($queryString, $queryParams); // Parse the query string into an array
$uniqueId = $queryParams['UniqueId'] ?? null; // Return the UniqueId if it exists
if($uniqueId){
$user = Auth::user();
MicrosoftGraphService::removeFileFromSharepoint($uniqueId, $user->msAccessToken->access_token);
}
}
//Lets upload with the New file
$file = $request->file('file');
$user = Auth::user();
$uploadResponse = MicrosoftGraphService::uploadFileToSharepoint($file, $user->msAccessToken->access_token);
if ($uploadResponse['status_code'] == 201) {
FileDetail::where('id',$fileDetail->id)->update([
'download_url' => $uploadResponse['download_url'],
'web_url' => $uploadResponse['web_url'],
'file_type' => $uploadResponse['file_type'],
'storage_location' => $uploadResponse['storage_location'],
]);
} else {
return response()->json([
'error' => $uploadResponse['error'],
'details' => $uploadResponse['details']
], $uploadResponse['status_code']);
}
}
}
else
{
return response()->json([
'message' => 'Access token not found',
],401);
}
}
public function destroy($fileUploadId)
{
$fileDetail = FileDetail::where('id',$fileUploadId)->first();
try{
if($fileDetail->storage_location == 'sharepoint'){
if(MicrosoftGraphService::sharepointFileUploadEnabledCheck())
{
$queryString = parse_url($fileDetail->download_url, PHP_URL_QUERY);
parse_str($queryString, $queryParams); // Parse the query string into an array
$uniqueId = $queryParams['UniqueId'] ?? null; // Return the UniqueId if it exists
if($uniqueId){
$user = Auth::user();
MicrosoftGraphService::removeFileFromSharepoint($uniqueId, $user->msAccessToken->access_token);
}
}
else
{
return response()->json([
'message' => 'Access token not found',
],401);
}
}
$fileDetail->delete();
return response()->json([
'message' => 'File deleted successfully'
], 200);
}catch (\Exception $ex){
return response()->json([
'code' => 500,
'message' => 'Something Went Wrong... Please try again',
'status' => 'error',
'error' => $ex->getMessage()
], 500);
}
}
public function downloadFile($fileUploadId)
{
$fileDetail = FileDetail::where('id',$fileUploadId)->first();
if ($fileDetail) {
if($fileDetail->storage_location == 'sharepoint'){
if(MicrosoftGraphService::sharepointFileUploadEnabledCheck())
{
$user = Auth::user();
$downloadResponse = MicrosoftGraphService::downloadFileFromSharepoint($fileDetail->download_url, $user->msAccessToken->access_token);
if($downloadResponse['status_code'] == 200){
return response($downloadResponse['fileContent'], 200)
->header('Content-Type', $downloadResponse['mimeType'])
->header('Content-Disposition', 'attachment; filename="' . basename($fileDetail->download_url) . '"');
}else{
return response()->json($downloadResponse, $downloadResponse['status_code']);
}
} else {
return response()->json([
'message' => 'Access token not found',
],401);
}
}
}else{
return response()->json([
'code' => 404,
'message' => 'No File detail found',
], 404);
}
}
}
Step 2: Create a Service file in following path: app\Services\MicrosoftGraphService.php and paste the below code
<?php
namespace App\Services;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Http;
use GuzzleHttp\Client;
class MicrosoftGraphService
{
public static function uploadFileToSharepoint($file, $msAccessToken)
{
$filePath = $file->getPathname();
$fileName = $file->getClientOriginalName();
$fileType = $file->getClientOriginalExtension();
$fileMimeType = $file->getMimeType();
$fileContent = file_get_contents($filePath);
$client = new Client();
$response = $client->request('PUT', "https://graph.microsoft.com/v1.0/sites/root/drive/root:/{$fileName}:/content", [
'headers' => [
'Authorization' => 'Bearer ' . $msAccessToken,
'Content-Type' => $fileMimeType,
],
'body' => $fileContent,
]);
$responseBody = $response->getBody()->getContents();
if ($response->getStatusCode() == 201) {
$responseData = json_decode($responseBody, true);
$webUrl = $responseData['webUrl'] ?? 'URL not available'; //To view the File on Browser via link
/**
* This is the "@microsoft.graph.downloadUrl" (Download_URL) to download any type of file from Sharepoint.
* Note: In this "@microsoft.graph.downloadUrl", you will have many parameters, but "UniqueId" parameter can be used to delete this file.
*/
$downloadUrl = $responseData['@microsoft.graph.downloadUrl'];
return [
'download_url' => $downloadUrl,
'web_url' => $webUrl,
'file_type' => $fileType,
'storage_location' => 'sharepoint',
// 'details' => $responseData,
'stauts_code' => $response->getStatusCode(),
];
} else {
return [
'error' => 'Failed to upload file',
'details' => $responseBody,
'stauts_code' => $response->getStatusCode(),
];
}
}
/**
*
* The "UniqueId" is extracted from "@microsoft.graph.downloadUrl" (Download URL) which is a parameter.
* This parameter "UniqueId" is used for deleting the File from sharepoint.
*/
public static function removeFileFromSharepoint($uniqueId, $msAccessToken)
{
$response = Http::withHeaders([
'Authorization' => 'Bearer ' . $msAccessToken,
])->delete("https://graph.microsoft.com/v1.0/sites/root/drive/items/{$uniqueId}");
if ($response->successful()) {
return [
'message' => 'File deleted successfully!',
'status' => 'success',
'status_code' => $response->status(),
];
} else {
$errorResponse = $response->json();
return [
'message' => 'Failed to delete the file.',
'status' => 'error',
'error' => $errorResponse,
'status_code' => $response->status(),
];
}
}
public static function downloadFileFromSharepoint($downloadLink, $msAccessToken)
{
$client = new Client();
try {
$response = $client->request('GET', $downloadLink, [
'headers' => [
'Authorization' => 'Bearer ' . $msAccessToken,
],
]);
if ($response->getStatusCode() === 200) {
$fileContent = $response->getBody()->getContents();
$mimeType = $response->getHeaderLine('Content-Type');
return [
'fileContent' => $fileContent,
'mimeType' => $mimeType,
'status_code' => 200
];
} else {
$errorResponse = $response->getBody()->getContents();
return [
'message' => 'Failed to download file from SharePoint.',
'error' => $errorResponse,
'status' => 'error',
'status_code' => $response->getStatusCode(),
];
}
} catch (\Exception $e) {
return [
'message' => 'An error occurred while attempting to download the file.',
'error' => $e->getMessage(),
'status' => 'error',
'status_code' => 500
];
}
}
/**
* checking if has token and also file-upload to sharepoint is enabled.
* You can enable from : http://localhost:3000/settings/email/configuration
*/
public static function sharepointFileUploadEnabledCheck()
{
$user = Auth::user();
if($user->msAccessToken && $user->msAccessToken->is_file_upload_enabled){
return true;
}else{
return false;
}
}
}
?>
Step 3: Create a Model related to your requirement. So as I have used in this code its FileDetail.php
php artisan make:model FileDetail -m
with the above command, you will be able to create the Model & Migration file both.
So as per your requirements, please add your fields.
Thanks for reading.