-
Notifications
You must be signed in to change notification settings - Fork 50
Description
Attempting to update multiple ZohoBooks "Item" records with the "update" method quickly leads to API rate limits.
Using a PUT to the bare "/items" with a JSON object of many Item records will update them all with a single API call. The reply data is a JSON array with single top-level array of "items" with each record being the full updated individual Item and also the response "Code" and "Message" that would normally be returned from a single Item's update/PUT call.
While this ZohoBooksApi module allows to send an update to the bare "/items" by providing "null" as the id to the ->update() method (which in turns sends it to ->put()), the current release does not properly handle the resulting data response from the Zoho API.
Two issues presented:
- Client.php - processResult() function does not have a case to handle a valid JSON response without a "Code" and "Message" at the top level, and
- Module.php - update() function is only set up to handle and return a single Model Item from make()
To resolve for immediate use I modified code as follows:
- processResult() in Client.php to accept the case where the data returned is a JSON object but does not have a top-level "Code" field.
if (!$result) {
// All ok, probably not json, like PDF?
if ($response->getStatusCode() >= 200 && $response->getStatusCode() <= 299) {
return (string)$response->getBody();
}
throw new ErrorResponseException($response->getReasonPhrase(), $response->getStatusCode());
}
if (isset($result['code']))
{
if ($result['code'] != 0)
{
throw new ErrorResponseException('Response from Zoho is not success. Message: ' . $result['message'], $result['code'] ?? $response->getStatusCode());
} else
{
// All OK
return $result;
}
}
// All OK, JSON and likely bulk update with individual response codes
return $result;
}
- update() in Module.php to test for a "null" $id, and if so to just return the decoded JSON array.
public function update($id, $data, $params = [])
{
$data = $this->client->put($this->getUrl(), $id, $data, $params);
if ($id != null)
{
// Updated single object
$data = $data[$this->inflector->singularize($this->getResourceItemKey())];
return $this->make($data);
} else
{
// Updated muliple objects, return collection
// case for bulk ie. update PUT to /items
// body is top level of module name i.e. 'items'
// array of each object that was submitted, 'code' and 'message' is in each sub object
return $data[$this->getResourceKey()];
}
}
Would it be more desirable to create another Module method such as updateMany() instead of passing in a null id?
Are there consequences or other cases where processResult() shouldn't just return the JSON data object?