97 lines
3.8 KiB
PHP
97 lines
3.8 KiB
PHP
<?php
|
|
/**
|
|
* Serve DOCX for OnlyOffice Document Server: from S3 or empty document for new template.
|
|
* Document Server requests this URL; it must be publicly reachable.
|
|
*/
|
|
|
|
class OnlyOfficeTemplates_GetDocument_Action extends Vtiger_Action_Controller
|
|
{
|
|
/** Document Server requests this URL without session; we verify token if OOT_DOCUMENT_SECRET is set. */
|
|
public function checkPermission(Vtiger_Request $request)
|
|
{
|
|
require_once dirname(__DIR__) . '/config.php';
|
|
$config = OnlyOfficeTemplates_getConfig();
|
|
$secret = $config['document_secret'] ?? '';
|
|
if ($secret !== '') {
|
|
$templateId = (int)$request->get('template_id');
|
|
$token = $request->get('token');
|
|
$expected = hash_hmac('sha256', (string)$templateId, $secret);
|
|
if ($token === '' || !hash_equals($expected, $token)) {
|
|
throw new AppException('LBL_PERMISSION_DENIED');
|
|
}
|
|
}
|
|
}
|
|
|
|
public function process(Vtiger_Request $request)
|
|
{
|
|
$templateId = (int)$request->get('template_id');
|
|
if ($templateId <= 0) {
|
|
$this->outputEmptyDocx();
|
|
return;
|
|
}
|
|
|
|
$adb = PearDatabase::getInstance();
|
|
$res = $adb->pquery(
|
|
"SELECT id, name, module, s3_key, file_name, owner FROM vtiger_oot_templates WHERE id = ?",
|
|
[$templateId]
|
|
);
|
|
$row = $adb->fetchByAssoc($res);
|
|
if (!$row) {
|
|
$this->outputEmptyDocx();
|
|
return;
|
|
}
|
|
if (empty($row['s3_key']) || empty($row['file_name'])) {
|
|
$this->outputEmptyDocx();
|
|
return;
|
|
}
|
|
|
|
require_once dirname(__DIR__) . '/config.php';
|
|
require_once dirname(__DIR__) . '/resources/S3Helper.php';
|
|
$config = OnlyOfficeTemplates_getConfig();
|
|
$s3 = new OnlyOfficeTemplates_S3Helper($config);
|
|
$body = $s3->getObjectBody($row['s3_key']);
|
|
$fileName = $row['file_name'];
|
|
header('Content-Type: application/vnd.openxmlformats-officedocument.wordprocessingml.document');
|
|
header('Content-Disposition: attachment; filename="' . basename($fileName) . '"');
|
|
header('Content-Length: ' . strlen($body));
|
|
header('Cache-Control: no-cache');
|
|
echo $body;
|
|
}
|
|
|
|
protected function outputEmptyDocx()
|
|
{
|
|
$rootDir = dirname(dirname(dirname(__DIR__)));
|
|
$emptyPath = dirname(__DIR__) . '/resources/empty.docx';
|
|
if (file_exists($emptyPath)) {
|
|
header('Content-Type: application/vnd.openxmlformats-officedocument.wordprocessingml.document');
|
|
header('Content-Disposition: attachment; filename="document.docx"');
|
|
header('Content-Length: ' . filesize($emptyPath));
|
|
header('Cache-Control: no-cache');
|
|
readfile($emptyPath);
|
|
return;
|
|
}
|
|
if (is_file($rootDir . '/vendor/autoload.php')) {
|
|
require_once $rootDir . '/vendor/autoload.php';
|
|
}
|
|
if (!class_exists('PhpOffice\PhpWord\PhpWord')) {
|
|
header('HTTP/1.1 500 Internal Server Error');
|
|
echo 'PHPWord not found';
|
|
return;
|
|
}
|
|
$phpWord = new \PhpOffice\PhpWord\PhpWord();
|
|
$phpWord->addSection();
|
|
$tmp = tempnam(sys_get_temp_dir(), 'oot_empty_') . '.docx';
|
|
try {
|
|
$writer = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, 'Word2007');
|
|
$writer->save($tmp);
|
|
header('Content-Type: application/vnd.openxmlformats-officedocument.wordprocessingml.document');
|
|
header('Content-Disposition: attachment; filename="document.docx"');
|
|
header('Content-Length: ' . filesize($tmp));
|
|
header('Cache-Control: no-cache');
|
|
readfile($tmp);
|
|
} finally {
|
|
@unlink($tmp);
|
|
}
|
|
}
|
|
}
|