Files
crm.clientright.ru/modules/OnlyOfficeTemplates/actions/GetDocument.php

97 lines
3.8 KiB
PHP
Raw Normal View History

2026-02-16 09:27:19 +03:00
<?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);
}
}
}