forrest
forrest copied to clipboard
"format => none" option doesn't work.
I was trying to get "Attachment.Body" as CSV file from Salesforce, but It returned NULL.
The following code is what I wrote then.
$url = 'https://foobar.salesforce.com/services/data/v43.0/sobjects/Attachment/00P5D000002UzJUUA0/body';
$res = Forrest::request($url, ['format' => 'none', 'method' => 'get']);
dd($res); // -> null
I think that the cause is "JsonFormatter" is used in default even though I specified format => none option.
Hi Shintaro
Did you find a fix for this? i'm trying to download and store PDF's and are getting something very similiar
$response = \Forrest::sobjects('Attachment/00PD000001bxAz4MAE/Body', ['format'=> 'none']);
$content = (string) $response->getBody();
I fixed it by overriding UserPassword and adding a method to get a Attachment.Body on Salesforce.
namespace App\Services\Forrest;
use GuzzleHttp\Exception\GuzzleException;
use Omniphx\Forrest\Authentications\UserPassword as BaseUserPassword;
use Psr\Http\Message\ResponseInterface;
/**
* This class is to add a original method by overriding UserPassword class on Forrest.
* @see https://github.com/omniphx/forrest
*/
class UserPassword extends BaseUserPassword
{
/**
* @param string $id Attachment.Id
* @return ResponseInterface
*
* @throws GuzzleException
*/
public function getAttachmentBody($id)
{
$url = $this->getBaseUrl() . sprintf('/sobjects/Attachment/%s/body', $id);
$parameters = [
'headers' => $this->formatter->setHeaders(),
];
$response = $this->httpClient->request("get", $url, $parameters);
$this->event->fire('forrest.response', json_encode([
'url' => $url,
'method' => 'get',
'status_code' => $response->getStatusCode(),
'body_size' => (string)$response->getBody()->getSize()
]));
return $response;
}
}
And overrode forrest in ServiceProvider.
<?php
namespace App\Providers;
use App\Services\Forrest\UserPassword;
use Omniphx\Forrest\Authentications\WebServer;
use Omniphx\Forrest\Formatters\JSONFormatter;
use Omniphx\Forrest\Providers\Laravel\ForrestServiceProvider as BaseServiceProvider;
use Omniphx\Forrest\Providers\Laravel\LaravelEncryptor;
use Omniphx\Forrest\Providers\Laravel\LaravelEvent;
use Omniphx\Forrest\Providers\Laravel\LaravelInput;
use Omniphx\Forrest\Repositories\InstanceURLRepository;
use Omniphx\Forrest\Repositories\RefreshTokenRepository;
use Omniphx\Forrest\Repositories\ResourceRepository;
use Omniphx\Forrest\Repositories\StateRepository;
use Omniphx\Forrest\Repositories\TokenRepository;
use Omniphx\Forrest\Repositories\VersionRepository;
class ForrestServiceProvider extends BaseServiceProvider
{
/**
* Register the service provider.
*
* @return void
*/
public function register()
{
$this->app->singleton('forrest', function ($app) {
// Config options
$settings = config('forrest');
$storageType = config('forrest.storage.type');
$authenticationType = config('forrest.authentication');
// Dependencies
$httpClient = $this->getClient();
$input = new LaravelInput(app('request'));
$event = new LaravelEvent(app('events'));
$encryptor = new LaravelEncryptor(app('encrypter'));
$redirect = $this->getRedirect();
$storage = $this->getStorage($storageType);
$refreshTokenRepo = new RefreshTokenRepository($encryptor, $storage);
$tokenRepo = new TokenRepository($encryptor, $storage);
$resourceRepo = new ResourceRepository($storage);
$versionRepo = new VersionRepository($storage);
$instanceURLRepo = new InstanceURLRepository($tokenRepo, $settings);
$stateRepo = new StateRepository($storage);
$formatter = new JSONFormatter($tokenRepo, $settings);
switch ($authenticationType) {
case 'WebServer':
$forrest = new WebServer(
$httpClient,
$encryptor,
$event,
$input,
$redirect,
$instanceURLRepo,
$refreshTokenRepo,
$resourceRepo,
$stateRepo,
$tokenRepo,
$versionRepo,
$formatter,
$settings);
break;
case 'UserPassword':
$forrest = new UserPassword(
$httpClient,
$encryptor,
$event,
$input,
$redirect,
$instanceURLRepo,
$refreshTokenRepo,
$resourceRepo,
$stateRepo,
$tokenRepo,
$versionRepo,
$formatter,
$settings);
break;
default:
$forrest = new WebServer(
$httpClient,
$encryptor,
$event,
$input,
$redirect,
$instanceURLRepo,
$refreshTokenRepo,
$resourceRepo,
$stateRepo,
$tokenRepo,
$versionRepo,
$formatter,
$settings);
break;
}
return $forrest;
});
}
}
You can get a Attachment.Body like this.
$body = Forrest::getAttachmentBody($attachment.Id);
Thanks @ShintaroNitta
For anyone reading this the final steps are
Update your App.php to reference the new service provider
Omniphx\Forrest\Providers\Laravel\ForrestServiceProvider::class
To
App\Providers\ForrestServiceProvider::class
Then you can dump out raw data using
$content = \Forrest::getAttachmentBody('123123123123');
$content = $content->getBody();
dd($content);
This seems to still be an issue @omniphx , the library doesn't seem to handle binary data coming back from a response.
Hi @omniphx we're planning to dive into a fix for this on the latest version over the next couple of weeks.
If you or anyone else has preference for how it's addressed please let me know. Otherwise, we'll use our best judgement and circle back with a PR once we have something working.
@kaypro4 let me know if you have any questions/need help!
The same approach works for ContentVersion as well for anyone stuck.
public function getContentVersionBody($id)
{
$url = $this->getBaseUrl() . sprintf('/sobjects/ContentVersion/%s/VersionData', $id);
$parameters = [
'headers' => $this->formatter->setHeaders(),
];
$response = $this->httpClient->request("get", $url, $parameters);
$this->event->fire('forrest.response', json_encode([
'url' => $url,
'method' => 'get',
'status_code' => $response->getStatusCode(),
'body_size' => (string)$response->getBody()->getSize()
]));
return $response;
}