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.
105 lines
4.6 KiB
PHP
105 lines
4.6 KiB
PHP
<?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;
|
||
}
|
||
}
|