25 Aug 2017

Basic usage for Forge SDK (PHP)

Default blog image

Various language specific Forge SDKs has been released in the past few months such as Java, node.js, Ruby, VB.NET, C# and also PHP, see here for more detail. Except for the PHP, most language specific Forge SDKs have simple guidances and example projects for showing how to use it in the real projects. A few customers asked me to provide some example for using the PHP version SDK, forge-php-client, so I decided to write this blog to demonstrate it in the simplest way.

This example will go through a very simplest Forge workflow to show the basic usage of the forge-php-client, but won't tell every APIs of the Forge and the contents of the SDK:

  1. Get access token ( Use OAuth API )
  2. Create bucket ( Use Data Management API )
  3. Upload file/object to bucket ( Use Data Management API )
  4. Request translation ( Use Model Derivative API )
  5. Check translation status ( Use Model Derivative API )

For Step #1

Before using the Forge platform APIs, we must retrieve an access token with corresponding permissions (scopes). Here is the sample for obtaining an access token from the OAuth API:

require_once( '../vendor/autoload.php' );

Autodesk\Auth\Configuration::getDefaultConfiguration()
   ->setClientId( '<your-client-id>' )
   ->setClientSecret( '<your-client-secret>' );

$twoLeggedAuth = new Autodesk\Auth\OAuth2\TwoLeggedAuth();
$twoLeggedAuth->setScopes( [ 'bucket:read' ] );    //!<< This is dependent on what API you want to call.

$twoLeggedAuth->fetchToken();

$tokenInfo = [
   'accessToken' => $twoLeggedAuth->getAccessToken(),
   'expiry'           => time() + $twoLeggedAuth->getExpiresIn(),
];

print_r( $tokenInfo );

For Step #2

After retrieving access token, we can access Forge APIs to create buckets, upload files and do the model translation. Now, before upload files/objects to the Data Management API, we must have to create a bucket of the Forge OSS (Object Storage Service) to store our files/objects firstly. For the API detail, please refer POST buckets and OSS Retention Policy.

$twoLeggedAuth->setScopes( [ 'bucket:create' ] );
$twoLeggedAuth->fetchToken();

$apiInstance = new Autodesk\Forge\Client\Api\BucketsApi( $twoLeggedAuth );

$bucket_info = array(
  'bucket_key' => 'adsk-forge-sdk-php-demo' . time(),  //!<< Your bucket name which should be unique globally on the Forge Server
  'policy_key' => 'transient'  //!<< Bucket type that affects when stored files will be deleted from the bucket.
);
$post_buckets = new \Autodesk\Forge\Client\Model\PostBucketsPayload( $bucket_info );

try {
  $result = $apiInstance->createBucket( $post_buckets, null );

  print_r( $result );  //!<< Print bucket creation response from the Data Management API.
} catch (Exception $e) {
  echo 'Exception when calling BucketsApi->createBucket: ', $e->getMessage(), PHP_EOL;
}

For Step #3

Now we can upload files/objects to the bucket created from the step #2 via the PUT buckets/:bucketKey/objects/:objectName of the Data Management API.

$twoLeggedAuth = new Autodesk\Auth\OAuth2\TwoLeggedAuth();
$twoLeggedAuth->setScopes( [ 'data:write' ] );

$twoLeggedAuth->fetchToken();

$apiInstance = new Autodesk\Forge\Client\Api\ObjectsApi( $twoLeggedAuth );
$bucket_key = 'adsk-forge-sdk-php-demo1503716788';  //!<< The BucketKey of the bukcet where files/objects will be uploaded to.
$filename = './models/HouseTest.rvt'; //!<< File/Object to be uploaded
$body = $filename;
$file = new SplFileObject( $body );
$content_length = $file->getSize();   //!<< Indicates the size of the request body.
$object_name = $file->getFilename();  //!<< URL-encoded object name

try {
    $result = $apiInstance->uploadObject( $bucket_key, $object_name, $content_length, $body, null, null );

    print_r( $result );  //!<< Print file/object upload response from the Data Management API.
} catch( Exception $e ) {
    echo 'Exception when calling ObjectsApi->uploadObject: ', $e->getMessage(), PHP_EOL;
}

