diff --git a/main/exercise/AnswerInOfficeDoc.php b/main/exercise/AnswerInOfficeDoc.php
index 52b42419e32..c4537cb4588 100644
--- a/main/exercise/AnswerInOfficeDoc.php
+++ b/main/exercise/AnswerInOfficeDoc.php
@@ -128,7 +128,7 @@ public function return_header(Exercise $exercise, $counter = null, $score = []):
$header .= '
';
if (!empty($this->extra) && 'true' === OnlyofficePlugin::create()->get('enable_onlyoffice_plugin')) {
- $fileUrl = api_get_path(WEB_COURSE_PATH).api_get_course_path() . "/exercises/" . $this->extra;
+ $fileUrl = api_get_course_path() . "/exercises/" . $this->extra;
$documentUrl = OnlyofficeTools::getPathToView($fileUrl);
$header .= "
";
} else {
@@ -183,9 +183,9 @@ public function getFileUrl(bool $loadFromDatabase = false): ?string
$this->fileName = basename($this->extra);
}
- $filePath = api_get_path(SYS_COURSE_PATH) . $this->course['path'] . '/exercises/' . $this->extra;
- if (is_file($filePath)) {
- return str_replace(api_get_path(SYS_COURSE_PATH), api_get_path(WEB_COURSE_PATH), $filePath);
+ $filePath = $this->course['path'].'/exercises/'.$this->extra;
+ if (is_file(api_get_path(SYS_COURSE_PATH).$filePath)) {
+ return $filePath;
}
return null;
diff --git a/main/exercise/exercise.class.php b/main/exercise/exercise.class.php
index d18dc7b6088..ffa7100cd7e 100755
--- a/main/exercise/exercise.class.php
+++ b/main/exercise/exercise.class.php
@@ -6599,11 +6599,9 @@ function ($answerId) use ($objAnswerTmp) {
$exercisePath = api_get_path(SYS_COURSE_PATH) . api_get_course_path() . "/exercises/{$courseId}/{$sessionId}/{$this->iid}/{$quesId}/{$userId}/";
$originalFilePath = $objQuestionTmp->getFileUrl(true);
- if (!empty($originalFilePath) && file_exists($originalFilePath)) {
- $originalExtension = pathinfo($originalFilePath, PATHINFO_EXTENSION);
- } else {
- $originalExtension = 'docx';
- }
+ $originalExtension = !empty($originalFilePath) && file_exists($originalFilePath)
+ ? pathinfo($originalFilePath, PATHINFO_EXTENSION)
+ : 'docx';
$fileName = "response_" . uniqid() . "." . $originalExtension;
$fullFilePath = $exercisePath . $fileName;
@@ -6612,7 +6610,11 @@ function ($answerId) use ($objAnswerTmp) {
mkdir($exercisePath, 0775, true);
}
- if (!empty($_FILES['office_file']['tmp_name'])) {
+ if (!empty($_POST['onlyoffice_file_url'])) {
+ $onlyofficeFileUrl = $_POST['onlyoffice_file_url'];
+ file_put_contents($fullFilePath, file_get_contents($onlyofficeFileUrl));
+ }
+ elseif (!empty($_FILES['office_file']['tmp_name'])) {
move_uploaded_file($_FILES['office_file']['tmp_name'], $fullFilePath);
} else {
if (!empty($originalFilePath) && file_exists($originalFilePath)) {
diff --git a/main/inc/lib/exercise.lib.php b/main/inc/lib/exercise.lib.php
index cf27fba631f..7d3fd578e65 100644
--- a/main/inc/lib/exercise.lib.php
+++ b/main/inc/lib/exercise.lib.php
@@ -287,7 +287,7 @@ function setRemoveLink(dataContext) {
case ANSWER_IN_OFFICE_DOC:
if ('true' === OnlyofficePlugin::create()->get('enable_onlyoffice_plugin')) {
if (!empty($objQuestionTmp->extra)) {
- $fileUrl = api_get_path(WEB_COURSE_PATH) . api_get_course_path() . "/exercises/" . $objQuestionTmp->extra;
+ $fileUrl = api_get_course_path() . "/exercises/" . $objQuestionTmp->extra;
$documentUrl = OnlyofficeTools::getPathToView($fileUrl);
echo '
';
diff --git a/plugin/onlyoffice/callback.php b/plugin/onlyoffice/callback.php
index a1c60720be3..47b5d5b44cd 100644
--- a/plugin/onlyoffice/callback.php
+++ b/plugin/onlyoffice/callback.php
@@ -24,7 +24,7 @@
if (isset($_GET['hash']) && !empty($_GET['hash'])) {
$callbackResponseArray = [];
- @header('Content-Type: application/json; charset==utf-8');
+ @header('Content-Type: application/json; charset=utf-8');
@header('X-Robots-Tag: noindex');
@header('X-Content-Type-Options: nosniff');
@@ -69,7 +69,7 @@
switch ($type) {
case 'track':
- $callbackResponseArray = track();
+ $callbackResponseArray = track($type, $docId);
exit(json_encode($callbackResponseArray));
case 'download':
$callbackResponseArray = download();
@@ -87,7 +87,7 @@
/**
* Handle request from the document server with the document status information.
*/
-function track(): array
+function track($type, $docId): array
{
$result = [];
@@ -138,10 +138,14 @@ function track(): array
}
}
- $data['url'] = isset($payload->url) ? $payload->url : null;
+ $data['url'] = $payload->url ?? null;
$data['status'] = $payload->status;
}
+ if (!isset($data['url']) || empty($data['url']) || !in_array($data['status'], [2, 3])) {
+ return ['status' => 'no_changes'];
+ }
+
$docStatus = new CallbackDocStatus($data['status']);
$callback = new OnlyofficeCallback();
$callback->setStatus($docStatus);
@@ -157,10 +161,35 @@ function track(): array
'groupId' => $groupId,
'sessionId' => $sessionId,
'courseInfo' => $courseInfo,
- ]);
- $result = $callbackService->processCallback($callback, $docId);
+ ]
+ );
+
+ if ($type === 'exercise') {
+ return saveExerciseFile($docId, $data['url']);
+ }
+
+ return $callbackService->processCallback($callback, $docId);
+}
+
+/**
+ * Save exercise file
+ */
+function saveExerciseFile($docId, $fileUrl): array
+{
+ global $courseInfo, $sessionId, $userId;
+
+ $exercisePath = api_get_path(SYS_COURSE_PATH) . api_get_course_path() . "/exercises/{$courseInfo['real_id']}/{$sessionId}/{$docId}/{$userId}/";
+
+ if (!is_dir($exercisePath)) {
+ mkdir($exercisePath, 0775, true);
+ }
+
+ $fileName = "response_" . uniqid() . ".docx";
+ $fullFilePath = $exercisePath . $fileName;
+
+ file_put_contents($fullFilePath, file_get_contents($fileUrl));
- return $result;
+ return ['status' => 'saved', 'file' => $fullFilePath];
}
/**
diff --git a/plugin/onlyoffice/editor.php b/plugin/onlyoffice/editor.php
index 5d16ad385bb..43f8b5382e0 100644
--- a/plugin/onlyoffice/editor.php
+++ b/plugin/onlyoffice/editor.php
@@ -3,7 +3,7 @@
* (c) Copyright Ascensio System SIA 2024.
*
* Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
+ * You may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
@@ -21,21 +21,19 @@
$isEnable = 'true' === $plugin->get('enable_onlyoffice_plugin');
if (!$isEnable) {
exit("Document server isn't enabled");
-
- return;
}
$appSettings = new OnlyofficeAppsettings($plugin);
$documentServerUrl = $appSettings->getDocumentServerUrl();
if (empty($documentServerUrl)) {
exit("Document server isn't configured");
-
- return;
}
$config = [];
$docApiUrl = $appSettings->getDocumentServerApiUrl();
-$docId = (int) $_GET['docId'];
+$docId = isset($_GET['docId']) ? (int) $_GET['docId'] : null;
+$docPath = isset($_GET['doc']) ? urldecode($_GET['doc']) : null;
+
$groupId = isset($_GET['groupId']) && !empty($_GET['groupId']) ? (int) $_GET['groupId'] : (!empty($_GET['gidReq']) ? (int) $_GET['gidReq'] : null);
$userId = api_get_user_id();
$userInfo = api_get_user_info($userId);
@@ -46,7 +44,41 @@
api_not_allowed(true);
}
$courseCode = $courseInfo['code'];
-$docInfo = DocumentManager::get_document_data_by_id($docId, $courseCode, false, $sessionId);
+$docInfo = null;
+$fileId = null;
+$fileUrl = null;
+
+if ($docPath) {
+ $filePath = api_get_path(SYS_COURSE_PATH) . $docPath;
+ if (!file_exists($filePath)) {
+ error_log("ERROR: Document not found -> " . $filePath);
+ die("Error: Document not found.");
+ }
+
+ $fileId = basename($docPath);
+
+ $docInfo = [
+ 'path' => $docPath,
+ 'title' => basename($docPath),
+ 'size' => filesize($filePath),
+ 'forceEdit' => isset($_GET['forceEdit']) ? $_GET['forceEdit'] : false,
+ ];
+
+ $fileUrl = api_get_path(WEB_COURSE_PATH) . $docPath;
+}
+elseif ($docId) {
+ $docInfo = DocumentManager::get_document_data_by_id($docId, $courseCode, false, $sessionId);
+ if ($docInfo) {
+ $fileId = $docId;
+ $fileUrl = (new OnlyofficeDocumentManager($appSettings, $docInfo))->getFileUrl($docId);
+ }
+}
+
+if (!$docInfo || !$fileId) {
+ error_log("ERROR: Document not found.");
+ die("Error: Document not found.");
+}
+
$langInfo = LangManager::getLangUser();
$jwtManager = new OnlyofficeJwtManager($appSettings);
if (isset($_GET['forceEdit']) && (bool) $_GET['forceEdit'] === true) {
@@ -55,22 +87,29 @@
$documentManager = new OnlyofficeDocumentManager($appSettings, $docInfo);
$extension = $documentManager->getExt($documentManager->getDocInfo('title'));
$docType = $documentManager->getDocType($extension);
-$key = $documentManager->getDocumentKey($docId, $courseCode);
-$fileUrl = $documentManager->getFileUrl($docId);
+$fileIdentifier = $docId ? (string) $docId : md5($docPath);
+$key = $documentManager->getDocumentKey($fileIdentifier, $courseCode);
+$fileUrl = $fileUrl ?? $documentManager->getFileUrl($fileIdentifier);
-if (!empty($appSettings->getStorageUrl())) {
+if (!empty($appSettings->getStorageUrl()) && !empty($fileUrl)) {
$fileUrl = str_replace(api_get_path(WEB_PATH), $appSettings->getStorageUrl(), $fileUrl);
}
$configService = new OnlyofficeConfigService($appSettings, $jwtManager, $documentManager);
$editorsMode = $configService->getEditorsMode();
-$config = $configService->createConfig($docId, $editorsMode, $_SERVER['HTTP_USER_AGENT']);
+$config = $configService->createConfig($fileIdentifier, $editorsMode, $_SERVER['HTTP_USER_AGENT']);
$config = json_decode(json_encode($config), true);
+
+if (empty($config)) {
+ error_log("ERROR: Failed to generate the configuration for OnlyOffice");
+ die("Error: Failed to generate the configuration for OnlyOffice.");
+}
+
$isMobileAgent = $configService->isMobileAgent($_SERVER['HTTP_USER_AGENT']);
$showHeaders = true;
$headerHeight = 'calc(100% - 140px)';
-if (!empty($_GET['nh'])) {
+if (!empty($_GET['nh']) || !empty($docPath)) {
$showHeaders = false;
$headerHeight = '100%';
}
@@ -98,11 +137,11 @@
var onRequestSaveAs = function (event) {
var url = + "onlyoffice/ajax/saveas.php";
- var folderId = ;
+ var folderId = ;
var saveData = {
title: event.data.title,
url: event.data.url,
- folderId: folderId ? folderId : 0,
+ folderId: folderId,
sessionId: ,
courseId: ,
groupId:
diff --git a/plugin/onlyoffice/lib/onlyofficeDocumentManager.php b/plugin/onlyoffice/lib/onlyofficeDocumentManager.php
index a051dc0efc4..3e0024e93c6 100644
--- a/plugin/onlyoffice/lib/onlyofficeDocumentManager.php
+++ b/plugin/onlyoffice/lib/onlyofficeDocumentManager.php
@@ -59,7 +59,7 @@ public function getFileUrl(string $fileId)
];
if (!empty($this->getGroupId())) {
- $data['groupId'] = $groupId;
+ $data['groupId'] = $this->getGroupId();
}
$jwtManager = new OnlyofficeJwtManager($this->settingsManager);
$hashUrl = $jwtManager->getHash($data);
@@ -76,8 +76,6 @@ public function getGroupId()
public function getCallbackUrl(string $fileId)
{
- $url = '';
-
$data = [
'type' => 'track',
'courseId' => api_get_course_int_id(),
@@ -87,13 +85,17 @@ public function getCallbackUrl(string $fileId)
];
if (!empty($this->getGroupId())) {
- $data['groupId'] = $groupId;
+ $data['groupId'] = $this->getGroupId();
+ }
+
+ if (isset($this->docInfo['path']) && str_contains($this->docInfo['path'], 'exercises/')) {
+ $data['typeExercise'] = 'exercise';
}
$jwtManager = new OnlyofficeJwtManager($this->settingsManager);
$hashUrl = $jwtManager->getHash($data);
- return $url.api_get_path(WEB_PLUGIN_PATH).'onlyoffice/callback.php?hash='.$hashUrl;
+ return api_get_path(WEB_PLUGIN_PATH) . 'onlyoffice/callback.php?hash=' . $hashUrl;
}
public function getGobackUrl(string $fileId)