By Augusto Goncalves (@augustomaia)
Last week we hosted a DevDay followed by Autodesk Cloud Accelerator in São Paulo, it was an interesting experience: some developers were working with ASP.NET (from their .NET experience), others with Java (server back-end with JBoss) and some with PHP. Quite a diverse environment!
I must say that Java is an old friend that I haven't seeing in a while (since colleague, actually) and PHP I just heard about (never used). So this week, back to regular work, I decided to give PHP a try: they say it's a web language :-)
Let's get started with PHP: first we need a server. After a quick search I found this cool article on how enable PHP on Apache for Mac OS X Yosemite. Couldn't be easier: just uncomment a line to enable PHP5 and restart Apache.
Now what about REST calls? Although cURL is available on PHP, I prefer use a library that wraps the calls in a easy manner. The top search result pointed me to HttpFul PHP Library. Again, couldn't be easier: here is a quick call to Autodesk Authenticate:
$response = \Httpful\Request
::post('https://developer.api.autodesk.com/authentication/v1/authenticate')
->addHeader('Content-Type', 'application/x-www-form-urlencoded')
->body('client_id=Xyz&client_secret=Xyz&grant_type=client_credentials')
->send();
After a few hours learning and writing PHP code, here is the main result: authenticate method that calls the respective Autodesk API. At the code below, check the comments for more details on each line.
Note you need to edit and include your developer key & secret. Also, as the PHP and HTML code are on the same file, the JavaScript call assume the file name as view.and.data.php. The PHP will check the URL and redirect the calls, in this sample, a call to view.and.data.php/authenticate will run the authenticate() method. I'm planing to expand this in the future to include other methods.
<?php
// we need a REST Library, found HttpFul
// Download from http://phphttpclient.com/
// You may need to add permissions for MAC OS with Apache
// sudo chmod -R 755 /library/webserver/documents
// (assuming default folder)
include 'httpful.phar';
// define some constants for this quick sample
define(CONSUMER_KEY, "your key");
define(CONSUMER_SECRET, "your secret");
define(BASE_URL, 'https://developer.api.autodesk.com');
// if the request URL contains the method being requested
// for instance, a call to view.and.data.php/authenticate
// will redirect to the function with the same name
$apiName = explode('/', trim($_SERVER['PATH_INFO'],'/'))[0];
if (!empty($apiName)){
// get the function by API name
try{ $apiFunction = new ReflectionFunction($apiName);}
catch (Exception $e) { echo ('API not found');}
// run the function and 'echo' it's reponse
if ($apiFunction != null) echo $apiFunction->invoke();
exit(); // no HTML output
}
// now the APIs
function authenticate(){
// request body (client key & secret)
$body = sprintf('client_id=%s' .
'&client_secret=%s' .
'&grant_type=client_credentials',
CONSUMER_KEY, CONSUMER_SECRET);
// prepare a POST request following the documentation
$response =
\Httpful\Request::post(
BASE_URL . '/authentication/v1/authenticate')
->addHeader('Content-Type', 'application/x-www-form-urlencoded')
->body($body)
->send(); // make the request
if ( $response->code == 200)
// access the JSON response directly
return $response->body->access_token;
else
// something went wrong...
throw new Exception('Cannot authenticate');
}
?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Minimum PHP View and Data Sample</title>
<link type="text/css" rel="stylesheet" href="https://developer.api.autodesk.com/viewingservice/v1/viewers/style.css" />
</head>
<script src="https://developer.api.autodesk.com/viewingservice/v1/viewers/viewer3D.min.js?v=1.2.23"></script>
<script>
// This is the basic JavaScript sample code available at the documentation
// It's optimized for 3D models and slightly adjusted for this case
// Show the model specified on the URN parameter
function showModel() {
var options = {
'document': 'urn:' + document.getElementById('modelURN').value,
'env': 'AutodeskProduction',
'getAccessToken': getToken,
'refreshToken': getToken,
};
var viewerElement = document.getElementById('viewer');
var viewer = new Autodesk.Viewing.Viewer3D(viewerElement, {});
Autodesk.Viewing.Initializer(
options,
function () {
viewer.initialize();
loadDocument(viewer, options.document);
}
);
}
// Load the document (urn) on the view object
function loadDocument(viewer, documentId) {
// Find the first 3d geometry and load that.
Autodesk.Viewing.Document.load(
documentId,
function (doc) { // onLoadCallback
var geometryItems = [];
geometryItems = Autodesk.Viewing.Document.getSubItemsWithProperties(doc.getRootItem(), {
'type': 'geometry',
'role': '3d'
}, true);
if (geometryItems.length > 0) {
viewer.load(doc.getViewablePath(geometryItems[0]));
}
},
function (errorMsg) { // onErrorCallback
alert("Load Error: " + errorMsg);
}
);
}
// This calls are required if the models stays open for a long time and the token expires
function getToken() {
return makePOSTSyncRequest("view.and.data.php/authenticate");
}
function makePOSTSyncRequest(url) {
var xmlHttp = null;
xmlHttp = new XMLHttpRequest();
xmlHttp.open("POST", url, false);
xmlHttp.send(null);
return xmlHttp.responseText;
}
</script>
<body>
<div>This is a minimum sample in PHP5.
<br /> First edit this file and enter your consumer key and consumer secret. Request at <a href="http://forge.autodesk.com">Forge portal</a>.
<br /> To use this sample you need a model URN. Please upload a model at <a href="http://models.autodesk.io">Models.Autodesk.IO</a></div>
<hr />
<div>
Specify a model URN:
<input type="text" id="modelURN" />
<input type="button" value="View model" onclick="showModel()">
</div>
<hr />
<div id="viewer">
</div>
</body>
</html>