msgraph-sdk-php icon indicating copy to clipboard operation
msgraph-sdk-php copied to clipboard

How to use range-update API with Microsoft Graph PHP SDK?

Open MarkDaleman opened this issue 9 months ago • 2 comments

Hello humans of the earth,

I'm trying to figure out how to use the range-update API with the Microsoft Graph PHP SDK. I want to update the value of a specific cell in an Excel worksheet, but I’m not sure how to properly construct the request using the SDK.

What I've tried:

  • I attempted using WorkbookWorksheetItemRequestBuilder::rangeWithAddress() to target the cell, but there doesn’t seem to be a clear method to perform the PATCH with the updated value.
  • Using WorkbookRange directly is challenging since it lacks a setValues() method or any way to set cell content.
  • I tried using RequestInformation::setContentFromParsable(), but it throws a type error since it expects a Parsable object, not a simple array.

What I’m looking for:

  • A recommended way to use the SDK to perform the range-update without manually crafting the HTTP request.
  • If there’s no current method, is there a workaround using the SDK’s RequestAdapter that adheres to best practices?

MarkDaleman avatar Feb 21 '25 15:02 MarkDaleman

@MarkDaleman I don't know if it's best practice, but here's the workaround that I used with version 2.27 of the SDK:

// URL-encode the range address to ensure special characters are handled
$encodedRangeAddress = rawurlencode($rangeAddress);
$requestAdapter = $this->client->getRequestAdapter();
$requestUrl = $requestAdapter->getBaseUrl()
    . "/drives/{$driveId}/items/{$fileId}/workbook/worksheets/{$worksheetId}/range(address='{$encodedRangeAddress}')";

// Create a RequestInformation instance.
$requestInfo = new RequestInformation();
$requestInfo->httpMethod = HttpMethod::PATCH;
$requestInfo->urlTemplate = $requestUrl;
$jsonData = json_encode($data);
// Convert JSON string to a PSR-7 stream using Guzzle's utility function.
$requestInfo->content = \GuzzleHttp\Psr7\Utils::streamFor($jsonData);

// Ensure the Content-Type header is set.
$requestInfo->addHeader("Content-Type", "application/json");
// If a session exists, use it to improve performance
if (!empty($this->workbookSessionId)) {
    $requestInfo->addHeader('workbook-session-id', $this->workbookSessionId);
}

try {
    // Make the request and wait
    $requestAdapter->sendNoContentAsync($requestInfo)->wait();
} catch (ODataError $e) {
    // Handle the error
}

snake14 avatar Feb 26 '25 01:02 snake14

Hello @snake14,

Your code example nudged me in the right direction:

/**
 * @throws \Exception
 */
public function updateCellAtPosition(string $address, WorkbookRange $payload, string $sheetId, string $documentId): WorkbookRange
{
    $requestInfo = new RequestInformation();
    // This is probably the way - since no one can give me the answer: https://github.com/microsoftgraph/msgraph-sdk-php/issues/1649
    $requestInfo->urlTemplate = '{+baseurl}/drives/{driveId}/items/{itemId}/workbook/worksheets/{worksheetId}/range(address=\'{cellToUpdate}\')';
    $requestInfo->pathParameters = [
        'driveId' => $this->getDriveId(),
        'itemId' => $documentId,
        'worksheetId' => $sheetId,
        'cellToUpdate' => $address,
    ];
    $requestInfo->httpMethod = HttpMethod::PATCH;
    $requestInfo->setContentFromParsable(
        $this->client->getRequestAdapter(),
        'application/json',
        $payload,
    );
    $errorMappings = [
        '4XX' => [ODataError::class, 'createFromDiscriminatorValue'],
        '5XX' => [ODataError::class, 'createFromDiscriminatorValue'],
    ];
    return $this->client->getRequestAdapter()->sendAsync(
        $requestInfo,
        [WorkbookRange::class, 'createFromDiscriminatorValue'],
        $errorMappings
    )->wait();
}

This works just fine! It would be nice to use the SDK, but for now, this will suffice.

MarkDaleman avatar Feb 26 '25 09:02 MarkDaleman