But there is an issue on the uploadObject method, we will face an error 504. To fix this issue, there is a workaround to change line #196 of the forge-php-client/lib/ApiClient.php.

//From:
curl_setopt( $curl, CURLOPT_POSTFIELDS, $postData );

//To:
curl_setopt( $curl, CURLOPT_POSTFIELDS, file_get_contents( $postData ) );

For Step #4

Now our file/object is uploaded to the bucket. Before sending the translation job, we have to encode the objectId to the Base64 format.

//From (URN):
urn:adsk.objects:os.object:adsk-forge-sdk-php-demo1503716788/HouseTest.rvt

//To (Base64EncodedURN):
dXJuOmFkc2sub2JqZWN0czpvcy5vYmplY3Q6YWRzay1mb3JnZS1zZGstcGhwLWRlbW8xNTAzNzE2Nzg4L0hvdXNlVGVzdC5ydnQ

To encode URN in PHP, we can do something like this:

$urn = 'urn:adsk.objects:os.object:adsk-forge-sdk-php-demo1503716788/HouseTest.rvt';

// URL safe encoding, ref: http://php.net/manual/en/function.base64-encode.php#103849
$base64Urn = rtrim( strtr( base64_encode( $urn ), '+/', '-_' ), '=' );

After obtaining the base64Urn, we can send a translation job request to the Model Derivative API via the POST job.

$twoLeggedAuth->setScopes( [ 'data:read', 'data:write' ] );
$twoLeggedAuth->fetchToken();

$apiInstance = new Autodesk\Forge\Client\Api\DerivativesApi( $twoLeggedAuth );

$jobInput = array(
  'urn' => 'dXJuOmFkc2sub2JqZWN0czpvcy5vYmplY3Q6YWRzay1mb3JnZS1zZGstcGhwLWRlbW8xNTAzNzE2Nzg4L0hvdXNlVGVzdC5ydnQ'
);
$jobPayloadInput = new Autodesk\Forge\Client\Model\JobPayloadInput( $jobInput );

$jobOutputItem = array(
  'type' => 'svf',
  'views' => array( '2d', '3d' )
);
$jobPayloadItem = new Autodesk\Forge\Client\Model\JobPayloadItem( $jobOutputItem );

$jobOutput = [
  'formats' => array( $jobPayloadItem )
];
$jobPayloadOutput = new Autodesk\Forge\Client\Model\JobPayloadOutput( $jobOutput );

$job = new \Autodesk\Forge\Client\Model\JobPayload();
$job->setInput( $jobPayloadInput );
$job->setOutput( $jobPayloadOutput );
$x_ads_force = false;   //!<<`true`: the endpoint replaces previously translated output file types with the newly generated derivatives,  `false` (default): previously created derivatives are not replaced

try {
    $result = $apiInstance->translate( $job, $x_ads_force );

    print_r( $result );  //!<< Print job request response from the Model Derivative API.
} catch( Exception $e ) {
    echo 'Exception when calling DerivativesApi->translate: ', $e->getMessage(), PHP_EOL;
}

For Step #5

After sending the translation job, we can check the translation status via the GET :urn/manifest of the Model Derivative API.

$twoLeggedAuth->setScopes( [ 'data:read' ] );
$twoLeggedAuth->fetchToken();

$apiInstance = new Autodesk\Forge\Client\Api\DerivativesApi( $twoLeggedAuth );
$base64Urn = 'dXJuOmFkc2sub2JqZWN0czpvcy5vYmplY3Q6YWRzay1mb3JnZS1zZGstcGhwLWRlbW8xNTAzNzE2Nzg4L0hvdXNlVGVzdC5ydnQ';

try {
  $result = $apiInstance->getManifest( $base64Urn, null );

  print_r( $result );  //!<< Print translation status from the Model Derivative API.
  echo 'Translation Status: ' . $result['status'];
  echo "\t\nTranslation Progress: " . $result['progress'];
} catch( Exception $e ) {
  echo 'Exception when calling DerivativesApi->getManifest: ', $e->getMessage(), PHP_EOL;
}

 

Related Article