We already know how to install the Fatfree framework and prepare for creating the sample from a previous article. The sample that we create in this article is not much different from other Fatfree examples. We need a template file with a form and a controller file to process entered data.
Logic
To get a list of changes we need two documents to compare with the GroupDocs Comparison API. We’ll look at the output document that a comparison creates. Lets take a look at the logic that this sample implements:
A user enter User ID, Private Key and File GUID (from GroupDocs account) into the form.
The entered data is transfered to the controller for processing.
Get entered data.
Check entered data.
Create GroupDocsRequestSigner, APIClient and ComparisonApi objects.
Get all changes from document.
Create a table with a list of changes.
Return this table to the template.
You may think that this logic implies a lot of work, but that’s not so: with GroupDocs PHP SDK it’s very simple. And now, let me show you how.
Implementation
First of all let’s take a look at the complete controller code:
<?php
//<i>This sample will show how to use <b>GetChanges</b> method from ComparisonApi to return a list of changes of a Document</i>
//###Set variables and get POST data
F3::set('userId', '');
F3::set('privateKey', '');
f3::set('result', "");
$clientId = F3::get('POST["client_id"]');
$privateKey = F3::get('POST["private_key"]');
$resultFileId = f3::get('POST["resultFileId"]');
function getChanges($clientId, $privateKey, $resultFileId)
{
//### Check clientId, privateKey and fileGuId
if (empty($clientId) || empty($privateKey) || empty($resultFileId)) {
throw new Exception('Please enter all required parameters');
} else {
//Set variables for Viewer
F3::set('userId', $clientId);
F3::set('privateKey', $privateKey);
//###Create Signer, ApiClient and Storage Api objects
//Create signer object
$signer = new GroupDocsRequestSigner($privateKey);
//Create apiClient object
$apiClient = new APIClient($signer);
//Create ComparisonApi object
$CompareApi = new ComparisonApi($apiClient);
//###Make request to ComparisonApi using user id
//Get changes list for document
$info = $CompareApi->GetChanges($clientId, $resultFileId);
//Check request status
if($info->status == "Ok") {
//###Create table with changes for template
$table = "<table class='border'>";
$table .= "<tr><td><font color='green'>Change Name</font></td><td><font color='green'>Change</font></td></tr>";
//Count of iterations
for($i = 0; $i < count($info->result->changes); $i++) {
//Cycle for the object of the top level
foreach($info->result->changes[$i] as $name => $content){
$table .= "<tr>";
//Check if the current element is an object
if(is_object($content)){
//If object make cycle for the current object
foreach($content as $subName => $subContent) {
$table .= "<tr><td>" . $subName . "</td><td>" . $subContent . "</td></tr>";
}
} elseif(!is_object($content)) {
//Get current element data
$table .= "<td>" . $name . "</td><td>" . $content . "</td>";
$table .= "</tr>";
}
}
$table .= "<tr bgcolor='#808080'><td></td><td></td></tr>";
}
$table .= "</table>";
return f3::set('change', $table);
} else {
throw new Exception($info->error_message);
}
//If request was successful - set url variable for template
// return f3::set('change', $table);
}
}
try {
getChanges($clientId, $privateKey, $resultFileId);
} catch(Exception $e) {
$error = 'ERROR: ' . $e->getMessage() . "\n";
f3::set('error', $error);
}
//Process template
f3::set('resultFileId', $resultFileId);
// f3::set('result', $result);
echo Template::serve('sample.htm');
We will not dwell on how to get POST data from the template and check it – you can find out how to do that from this previous article. To get all changes from the compared document, we need only one method: GetChanges (from the ComparisonApi class). This method take two parameters:
In the query result this method returns a ChangesResponse object that contains all the changes.
Creating a table of changes
To create a table with a list of changes we must use several nested loops and checks. These loops go over all the elements and checks whether each element is an object or not. If an element is an object, the next nested loop for this element runs. As a result of the nested loops we get a table with all the changes were each successive iteration of the main loop is in separate rows. Code for the table creation:
//###Create table with changes for template
$table = "<table class='border'>";
$table .= "<tr><td><font color='green'>Change Name</font></td><td><font color='green'>Change</font></td></tr>";
//Count of iterations
for($i = 0; $i < count($info->result->changes); $i++) {
//Cycle for the object of the top level
foreach($info->result->changes[$i] as $name => $content){
$table .= "<tr>";
//Check if the current element is an object
if(is_object($content)){
//If object make cycle for the current object
foreach($content as $subName => $subContent) {
$table .= "<tr><td>" . $subName . "</td><td>" . $subContent . "</td></tr>";
}
} elseif(!is_object($content)) {
//Get current element data
$table .= "<td>" . $name . "</td><td>" . $content . "</td>";
$table .= "</tr>";
}
}
$table .= "<tr bgcolor='#808080'><td></td><td></td></tr>";
}
$table .= "</table>";
As you can see, we only have two nested loops. This is due to the fact that the ChangesResponse object can’t have more than two-tiered nesting. On the first level, we have all the basic changes, and on the second level, we have info about the rectangle element. Now it is time to return this table to the template.