Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
6bc5b60
Exercise: Add OnlyOffice question type with document editing support …
christianbeeznest Mar 8, 2025
4d82256
Exercise: Improved OnlyOffice integration and URL handling - refs BT#…
christianbeeznest Mar 9, 2025
a60bfcb
Exercise: Improve OnlyOffice integration with dynamic return URLs - r…
christianbeeznest Mar 9, 2025
e10f338
Exercise: Add missing parameters for docInfo onlyoffice - refs BT#22370
christianbeeznest Mar 10, 2025
b088041
Exercise: Improve file handling with onlyoffice and exercise tracking…
christianbeeznest Mar 10, 2025
e063434
Merge remote-tracking branch 'upstream/1.11.x' into efc-22370
christianbeeznest Mar 11, 2025
bb4ed6d
Exercise: Fix evaluation of Answer in Office doc question - refs BT#2…
christianbeeznest Mar 11, 2025
5fb30f2
Exercise: Improve display onlyoffice doc editor - refs BT#22370
christianbeeznest Mar 12, 2025
07d3aed
Exercise: Add readonly to editor onlyoffice in results - refs BT#22370
christianbeeznest Mar 12, 2025
1169d33
Merge remote-tracking branch 'upstream/1.11.x' into efc-22370
christianbeeznest Mar 19, 2025
1a5bc07
Exercise: Fix student edit permissions & finalization view in OnlyOffice
christianbeeznest Mar 20, 2025
98cf6fe
Exercise: Fix student id to display onlyoffice answer
christianbeeznest Mar 20, 2025
e21d4eb
Merge remote-tracking branch 'upstream/1.11.x' into efc-22370
christianbeeznest Mar 24, 2025
5bc1912
Exercise: Auto-refresh OnlyOffice iframe to show latest edits - refs …
christianbeeznest Mar 24, 2025
c486375
Exercise: Auto-refresh OnlyOffice iframe to show results - refs BT#22370
christianbeeznest Mar 24, 2025
d31bce5
Exercise: Auto-refresh OnlyOffice iframe - refs BT#22370
christianbeeznest Mar 24, 2025
d8a9019
Merge remote-tracking branch 'upstream/1.11.x' into efc-22370
christianbeeznest Mar 28, 2025
b789f21
Exercise: Prevent cached document in results page by adding timestamp…
christianbeeznest Mar 28, 2025
4b377c5
Exercise: Improve document reload in result view - refs BT#22370
christianbeeznest Mar 29, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Exercise: Improved OnlyOffice integration and URL handling - refs BT#…
…22370
  • Loading branch information
christianbeeznest committed Mar 9, 2025
commit 4d82256e54916b067caee42d8fc9b7382592fcbe
8 changes: 4 additions & 4 deletions main/exercise/AnswerInOfficeDoc.php
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ public function return_header(Exercise $exercise, $counter = null, $score = []):
$header .= '<div class="question-container">';

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 .= "<iframe src='{$documentUrl}' width='800' height='600'></iframe>";
} else {
Expand Down Expand Up @@ -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;
Expand Down
14 changes: 8 additions & 6 deletions main/exercise/exercise.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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)) {
Expand Down
2 changes: 1 addition & 1 deletion main/inc/lib/exercise.lib.php
Original file line number Diff line number Diff line change
Expand Up @@ -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 '<div class="office-doc-container">';
Expand Down
43 changes: 36 additions & 7 deletions plugin/onlyoffice/callback.php
Original file line number Diff line number Diff line change
Expand Up @@ -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');

Expand Down Expand Up @@ -69,7 +69,7 @@

switch ($type) {
case 'track':
$callbackResponseArray = track();
$callbackResponseArray = track($type, $docId);
exit(json_encode($callbackResponseArray));
case 'download':
$callbackResponseArray = download();
Expand All @@ -87,7 +87,7 @@
/**
* Handle request from the document server with the document status information.
*/
function track(): array
function track($type, $docId): array
{
$result = [];

Expand Down Expand Up @@ -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);
Expand All @@ -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];
}

/**
Expand Down
67 changes: 53 additions & 14 deletions plugin/onlyoffice/editor.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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);
Expand All @@ -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) {
Expand All @@ -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%';
}
Expand Down Expand Up @@ -98,11 +137,11 @@

var onRequestSaveAs = function (event) {
var url = <?php echo json_encode(api_get_path(WEB_PLUGIN_PATH)); ?> + "onlyoffice/ajax/saveas.php";
var folderId = <?php echo json_encode($docInfo['parent_id']); ?>;
var folderId = <?php echo json_encode($docInfo['parent_id'] ?? 0); ?>;
var saveData = {
title: event.data.title,
url: event.data.url,
folderId: folderId ? folderId : 0,
folderId: folderId,
sessionId: <?php echo json_encode($sessionId); ?>,
courseId: <?php echo json_encode($courseId); ?>,
groupId: <?php echo json_encode($groupId); ?>
Expand Down
12 changes: 7 additions & 5 deletions plugin/onlyoffice/lib/onlyofficeDocumentManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -76,8 +76,6 @@ public function getGroupId()

public function getCallbackUrl(string $fileId)
{
$url = '';

$data = [
'type' => 'track',
'courseId' => api_get_course_int_id(),
Expand All @@ -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)
Expand Down
Loading