Files
Fedor e21a37c2cb feat: finalize OnlyOfficeTemplates rollout and stability fixes
Complete OnlyOfficeTemplates safe rollout with module-scoped template paths, placeholder side panel, docx-renderer feature flags/fallback, public OnlyOffice endpoints, and list/delete UX so editing and saving work reliably without breaking legacy flow.
2026-03-26 18:03:58 +03:00

105 lines
4.6 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
/**
* Edit/Create template: left = metadata (name, module), right = OnlyOffice Document Editor in iframe.
* Document is loaded from GetDocument and saved to S3 via OnlyOffice callback.
*/
class OnlyOfficeTemplates_Edit_View extends Vtiger_Index_View
{
public function checkPermission(Vtiger_Request $request)
{
$moduleName = $request->getModule();
$tabId = getTabId($moduleName);
$privileges = Users_Privileges_Model::getCurrentUserPrivilegesModel();
if (!$privileges->hasModulePermission($tabId)) {
throw new AppException('LBL_PERMISSION_DENIED');
}
}
public function process(Vtiger_Request $request)
{
$moduleName = $request->getModule();
$templateId = (int)$request->get('templateid');
// Без реального id документа OnlyOffice получает template_id=0 — редирект на создание черновика
if ($templateId <= 0) {
header('Location: index.php?module=OnlyOfficeTemplates&action=CreateDraft&app=TOOLS');
return;
}
$viewer = $this->getViewer($request);
$adb = PearDatabase::getInstance();
$currentUser = Users_Record_Model::getCurrentUserModel();
$userId = $currentUser->getId();
$template = null;
if ($templateId > 0) {
$res = $adb->pquery(
"SELECT id, name, module, file_name, owner FROM vtiger_oot_templates WHERE id = ?",
[$templateId]
);
$template = $adb->fetchByAssoc($res);
// Доступ: достаточно прав на модуль (checkPermission выше); шаблоны доступны всем с доступом к OnlyOfficeTemplates
}
if (!$template) {
header('Location: index.php?module=OnlyOfficeTemplates&view=List&app=TOOLS');
return;
}
$res = $adb->pquery(
"SELECT name FROM vtiger_tab WHERE isentitytype = 1 AND presence = 0 ORDER BY name",
[]
);
$modules = [];
while ($row = $adb->fetchByAssoc($res)) {
$modules[$row['name']] = vtranslate($row['name'], $row['name']);
}
require_once dirname(__DIR__) . '/config.php';
$config = OnlyOfficeTemplates_getConfig();
$docServer = rtrim($config['onlyoffice_document_server'] ?? '', '/');
if ($docServer === '') {
$viewer->assign('OOT_EDITOR_AVAILABLE', false);
$viewer->assign('OOT_EDITOR_MESSAGE', 'OnlyOffice Document Server не настроен (ONLYOFFICE_DOCUMENT_SERVER).');
} else {
$viewer->assign('OOT_EDITOR_AVAILABLE', true);
$baseUrl = $this->getBaseUrl();
$tid = (int)$template['id'];
$documentUrl = $baseUrl . '/modules/OnlyOfficeTemplates/public/get_document.php?template_id=' . $tid;
$secret = $config['document_secret'] ?? '';
if ($secret !== '' && $tid > 0) {
$documentUrl .= '&token=' . rawurlencode(hash_hmac('sha256', (string)$tid, $secret));
}
$callbackUrl = $baseUrl . '/modules/OnlyOfficeTemplates/public/callback.php';
$docKey = $tid > 0 ? (string)$tid : ('new_' . $userId . '_' . time());
$viewer->assign('OOT_DOCUMENT_SERVER', $docServer);
$viewer->assign('OOT_DOCUMENT_URL', $documentUrl);
$viewer->assign('OOT_CALLBACK_URL', $callbackUrl);
$viewer->assign('OOT_DOC_KEY', $docKey);
$viewer->assign('OOT_DOC_TITLE', $template['file_name'] ?: 'document.docx');
}
$viewer->assign('MODULE_NAME', $moduleName);
$viewer->assign('TEMPLATE', $template);
$viewer->assign('MODULES', $modules);
$viewer->assign('OOT_SOURCE_MODULE', $template['module'] ?? '');
$viewer->assign('OOT_PLACEHOLDERS_URL', 'index.php?module=OnlyOfficeTemplates&action=GetAvailablePlaceholders');
$viewer->assign('ERROR_MSG', $request->get('error') ?: '');
$viewer->view('Edit.tpl', $moduleName);
}
protected function getBaseUrl()
{
if (function_exists('vglobal') && (vglobal('site_URL') ?? '') !== '') {
return rtrim(vglobal('site_URL'), '/');
}
$proto = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http';
$host = $_SERVER['HTTP_HOST'] ?? 'localhost';
$path = dirname($_SERVER['SCRIPT_NAME'] ?? '');
$path = str_replace('\\', '/', $path);
if ($path === '/' || $path === '') {
return $proto . '://' . $host;
}
return $proto . '://' . $host . $path;
}
}