DocumentServer/OnlineEditorsExample/OnlineEditorsExamplePHP/functions.php
2015-04-29 19:10:50 +03:00

467 lines
15 KiB
PHP

<?php
require_once( dirname(__FILE__) . '/config.php' );
require_once( dirname(__FILE__) . '/common.php' );
function servConvGetKey() {
if (defined('ServiceConverterTenantId'))
return ServiceConverterTenantId;
return "OnlyOfficeAppsExample";
}
function servConvGetSKey() {
if (defined('ServiceConverterKey'))
return ServiceConverterKey;
return "ONLYOFFICE";
}
function HaveExternalIP() {
$_haveExternalIPCacheFile = "cache/haveExternalIP.txt";
$_cacheTimeSeconds = 1 * 60 * 60; // cache for 1 hour
$_haveExternalIPObj = unserialize(file_get_contents($_haveExternalIPCacheFile));
if (!(isset($_haveExternalIPObj) &&
is_array($_haveExternalIPObj) &&
isset($_haveExternalIPObj['haveExternalIP']) &&
isset($_haveExternalIPObj['updDate']) &&
is_bool($_haveExternalIPObj['haveExternalIP']) &&
is_int($_haveExternalIPObj['updDate']) &&
$_haveExternalIPObj['updDate'] + $_cacheTimeSeconds >= time()))
{
$convertUri = "";
try
{
$demoName = "demo.docx";
$fileUri = getVirtualPath() . $demoName;
if (!file_exists($fileUri)){
if(!@copy(dirname(__FILE__) . DIRECTORY_SEPARATOR . "app_data" . DIRECTORY_SEPARATOR . $demoName, getStoragePath($demoName)))
{
$errors= error_get_last();
$err = "Copy demo file error: " . $errors['type'] . "\r\n".$errors['message'];
sendlog("HaveExternalIP errors: " . $err, "logs/common.log");
throw new Exception($err);
} else {
GetConvertedUri($fileUri, "docx", "docx", guid(), FALSE, $convertUri);
}
}
}
catch (Exception $e) {
$convertUri = "";
}
$_haveExternalIPObj = array(
'haveExternalIP' => ($convertUri != ""),
'updDate' => time()
);
file_put_contents($_haveExternalIPCacheFile, serialize($_haveExternalIPObj));
}
return $_haveExternalIPObj['haveExternalIP'];
}
function FileUri($file_name) {
$uri = getVirtualPath() . $file_name;
if (HaveExternalIP()) {
return $uri;
}
return GetExternalFileUri($uri);
}
function GetExternalFileUri($local_uri) {
$externalUri = '';
try
{
$documentRevisionId = GenerateRevisionId($local_uri);
if (($fileContents = file_get_contents(str_replace(" ","%20", $local_uri)))===FALSE){
throw new Exception("Bad Request");
} else {
$contentType = mime_content_type($local_uri);
$validateKey = GenerateValidateKey($documentRevisionId, false);
$urlToService = generateUrlToStorage('', '', '', '', $documentRevisionId, $validateKey);
$opts = array('http' => array(
'method' => 'POST',
'header' => "User-Agent: " . $_SERVER['HTTP_USER_AGENT'] . "\r\n" .
"Content-Type: " . $contentType . "\r\n" .
"Content-Length: " . strlen($fileContents) . "\r\n",
'content' => $fileContents,
'timeout' => $GLOBALS['DOC_SERV_TIMEOUT']
)
);
if (substr($urlToService, 0, strlen("https")) === "https") {
$opts['ssl'] = array( 'verify_peer' => FALSE );
}
$context = stream_context_create($opts);
if (($response_data = file_get_contents($urlToService, FALSE, $context))===FALSE){
throw new Exception ("Could not get an answer");
} else {
sendlog("GetExternalUri response_data:" . PHP_EOL . $response_data, "logs/common.log");
GetResponseUri($response_data, $externalUri);
}
sendlog("GetExternalFileUri. externalUri = " . $externalUri, "logs/common.log");
return $externalUri . "";
}
}
catch (Exception $e)
{
sendlog("GetExternalFileUri Exception: " . $e->getMessage(), "logs/common.log");
}
return $local_uri;
}
function DoUpload($fileUri) {
$_fileName = GetCorrectName($fileUri);
$ext = strtolower('.' . pathinfo($_fileName, PATHINFO_EXTENSION));
if (!in_array($ext, getFileExts()))
{
throw new Exception("File type is not supported");
}
if(!@copy($fileUri, getStoragePath($_fileName)))
{
$errors= error_get_last();
$err = "Copy file error: " . $errors['type'] . "<br />\n" . $errors['message'];
throw new Exception($err);
}
return $_fileName;
}
function generateUrlToConverter($document_uri, $from_extension, $to_extension, $title, $document_revision_id, $validateKey, $is_async) {
$urlToConverterParams = array(
"url" => $document_uri,
"outputtype" => trim($to_extension,'.'),
"filetype" => trim($from_extension, '.'),
"title" => $title,
"key" => $document_revision_id,
"vkey" => $validateKey);
$urlToConverter = $GLOBALS['DOC_SERV_CONVERTER_URL'] . "?" . http_build_query($urlToConverterParams);
if ($is_async)
$urlToConverter = $urlToConverter . "&async=true";
return $urlToConverter;
}
function generateUrlToStorage($document_uri, $from_extension, $to_extension, $title, $document_revision_id, $validateKey) {
return $GLOBALS['DOC_SERV_STORAGE_URL'] . "?" . http_build_query(
array(
"url" => $document_uri,
"outputtype" => trim($to_extension,'.'),
"filetype" => trim($from_extension, '.'),
"title" => $title,
"key" => $document_revision_id,
"vkey" => $validateKey));
}
/**
* Encoding string from object
*
* @param object $primary_key Json of primary key
* @param string $secret Secret key for encoding
*
* @return Encoding string
*/
function signature_Create($primary_key, $secret) {
$payload = base64_encode( hash( 'sha256', ($primary_key . $secret), true ) ) . "?" . $primary_key;
$base64Str = base64_encode($payload);
$ind = 0;
for ($n = strlen($base64Str); $n > 0; $n--){
if ($base64Str[$n-1] === '='){
$ind++;
} else {
break;
}
}
$base64Str = str_replace(array('+', '/'), array('-', '_'), trim($base64Str, '==')) . $ind;
return urlencode($base64Str);
}
/**
* Generate an error code table
*
* @param string $errorCode Error code
*
* @return null
*/
function ProcessConvServResponceError($errorCode) {
$errorMessageTemplate = "Error occurred in the document service: ";
$errorMessage = '';
switch ($errorCode)
{
case -8:
$errorMessage = $errorMessageTemplate . "Error document VKey";
break;
case -7:
$errorMessage = $errorMessageTemplate . "Error document request";
break;
case -6:
$errorMessage = $errorMessageTemplate . "Error database";
break;
case -5:
$errorMessage = $errorMessageTemplate . "Error unexpected guid";
break;
case -4:
$errorMessage = $errorMessageTemplate . "Error download error";
break;
case -3:
$errorMessage = $errorMessageTemplate . "Error convertation error";
break;
case -2:
$errorMessage = $errorMessageTemplate . "Error convertation timeout";
break;
case -1:
$errorMessage = $errorMessageTemplate . "Error convertation unknown";
break;
case 0:
break;
default:
$errorMessage = $errorMessageTemplate . "ErrorCode = " . $errorCode;
break;
}
throw new Exception($errorMessage);
}
/**
* Translation key to a supported form.
*
* @param string $expected_key Expected key
*
* @return Supported key
*/
function GenerateRevisionId($expected_key) {
if (strlen($expected_key) > 20) $expected_key = crc32( $expected_key);
$key = preg_replace("[^0-9-.a-zA-Z_=]", "_", $expected_key);
$key = substr($key, 0, min(array(strlen($key), 20)));
return $key;
}
/**
* Generate validate key for editor by documentId
*
* LFJ7 or "http://helpcenter.onlyoffice.com/content/GettingStarted.pdf"
*
* @param string $document_revision_id Key for caching on service, whose used in editor
* @param bool $add_host_for_validate Add host address to the key
*
* @return Validation key
*/
function GenerateValidateKey($document_revision_id, $add_host_for_validate = true) {
if (empty($document_revision_id)) return '';
$document_revision_id = GenerateRevisionId($document_revision_id);
$keyId = servConvGetKey();
$primaryKey = NULL;
$ms = number_format(round(microtime(true) * 1000),0,'.','');
if ($add_host_for_validate)
{
$userIp = getClientIp();
if (!empty($userIp)) {
$primaryKey = "{\"expire\":\"\\/Date(" . $ms . ")\\/\",\"key\":\"" . $document_revision_id . "\",\"key_id\":\"" . $keyId . "\",\"user_count\":0,\"ip\":\"" . $userIp . "\"}";
}
}
if ($primaryKey == NULL)
$primaryKey = "{\"expire\":\"\\/Date(" . $ms . ")\\/\",\"key\":\"" . $document_revision_id . "\",\"key_id\":\"" . $keyId . "\",\"user_count\":0}";
sendlog("GenerateValidateKey. primaryKey = " . $primaryKey, "logs/common.log");
return signature_Create($primaryKey, servConvGetSKey());
}
/**
* Request for conversion to a service
*
* @param string $document_uri Uri for the document to convert
* @param string $from_extension Document extension
* @param string $to_extension Extension to which to convert
* @param string $document_revision_id Key for caching on service
* @param bool $is_async Perform conversions asynchronously
*
* @return Xml document request result of conversion
*/
function SendRequestToConvertService($document_uri, $from_extension, $to_extension, $document_revision_id, $is_async) {
if (empty($from_extension))
{
$path_parts = pathinfo($document_uri);
$from_extension = $path_parts['extension'];
}
$title = basename($document_uri);
if (empty($title)) {
$title = guid();
}
if (empty($document_revision_id)) {
$document_revision_id = $document_uri;
}
$document_revision_id = GenerateRevisionId($document_revision_id);
$validateKey = GenerateValidateKey($document_revision_id, false);
$urlToConverter = generateUrlToConverter($document_uri, $from_extension, $to_extension, $title, $document_revision_id, $validateKey, $is_async);
$response_xml_data;
$countTry = 0;
$opts = array('http' => array(
'method' => 'GET',
'timeout' => $GLOBALS['DOC_SERV_TIMEOUT']
)
);
if (substr($urlToConverter, 0, strlen("https")) === "https") {
$opts['ssl'] = array( 'verify_peer' => FALSE );
}
$context = stream_context_create($opts);
while ($countTry < ServiceConverterMaxTry)
{
$countTry = $countTry + 1;
$response_xml_data = file_get_contents($urlToConverter, FALSE, $context);
if ($response_xml_data !== false){ break; }
}
if ($countTry == ServiceConverterMaxTry)
{
throw new Exception ("Bad Request or timeout error");
}
libxml_use_internal_errors(true);
$data = simplexml_load_string($response_xml_data);
if (!$data) {
$exc = "Bad Response. Errors: ";
foreach(libxml_get_errors() as $error) {
$exc = $exc . "\t" . $error->message;
}
throw new Exception ($exc);
}
return $data;
}
/**
* The method is to convert the file to the required format
*
* Example:
* string convertedDocumentUri;
* GetConvertedUri("http://helpcenter.onlyoffice.com/content/GettingStarted.pdf", ".pdf", ".docx", "http://helpcenter.onlyoffice.com/content/GettingStarted.pdf", false, out convertedDocumentUri);
*
* @param string $document_uri Uri for the document to convert
* @param string $from_extension Document extension
* @param string $to_extension Extension to which to convert
* @param string $document_revision_id Key for caching on service
* @param bool $is_async Perform conversions asynchronously
* @param string $converted_document_uri Uri to the converted document
*
* @return The percentage of completion of conversion
*/
function GetConvertedUri($document_uri, $from_extension, $to_extension, $document_revision_id, $is_async, &$converted_document_uri) {
$converted_document_uri = "";
$responceFromConvertService = SendRequestToConvertService($document_uri, $from_extension, $to_extension, $document_revision_id, $is_async);
$errorElement = $responceFromConvertService->Error;
if ($errorElement != NULL && $errorElement != "") ProcessConvServResponceError($errorElement);
$isEndConvert = $responceFromConvertService->EndConvert;
$percent = $responceFromConvertService->Percent . "";
if ($isEndConvert != NULL && strtolower($isEndConvert) == "true")
{
$converted_document_uri = $responceFromConvertService->FileUrl;
$percent = 100;
}
else if ($percent >= 100)
$percent = 99;
return $percent;
}
/**
* Processing document received from the editing service.
*
* @param string $x_document_response The resulting xml from editing service
* @param string $response_uri Uri to the converted document
*
* @return The percentage of completion of conversion
*/
function GetResponseUri($x_document_response, &$response_uri) {
$response_uri = "";
$resultPercent = 0;
libxml_use_internal_errors(true);
$data = simplexml_load_string($x_document_response);
if (!$data) {
$errs = "Invalid answer format. Errors: ";
foreach(libxml_get_errors() as $error) {
$errs = $errs . '\t' . $error->message;
}
throw new Exception ($errs);
}
$errorElement = $data->Error;
if ($errorElement != NULL && $errorElement != "") ProcessConvServResponceError($data->Error);
$endConvert = $data->EndConvert;
if ($endConvert != NULL && $endConvert == "") throw new Exception("Invalid answer format");
if ($endConvert != NULL && strtolower($endConvert) == true)
{
$fileUrl = $data->FileUrl;
if ($fileUrl == NULL || $fileUrl == "") throw new Exception("Invalid answer format");
$response_uri = $fileUrl;
$resultPercent = 100;
}
else
{
$percent = $data->Percent;
if ($percent != NULL && $percent != "")
$resultPercent = $percent;
if ($resultPercent >= 100)
$resultPercent = 99;
}
return $resultPercent;
}
?>