upgrade
This commit is contained in:
48
plugin/onlyoffice/lib/langManager.php
Normal file
48
plugin/onlyoffice/lib/langManager.php
Normal file
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
/**
|
||||
* (c) Copyright Ascensio System SIA 2025.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (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
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
require_once __DIR__.'/../../../main/inc/global.inc.php';
|
||||
|
||||
class LangManager
|
||||
{
|
||||
/**
|
||||
* Return lang info for current user.
|
||||
*/
|
||||
public static function getLangUser(): array
|
||||
{
|
||||
$langInfo = [];
|
||||
$userLang = api_get_language_from_type('user_profil_lang');
|
||||
if (empty($userLang)) {
|
||||
$userLang = api_get_language_from_type('course_lang');
|
||||
}
|
||||
if (empty($userLang)) {
|
||||
$langId = SubLanguageManager::get_platform_language_id();
|
||||
$langInfo = api_get_language_info($langId);
|
||||
|
||||
return $langInfo;
|
||||
}
|
||||
|
||||
$allLang = SubLanguageManager::getAllLanguages();
|
||||
foreach ($allLang as $langItem) {
|
||||
if ($langItem['english_name'] === $userLang) {
|
||||
$langInfo = $langItem;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $langInfo;
|
||||
}
|
||||
}
|
||||
45
plugin/onlyoffice/lib/onlyofficeActionObserver.php
Normal file
45
plugin/onlyoffice/lib/onlyofficeActionObserver.php
Normal file
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
/**
|
||||
* (c) Copyright Ascensio System SIA 2025.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (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
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
class OnlyofficeActionObserver extends HookObserver implements HookDocumentActionObserverInterface
|
||||
{
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct(
|
||||
'plugin/onlyoffice/lib/onlyofficePlugin.php',
|
||||
'onlyoffice'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a Onlyoffice edit tools when the Chamilo loads document tools.
|
||||
*
|
||||
* @param HookDocumentActionEventInterface $event - the hook event
|
||||
*/
|
||||
public function notifyDocumentAction(HookDocumentActionEventInterface $event)
|
||||
{
|
||||
$data = $event->getEventData();
|
||||
|
||||
if (HOOK_EVENT_TYPE_PRE === $data['type']) {
|
||||
$data['actions'][] = OnlyofficeTools::getButtonCreateNew();
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
}
|
||||
46
plugin/onlyoffice/lib/onlyofficeAppRequests.php
Normal file
46
plugin/onlyoffice/lib/onlyofficeAppRequests.php
Normal file
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
/**
|
||||
* (c) Copyright Ascensio System SIA 2025.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (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
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
use Onlyoffice\DocsIntegrationSdk\Service\Request\RequestService;
|
||||
|
||||
class OnlyofficeAppRequests extends RequestService
|
||||
{
|
||||
/**
|
||||
* File url to test convert service.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $convertFileUrl;
|
||||
private $convertFilePath;
|
||||
|
||||
public function __construct($settingsManager, $httpClient, $jwtManager)
|
||||
{
|
||||
parent::__construct($settingsManager, $httpClient, $jwtManager);
|
||||
}
|
||||
|
||||
public function getFileUrlForConvert()
|
||||
{
|
||||
$data = [
|
||||
'type' => 'empty',
|
||||
'courseId' => api_get_course_int_id(),
|
||||
'userId' => api_get_user_id(),
|
||||
'sessionId' => api_get_session_id(),
|
||||
];
|
||||
$hashUrl = $this->jwtManager->getHash($data);
|
||||
|
||||
return api_get_path(WEB_PLUGIN_PATH).'onlyoffice/callback.php?hash='.$hashUrl;
|
||||
}
|
||||
}
|
||||
177
plugin/onlyoffice/lib/onlyofficeAppSettings.php
Normal file
177
plugin/onlyoffice/lib/onlyofficeAppSettings.php
Normal file
@@ -0,0 +1,177 @@
|
||||
<?php
|
||||
/**
|
||||
* (c) Copyright Ascensio System SIA 2025.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (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
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
use Onlyoffice\DocsIntegrationSdk\Manager\Settings\SettingsManager;
|
||||
|
||||
class OnlyofficeAppsettings extends SettingsManager
|
||||
{
|
||||
/**
|
||||
* Link to Docs Cloud.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public const LINK_TO_DOCS = 'https://www.onlyoffice.com/docs-registration.aspx?referer=chamilo';
|
||||
/**
|
||||
* The settings key for the document server address.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $documentServerUrl = 'document_server_url';
|
||||
|
||||
/**
|
||||
* The config key for the jwt header.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $jwtHeader = 'onlyoffice_jwt_header';
|
||||
|
||||
/**
|
||||
* The config key for the internal url.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $documentServerInternalUrl = 'onlyoffice_internal_url';
|
||||
|
||||
/**
|
||||
* The config key for the storage url.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $storageUrl = 'onlyoffice_storage_url';
|
||||
|
||||
/**
|
||||
* The config key for the demo data.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $useDemoName = 'onlyoffice_connect_demo_data';
|
||||
|
||||
/**
|
||||
* Chamilo plugin.
|
||||
*/
|
||||
public $plugin;
|
||||
|
||||
public $newSettings;
|
||||
|
||||
/**
|
||||
* The config key for JWT secret key.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $jwtKey = 'jwt_secret';
|
||||
|
||||
public function __construct(Plugin $plugin, ?array $newSettings = null)
|
||||
{
|
||||
parent::__construct();
|
||||
$this->plugin = $plugin;
|
||||
$this->newSettings = $newSettings;
|
||||
}
|
||||
|
||||
public function getSetting($settingName)
|
||||
{
|
||||
$value = null;
|
||||
if (null !== $this->newSettings) {
|
||||
if (isset($this->newSettings[$settingName])) {
|
||||
$value = $this->newSettings[$settingName];
|
||||
}
|
||||
|
||||
if (empty($value)) {
|
||||
$prefix = $this->plugin->getPluginName();
|
||||
|
||||
if (substr($settingName, 0, strlen($prefix)) == $prefix) {
|
||||
$settingNameWithoutPrefix = substr($settingName, strlen($prefix) + 1);
|
||||
}
|
||||
|
||||
if (isset($this->newSettings[$settingNameWithoutPrefix])) {
|
||||
$value = $this->newSettings[$settingNameWithoutPrefix];
|
||||
}
|
||||
}
|
||||
if ($this->isSettingUrl($value)) {
|
||||
$value = $this->processUrl($value);
|
||||
}
|
||||
if (!empty($value)) {
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
switch ($settingName) {
|
||||
case $this->jwtHeader:
|
||||
$settings = api_get_setting($settingName);
|
||||
$value = is_array($settings) && array_key_exists($this->plugin->getPluginName(), $settings)
|
||||
? $settings[$this->plugin->getPluginName()]
|
||||
: null;
|
||||
|
||||
if (empty($value)) {
|
||||
$value = 'Authorization';
|
||||
}
|
||||
break;
|
||||
case $this->documentServerInternalUrl:
|
||||
$settings = api_get_setting($settingName);
|
||||
$value = is_array($settings) ? ($settings[$this->plugin->getPluginName()] ?? null) : null;
|
||||
break;
|
||||
case $this->useDemoName:
|
||||
$settings = api_get_setting($settingName);
|
||||
$value = is_array($settings) ? ($settings[0] ?? null) : null;
|
||||
break;
|
||||
case $this->jwtPrefix:
|
||||
$value = 'Bearer ';
|
||||
break;
|
||||
default:
|
||||
if (!empty($this->plugin) && method_exists($this->plugin, 'get')) {
|
||||
$value = $this->plugin->get($settingName);
|
||||
}
|
||||
}
|
||||
if (empty($value)) {
|
||||
$value = api_get_configuration_value($settingName);
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
public function setSetting($settingName, $value, $createSetting = false)
|
||||
{
|
||||
if (($settingName === $this->useDemoName) && $createSetting) {
|
||||
api_add_setting($value, $settingName, null, 'setting', 'Plugins');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$prefix = $this->plugin->getPluginName();
|
||||
if (!(substr($settingName, 0, strlen($prefix)) == $prefix)) {
|
||||
$settingName = $prefix.'_'.$settingName;
|
||||
}
|
||||
api_set_setting($settingName, $value);
|
||||
}
|
||||
|
||||
public function getServerUrl()
|
||||
{
|
||||
return api_get_path(WEB_PATH);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get link to Docs Cloud.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getLinkToDocs()
|
||||
{
|
||||
return self::LINK_TO_DOCS;
|
||||
}
|
||||
|
||||
public function isSettingUrl($settingName)
|
||||
{
|
||||
return in_array($settingName, [$this->documentServerUrl, $this->documentServerInternalUrl, $this->storageUrl]);
|
||||
}
|
||||
}
|
||||
150
plugin/onlyoffice/lib/onlyofficeCallbackService.php
Normal file
150
plugin/onlyoffice/lib/onlyofficeCallbackService.php
Normal file
@@ -0,0 +1,150 @@
|
||||
<?php
|
||||
/**
|
||||
* (c) Copyright Ascensio System SIA 2025.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (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
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
use Onlyoffice\DocsIntegrationSdk\Service\Callback\CallbackService;
|
||||
|
||||
class OnlyofficeCallbackService extends CallbackService
|
||||
{
|
||||
private $docData;
|
||||
|
||||
public function __construct($settingsManager, $jwtManager, $docData = [])
|
||||
{
|
||||
parent::__construct($settingsManager, $jwtManager);
|
||||
$this->docData = $docData;
|
||||
$this->trackResult = 1;
|
||||
}
|
||||
|
||||
public function processTrackerStatusEditing($callback, string $fileid)
|
||||
{
|
||||
return $this->processTrackerStatusEditingAndClosed($callback, $fileid);
|
||||
}
|
||||
|
||||
public function processTrackerStatusMustsave($callback, string $fileid)
|
||||
{
|
||||
return $this->processTrackerStatusMustsaveAndCorrupted($callback, $fileid);
|
||||
}
|
||||
|
||||
public function processTrackerStatusCorrupted($callback, string $fileid)
|
||||
{
|
||||
return $this->processTrackerStatusMustsaveAndCorrupted($callback, $fileid);
|
||||
}
|
||||
|
||||
public function processTrackerStatusClosed($callback, string $fileid)
|
||||
{
|
||||
return $this->processTrackerStatusEditingAndClosed($callback, $fileid);
|
||||
}
|
||||
|
||||
public function processTrackerStatusForcesave($callback, string $fileid)
|
||||
{
|
||||
$result['error'] = $this->trackResult;
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function processTrackerStatusMustsaveAndCorrupted($callback, string $fileid)
|
||||
{
|
||||
$downloadUri = $callback->getUrl();
|
||||
$this->settingsManager->replaceDocumentServerUrlToInternal($downloadUri);
|
||||
try {
|
||||
if (!empty($this->docData['docId']) && !empty($this->docData['courseCode'])) {
|
||||
$docInfo = DocumentManager::get_document_data_by_id($fileid, $this->docData['courseCode'], false, $this->docData['sessionId']);
|
||||
if (false === $docInfo) {
|
||||
$result['error'] = 'File not found';
|
||||
|
||||
return $result;
|
||||
}
|
||||
$filePath = $docInfo['absolute_path'];
|
||||
} else {
|
||||
$result['error'] = 'Bad Request';
|
||||
|
||||
return $result;
|
||||
}
|
||||
list($isAllowToEdit, $isMyDir, $isGroupAccess, $isReadonly) = $this->getPermissionsByDocInfo($docInfo);
|
||||
|
||||
if ($isReadonly) {
|
||||
$result['error'] = $this->trackResult;
|
||||
|
||||
return $result;
|
||||
}
|
||||
if (($new_data = file_get_contents($downloadUri)) === false) {
|
||||
$result['error'] = $this->trackResult;
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
if ($isAllowToEdit || $isMyDir || $isGroupAccess) {
|
||||
$groupInfo = GroupManager::get_group_properties($this->docData['groupId']);
|
||||
|
||||
if ($fp = @fopen($filePath, 'w')) {
|
||||
fputs($fp, $new_data);
|
||||
fclose($fp);
|
||||
api_item_property_update($this->docData['courseInfo'],
|
||||
TOOL_DOCUMENT,
|
||||
$fileid,
|
||||
'DocumentUpdated',
|
||||
$this->docData['userId'],
|
||||
$groupInfo,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
$this->docData['sessionId']);
|
||||
update_existing_document($this->docData['courseInfo'],
|
||||
$fileid,
|
||||
filesize($filePath),
|
||||
false);
|
||||
$this->trackResult = 0;
|
||||
$result['error'] = $this->trackResult;
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
} catch (UnexpectedValueException $e) {
|
||||
$result['error'] = 'Bad Request';
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
public function processTrackerStatusEditingAndClosed($callback, string $fileid)
|
||||
{
|
||||
$this->trackResult = 0;
|
||||
$result['error'] = $this->trackResult;
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method checks access rights to document and returns permissions.
|
||||
*/
|
||||
public function getPermissionsByDocInfo(array $docInfo)
|
||||
{
|
||||
$isAllowToEdit = api_is_allowed_to_edit(true, true);
|
||||
$isMyDir = DocumentManager::is_my_shared_folder($this->docData['userId'], $docInfo['absolute_parent_path'], $this->docData['sessionId']);
|
||||
|
||||
$isGroupAccess = false;
|
||||
if (!empty($groupId)) {
|
||||
$courseInfo = api_get_course_info($this->docData['courseCode']);
|
||||
Session::write('_real_cid', $courseInfo['real_id']);
|
||||
$groupProperties = GroupManager::get_group_properties($this->docData['groupId']);
|
||||
$docInfoGroup = api_get_item_property_info($courseInfo['real_id'], 'document', $docInfo['id'], $this->docData['sessionId']);
|
||||
$isGroupAccess = GroupManager::allowUploadEditDocument($this->docData['userId'], $this->docData['courseCode'], $groupProperties, $docInfoGroup);
|
||||
}
|
||||
|
||||
$isReadonly = $docInfo['readonly'];
|
||||
|
||||
return [$isAllowToEdit, $isMyDir, $isGroupAccess, $isReadonly];
|
||||
}
|
||||
}
|
||||
179
plugin/onlyoffice/lib/onlyofficeConfigService.php
Normal file
179
plugin/onlyoffice/lib/onlyofficeConfigService.php
Normal file
@@ -0,0 +1,179 @@
|
||||
<?php
|
||||
/**
|
||||
* (c) Copyright Ascensio System SIA 2025.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (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
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
use Onlyoffice\DocsIntegrationSdk\Models\Customization;
|
||||
use Onlyoffice\DocsIntegrationSdk\Models\EditorsMode;
|
||||
use Onlyoffice\DocsIntegrationSdk\Models\GoBack;
|
||||
use Onlyoffice\DocsIntegrationSdk\Models\Permissions;
|
||||
use Onlyoffice\DocsIntegrationSdk\Models\User;
|
||||
use Onlyoffice\DocsIntegrationSdk\Service\DocEditorConfig\DocEditorConfigService;
|
||||
|
||||
class OnlyofficeConfigService extends DocEditorConfigService
|
||||
{
|
||||
public function __construct($settingsManager, $jwtManager, $documentManager)
|
||||
{
|
||||
parent::__construct($settingsManager, $jwtManager, $documentManager);
|
||||
}
|
||||
|
||||
public function getEditorsMode()
|
||||
{
|
||||
if ($this->isEditable() && $this->getAccessRights() && !$this->isReadOnly()) {
|
||||
$editorsMode = new EditorsMode('edit');
|
||||
} else {
|
||||
if ($this->canView()) {
|
||||
$editorsMode = new EditorsMode('view');
|
||||
} else {
|
||||
api_not_allowed(true);
|
||||
}
|
||||
}
|
||||
|
||||
return $editorsMode;
|
||||
}
|
||||
|
||||
public function isEditable()
|
||||
{
|
||||
return $this->documentManager->isDocumentEditable($this->documentManager->getDocInfo('title'));
|
||||
}
|
||||
|
||||
public function canView()
|
||||
{
|
||||
return $this->documentManager->isDocumentViewable($this->documentManager->getDocInfo('title'));
|
||||
}
|
||||
|
||||
public function getAccessRights()
|
||||
{
|
||||
$isAllowToEdit = api_is_allowed_to_edit(true, true);
|
||||
$isMyDir = DocumentManager::is_my_shared_folder(
|
||||
api_get_user_id(),
|
||||
$this->documentManager->getDocInfo('absolute_parent_path'),
|
||||
api_get_session_id()
|
||||
);
|
||||
$isGroupAccess = false;
|
||||
if (!empty($this->documentManager->getGroupId())) {
|
||||
$groupProperties = GroupManager::get_group_properties($this->documentManager->getGroupId());
|
||||
$docInfoGroup = api_get_item_property_info(
|
||||
api_get_course_int_id(),
|
||||
'document',
|
||||
$docId,
|
||||
$sessionId
|
||||
);
|
||||
$isGroupAccess = GroupManager::allowUploadEditDocument(
|
||||
$userId,
|
||||
$courseCode,
|
||||
$groupProperties,
|
||||
$docInfoGroup
|
||||
);
|
||||
$isMemberGroup = GroupManager::is_user_in_group($userId, $groupProperties);
|
||||
if (!$isGroupAccess) {
|
||||
if (!$groupProperties['status']) {
|
||||
api_not_allowed(true);
|
||||
}
|
||||
if (!$isMemberGroup && 1 != $groupProperties['doc_state']) {
|
||||
api_not_allowed(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Allow editing if the document is part of an exercise
|
||||
if (!empty($_GET['exerciseId']) || !empty($_GET['exeId'])) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$accessRights = $isAllowToEdit || $isMyDir || $isGroupAccess;
|
||||
|
||||
return $accessRights;
|
||||
}
|
||||
|
||||
public function isReadOnly()
|
||||
{
|
||||
return $this->documentManager->getDocInfo('readonly');
|
||||
}
|
||||
|
||||
public function getUser()
|
||||
{
|
||||
$user = new User();
|
||||
$user->setId(api_get_user_id());
|
||||
$userInfo = api_get_user_info($userId);
|
||||
$user->setName($userInfo['username']);
|
||||
|
||||
return $user;
|
||||
}
|
||||
|
||||
public function getCustomization(string $fileId)
|
||||
{
|
||||
$goback = new GoBack();
|
||||
|
||||
if (!empty($this->documentManager->getGobackUrl($fileId))) {
|
||||
$goback->setUrl($this->documentManager->getGobackUrl($fileId));
|
||||
}
|
||||
$goback->setBlank(false);
|
||||
$customization = new Customization();
|
||||
$customization->setGoback($goback);
|
||||
$customization->setCompactHeader(true);
|
||||
$customization->setToolbarNoTabs(true);
|
||||
|
||||
return $customization;
|
||||
}
|
||||
|
||||
public function getLang()
|
||||
{
|
||||
return $this->getLangInfo();
|
||||
}
|
||||
|
||||
public function getRegion()
|
||||
{
|
||||
return $this->getLangInfo();
|
||||
}
|
||||
|
||||
public function getLangInfo()
|
||||
{
|
||||
$langInfo = LangManager::getLangUser();
|
||||
|
||||
return $langInfo['isocode'];
|
||||
}
|
||||
|
||||
public function getPermissions(string $fileId = '')
|
||||
{
|
||||
$permsEdit = $this->getAccessRights() && !$this->isReadOnly();
|
||||
$isFillable = $this->documentManager->isDocumentFillable($this->documentManager->getDocInfo('title'));
|
||||
|
||||
$permissions = new Permissions(null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
$permsEdit,
|
||||
null,
|
||||
$isFillable,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null
|
||||
);
|
||||
|
||||
return $permissions;
|
||||
}
|
||||
|
||||
public function getCoEditing(string $fileId = '', $mode = null, $type)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
284
plugin/onlyoffice/lib/onlyofficeDocumentManager.php
Normal file
284
plugin/onlyoffice/lib/onlyofficeDocumentManager.php
Normal file
@@ -0,0 +1,284 @@
|
||||
<?php
|
||||
/**
|
||||
* (c) Copyright Ascensio System SIA 2025.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (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
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
use DocumentManager as ChamiloDocumentManager;
|
||||
use Onlyoffice\DocsIntegrationSdk\Manager\Document\DocumentManager;
|
||||
|
||||
class OnlyofficeDocumentManager extends DocumentManager
|
||||
{
|
||||
private $docInfo;
|
||||
|
||||
public function __construct($settingsManager, array $docInfo, $formats = null, $systemLangCode = 'en')
|
||||
{
|
||||
$formats = new OnlyofficeFormatsManager();
|
||||
parent::__construct($settingsManager, $formats, $systemLangCode);
|
||||
$this->docInfo = $docInfo;
|
||||
}
|
||||
|
||||
public function getDocumentKey(string $fileId, $courseCode, bool $embedded = false)
|
||||
{
|
||||
if (!isset($this->docInfo['absolute_path'])) {
|
||||
return null;
|
||||
}
|
||||
$mtime = filemtime($this->docInfo['absolute_path']);
|
||||
$key = $mtime.$courseCode.$fileId;
|
||||
|
||||
return self::generateRevisionId($key);
|
||||
}
|
||||
|
||||
public function getDocumentName(string $fileId = '')
|
||||
{
|
||||
return $this->docInfo['title'];
|
||||
}
|
||||
|
||||
public static function getLangMapping()
|
||||
{
|
||||
}
|
||||
|
||||
public function getFileUrl(string $fileId)
|
||||
{
|
||||
$data = [
|
||||
'type' => 'download',
|
||||
'courseId' => api_get_course_int_id(),
|
||||
'userId' => api_get_user_id(),
|
||||
'docId' => $fileId,
|
||||
'sessionId' => api_get_session_id(),
|
||||
];
|
||||
|
||||
if (!empty($this->getGroupId())) {
|
||||
$data['groupId'] = $this->getGroupId();
|
||||
}
|
||||
|
||||
if (isset($this->docInfo['path']) && str_contains($this->docInfo['path'], 'exercises/')) {
|
||||
$data['doctype'] = 'exercise';
|
||||
$data['docPath'] = urlencode($this->docInfo['path']);
|
||||
}
|
||||
|
||||
$jwtManager = new OnlyofficeJwtManager($this->settingsManager);
|
||||
$hashUrl = $jwtManager->getHash($data);
|
||||
|
||||
return api_get_path(WEB_PLUGIN_PATH).$this->settingsManager->plugin->getPluginName().'/callback.php?hash='.$hashUrl;
|
||||
}
|
||||
|
||||
public function getGroupId()
|
||||
{
|
||||
$groupId = isset($_GET['groupId']) && !empty($_GET['groupId']) ? $_GET['groupId'] : null;
|
||||
|
||||
return $groupId;
|
||||
}
|
||||
|
||||
public function getCallbackUrl(string $fileId)
|
||||
{
|
||||
$data = [
|
||||
'type' => 'track',
|
||||
'courseId' => api_get_course_int_id(),
|
||||
'userId' => api_get_user_id(),
|
||||
'docId' => $fileId,
|
||||
'sessionId' => api_get_session_id(),
|
||||
];
|
||||
|
||||
if (!empty($this->getGroupId())) {
|
||||
$data['groupId'] = $this->getGroupId();
|
||||
}
|
||||
|
||||
if (isset($this->docInfo['path']) && str_contains($this->docInfo['path'], 'exercises/')) {
|
||||
$data['doctype'] = 'exercise';
|
||||
$data['docPath'] = urlencode($this->docInfo['path']);
|
||||
}
|
||||
|
||||
$jwtManager = new OnlyofficeJwtManager($this->settingsManager);
|
||||
$hashUrl = $jwtManager->getHash($data);
|
||||
|
||||
return api_get_path(WEB_PLUGIN_PATH).'onlyoffice/callback.php?hash='.$hashUrl;
|
||||
}
|
||||
|
||||
public function getGobackUrl(string $fileId): string
|
||||
{
|
||||
if (!empty($this->docInfo)) {
|
||||
if (isset($this->docInfo['path']) && str_contains($this->docInfo['path'], 'exercises/')) {
|
||||
return api_get_path(WEB_CODE_PATH).'exercise/exercise_submit.php'
|
||||
.'?cidReq='.Security::remove_XSS(api_get_course_id())
|
||||
.'&id_session='.Security::remove_XSS(api_get_session_id())
|
||||
.'&gidReq='.Security::remove_XSS($this->getGroupId())
|
||||
.'&exerciseId='.Security::remove_XSS($this->docInfo['exercise_id']);
|
||||
}
|
||||
|
||||
return self::getUrlToLocation(api_get_course_id(), api_get_session_id(), $this->getGroupId(), $this->docInfo['parent_id'], $this->docInfo['path'] ?? '');
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Return location file in Chamilo documents or exercises.
|
||||
*/
|
||||
public static function getUrlToLocation($courseCode, $sessionId, $groupId, $folderId, $filePath = ''): string
|
||||
{
|
||||
if (!empty($filePath) && str_contains($filePath, 'exercises/')) {
|
||||
return api_get_path(WEB_CODE_PATH).'exercise/exercise_submit.php'
|
||||
.'?cidReq='.Security::remove_XSS($courseCode)
|
||||
.'&id_session='.Security::remove_XSS($sessionId)
|
||||
.'&gidReq='.Security::remove_XSS($groupId)
|
||||
.'&exerciseId='.Security::remove_XSS($folderId);
|
||||
}
|
||||
|
||||
return api_get_path(WEB_CODE_PATH).'document/document.php'
|
||||
.'?cidReq='.Security::remove_XSS($courseCode)
|
||||
.'&id_session='.Security::remove_XSS($sessionId)
|
||||
.'&gidReq='.Security::remove_XSS($groupId)
|
||||
.'&id='.Security::remove_XSS($folderId);
|
||||
}
|
||||
|
||||
public function getCreateUrl(string $fileId)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of docInfo.
|
||||
*/
|
||||
public function getDocInfo($elem = null)
|
||||
{
|
||||
if (empty($elem)) {
|
||||
return $this->docInfo;
|
||||
} else {
|
||||
if (isset($this->docInfo[$elem])) {
|
||||
return $this->docInfo[$elem];
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value of docInfo.
|
||||
*/
|
||||
public function setDocInfo($docInfo)
|
||||
{
|
||||
$this->docInfo = $docInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return file extension by file type.
|
||||
*/
|
||||
public static function getDocExtByType(string $type): string
|
||||
{
|
||||
if ('text' === $type) {
|
||||
return 'docx';
|
||||
}
|
||||
if ('spreadsheet' === $type) {
|
||||
return 'xlsx';
|
||||
}
|
||||
if ('presentation' === $type) {
|
||||
return 'pptx';
|
||||
}
|
||||
if ('formTemplate' === $type) {
|
||||
return 'pdf';
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create new file.
|
||||
*/
|
||||
public static function createFile(
|
||||
string $basename,
|
||||
string $fileExt,
|
||||
int $folderId,
|
||||
int $userId,
|
||||
int $sessionId,
|
||||
int $courseId,
|
||||
int $groupId,
|
||||
string $templatePath = ''): array
|
||||
{
|
||||
$courseInfo = api_get_course_info_by_id($courseId);
|
||||
$courseCode = $courseInfo['code'];
|
||||
$groupInfo = GroupManager::get_group_properties($groupId);
|
||||
|
||||
$fileTitle = Security::remove_XSS($basename).'.'.$fileExt;
|
||||
|
||||
$fileNameSuffix = ChamiloDocumentManager::getDocumentSuffix($courseInfo, $sessionId, $groupId);
|
||||
// Try to avoid directories browsing (remove .., slashes and backslashes)
|
||||
$patterns = ['#\.\./#', '#\.\.#', '#/#', '#\\\#'];
|
||||
$replacements = ['', '', '', ''];
|
||||
$fileName = preg_replace($patterns, $replacements, $basename).$fileNameSuffix.'.'.$fileExt;
|
||||
|
||||
if (empty($templatePath)) {
|
||||
$templatePath = TemplateManager::getEmptyTemplate($fileExt);
|
||||
}
|
||||
|
||||
$folderPath = '';
|
||||
$fileRelatedPath = '/';
|
||||
if (!empty($folderId)) {
|
||||
$document_data = ChamiloDocumentManager::get_document_data_by_id(
|
||||
$folderId,
|
||||
$courseCode,
|
||||
true,
|
||||
$sessionId
|
||||
);
|
||||
$folderPath = $document_data['absolute_path'];
|
||||
$fileRelatedPath = $fileRelatedPath.substr($document_data['absolute_path_from_document'], 10).'/'.$fileName;
|
||||
} else {
|
||||
$folderPath = api_get_path(SYS_COURSE_PATH).api_get_course_path($courseCode).'/document';
|
||||
if (!empty($groupId)) {
|
||||
$folderPath = $folderPath.'/'.$groupInfo['directory'];
|
||||
$fileRelatedPath = $groupInfo['directory'].'/';
|
||||
}
|
||||
$fileRelatedPath = $fileRelatedPath.$fileName;
|
||||
}
|
||||
$filePath = $folderPath.'/'.$fileName;
|
||||
|
||||
if (file_exists($filePath)) {
|
||||
return ['error' => 'fileIsExist'];
|
||||
}
|
||||
|
||||
if ($fp = @fopen($filePath, 'w')) {
|
||||
$content = file_get_contents($templatePath);
|
||||
fputs($fp, $content);
|
||||
fclose($fp);
|
||||
|
||||
chmod($filePath, api_get_permissions_for_new_files());
|
||||
|
||||
$documentId = add_document(
|
||||
$courseInfo,
|
||||
$fileRelatedPath,
|
||||
'file',
|
||||
filesize($filePath),
|
||||
$fileTitle,
|
||||
null,
|
||||
false
|
||||
);
|
||||
if ($documentId) {
|
||||
api_item_property_update(
|
||||
$courseInfo,
|
||||
TOOL_DOCUMENT,
|
||||
$documentId,
|
||||
'DocumentAdded',
|
||||
$userId,
|
||||
$groupInfo,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
$sessionId
|
||||
);
|
||||
} else {
|
||||
return ['error' => 'impossibleCreateFile'];
|
||||
}
|
||||
}
|
||||
|
||||
return ['documentId' => $documentId];
|
||||
}
|
||||
}
|
||||
73
plugin/onlyoffice/lib/onlyofficeFormatsManager.php
Normal file
73
plugin/onlyoffice/lib/onlyofficeFormatsManager.php
Normal file
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
/**
|
||||
* (c) Copyright Ascensio System SIA 2025.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (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
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
use Onlyoffice\DocsIntegrationSdk\Manager\Formats\FormatsManager;
|
||||
use Onlyoffice\DocsIntegrationSdk\Util\CommonError;
|
||||
|
||||
class OnlyofficeFormatsManager extends FormatsManager
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
$formats = self::getFormats();
|
||||
$this->formatsList = self::buildNamedFormatsArray($formats);
|
||||
}
|
||||
|
||||
private static function getFormats()
|
||||
{
|
||||
$formats = file_get_contents(dirname(__DIR__).
|
||||
DIRECTORY_SEPARATOR.
|
||||
'vendor'.
|
||||
DIRECTORY_SEPARATOR.
|
||||
'onlyoffice'.
|
||||
DIRECTORY_SEPARATOR.
|
||||
'docs-integration-sdk'.
|
||||
DIRECTORY_SEPARATOR.
|
||||
'resources'.
|
||||
DIRECTORY_SEPARATOR.
|
||||
'assets'.
|
||||
DIRECTORY_SEPARATOR.
|
||||
'document-formats'.
|
||||
DIRECTORY_SEPARATOR.
|
||||
'onlyoffice-docs-formats.txt');
|
||||
|
||||
if (empty($formats)) {
|
||||
$formats = file_get_contents(dirname(__DIR__).
|
||||
DIRECTORY_SEPARATOR.
|
||||
'vendor'.
|
||||
DIRECTORY_SEPARATOR.
|
||||
'onlyoffice'.
|
||||
DIRECTORY_SEPARATOR.
|
||||
'docs-integration-sdk'.
|
||||
DIRECTORY_SEPARATOR.
|
||||
'resources'.
|
||||
DIRECTORY_SEPARATOR.
|
||||
'assets'.
|
||||
DIRECTORY_SEPARATOR.
|
||||
'document-formats'.
|
||||
DIRECTORY_SEPARATOR.
|
||||
'onlyoffice-docs-formats.json');
|
||||
}
|
||||
|
||||
if (!empty($formats)) {
|
||||
$formats = json_decode($formats);
|
||||
if (!empty($formats)) {
|
||||
return $formats;
|
||||
}
|
||||
throw new \Exception(CommonError::message(CommonError::EMPTY_FORMATS_ASSET));
|
||||
}
|
||||
throw new \Exception(CommonError::message(CommonError::EMPTY_FORMATS_ASSET));
|
||||
}
|
||||
}
|
||||
66
plugin/onlyoffice/lib/onlyofficeHttpClient.php
Normal file
66
plugin/onlyoffice/lib/onlyofficeHttpClient.php
Normal file
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
/**
|
||||
* (c) Copyright Ascensio System SIA 2025.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (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
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
use GuzzleHttp\Client;
|
||||
use GuzzleHttp\Exception\RequestException;
|
||||
use Onlyoffice\DocsIntegrationSdk\Service\Request\HttpClientInterface;
|
||||
|
||||
class OnlyofficeHttpClient implements HttpClientInterface
|
||||
{
|
||||
private $responseStatusCode;
|
||||
private $responseBody;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->responseStatusCode = null;
|
||||
$this->responseBody = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Request to Document Server with turn off verification.
|
||||
*
|
||||
* @param string $url - request address
|
||||
* @param array $method - request method
|
||||
* @param array $opts - request options
|
||||
*/
|
||||
public function request($url, $method = 'GET', $opts = [])
|
||||
{
|
||||
$httpClient = new Client(['base_uri' => $url]);
|
||||
try {
|
||||
$response = $httpClient->request($method, $url, $opts);
|
||||
$this->responseBody = $response->getBody()->getContents();
|
||||
$this->responseStatusCode = $response->getStatusCode();
|
||||
} catch (RequestException $requestException) {
|
||||
throw new Exception($requestException->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of responseStatusCode.
|
||||
*/
|
||||
public function getStatusCode()
|
||||
{
|
||||
return $this->responseStatusCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of responseBody.
|
||||
*/
|
||||
public function getBody()
|
||||
{
|
||||
return $this->responseBody;
|
||||
}
|
||||
}
|
||||
45
plugin/onlyoffice/lib/onlyofficeItemActionObserver.php
Normal file
45
plugin/onlyoffice/lib/onlyofficeItemActionObserver.php
Normal file
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
/**
|
||||
* (c) Copyright Ascensio System SIA 2025.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (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
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
class OnlyofficeItemActionObserver extends HookObserver implements HookDocumentItemActionObserverInterface
|
||||
{
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct(
|
||||
'plugin/onlyoffice/lib/onlyofficePlugin.php',
|
||||
'onlyoffice'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a Onlyoffice edit tools when the Chamilo loads document items.
|
||||
*
|
||||
* @param HookDocumentItemActionEventInterface $event - the hook event
|
||||
*/
|
||||
public function notifyDocumentItemAction(HookDocumentItemActionEventInterface $event)
|
||||
{
|
||||
$data = $event->getEventData();
|
||||
|
||||
if (HOOK_EVENT_TYPE_PRE === $data['type']) {
|
||||
$data['actions'][] = OnlyofficeTools::getButtonEdit($data);
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
}
|
||||
41
plugin/onlyoffice/lib/onlyofficeItemViewObserver.php
Normal file
41
plugin/onlyoffice/lib/onlyofficeItemViewObserver.php
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
/**
|
||||
* (c) Copyright Ascensio System SIA 2025.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (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
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
class OnlyofficeItemViewObserver extends HookObserver implements HookDocumentItemViewObserverInterface
|
||||
{
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct(
|
||||
'plugin/onlyoffice/lib/onlyofficePlugin.php',
|
||||
'onlyoffice'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a Onlyoffice view tools when the Chamilo loads document items.
|
||||
*
|
||||
* @param HookDocumentItemViewEventInterface $event - the hook event
|
||||
*/
|
||||
public function notifyDocumentItemView(HookDocumentItemViewEventInterface $event): string
|
||||
{
|
||||
$data = $event->getEventData();
|
||||
|
||||
return OnlyofficeTools::getButtonView($data);
|
||||
}
|
||||
}
|
||||
44
plugin/onlyoffice/lib/onlyofficeJwtManager.php
Normal file
44
plugin/onlyoffice/lib/onlyofficeJwtManager.php
Normal file
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
/**
|
||||
* (c) Copyright Ascensio System SIA 2025.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (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
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
use Firebase\JWT\JWT;
|
||||
use Firebase\JWT\Key;
|
||||
use Onlyoffice\DocsIntegrationSdk\Manager\Security\JwtManager;
|
||||
|
||||
class OnlyofficeJwtManager extends JwtManager
|
||||
{
|
||||
public function __construct($settingsManager)
|
||||
{
|
||||
parent::__construct($settingsManager);
|
||||
}
|
||||
|
||||
public function encode($payload, $key, $algorithm = 'HS256')
|
||||
{
|
||||
return JWT::encode($payload, $key, $algorithm);
|
||||
}
|
||||
|
||||
public function decode($token, $key, $algorithm = 'HS256')
|
||||
{
|
||||
$payload = JWT::decode($token, new Key($key, $algorithm));
|
||||
|
||||
return $payload;
|
||||
}
|
||||
|
||||
public function getHash($object)
|
||||
{
|
||||
return $this->encode($object, api_get_security_key());
|
||||
}
|
||||
}
|
||||
143
plugin/onlyoffice/lib/onlyofficePlugin.php
Normal file
143
plugin/onlyoffice/lib/onlyofficePlugin.php
Normal file
@@ -0,0 +1,143 @@
|
||||
<?php
|
||||
/**
|
||||
* (c) Copyright Ascensio System SIA 2025.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (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
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Plugin class for the Onlyoffice plugin.
|
||||
*
|
||||
* @author Asensio System SIA
|
||||
*/
|
||||
class OnlyofficePlugin extends Plugin implements HookPluginInterface
|
||||
{
|
||||
/**
|
||||
* OnlyofficePlugin name.
|
||||
*/
|
||||
private $pluginName = 'onlyoffice';
|
||||
|
||||
/**
|
||||
* OnlyofficePlugin constructor.
|
||||
*/
|
||||
protected function __construct()
|
||||
{
|
||||
parent::__construct(
|
||||
'1.5.0',
|
||||
'Asensio System SIA',
|
||||
[
|
||||
'enable_onlyoffice_plugin' => 'boolean',
|
||||
'document_server_url' => 'text',
|
||||
'jwt_secret' => 'text',
|
||||
'jwt_header' => 'text',
|
||||
'document_server_internal' => 'text',
|
||||
'storage_url' => 'text',
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create OnlyofficePlugin object.
|
||||
*/
|
||||
public static function create(): OnlyofficePlugin
|
||||
{
|
||||
static $result = null;
|
||||
|
||||
return $result ?: $result = new self();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method install the plugin tables.
|
||||
*/
|
||||
public function install()
|
||||
{
|
||||
$this->installHook();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method drops the plugin tables.
|
||||
*/
|
||||
public function uninstall()
|
||||
{
|
||||
$this->uninstallHook();
|
||||
}
|
||||
|
||||
/**
|
||||
* Install the "create" hooks.
|
||||
*/
|
||||
public function installHook()
|
||||
{
|
||||
$itemActionObserver = OnlyofficeItemActionObserver::create();
|
||||
HookDocumentItemAction::create()->attach($itemActionObserver);
|
||||
|
||||
$actionObserver = OnlyofficeActionObserver::create();
|
||||
HookDocumentAction::create()->attach($actionObserver);
|
||||
|
||||
$viewObserver = OnlyofficeItemViewObserver::create();
|
||||
HookDocumentItemView::create()->attach($viewObserver);
|
||||
}
|
||||
|
||||
/**
|
||||
* Uninstall the "create" hooks.
|
||||
*/
|
||||
public function uninstallHook()
|
||||
{
|
||||
$itemActionObserver = OnlyofficeItemActionObserver::create();
|
||||
HookDocumentItemAction::create()->detach($itemActionObserver);
|
||||
|
||||
$actionObserver = OnlyofficeActionObserver::create();
|
||||
HookDocumentAction::create()->detach($actionObserver);
|
||||
|
||||
$viewObserver = OnlyofficeItemViewObserver::create();
|
||||
HookDocumentItemView::create()->detach($viewObserver);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get link to plugin settings.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getConfigLink()
|
||||
{
|
||||
return api_get_path(WEB_PATH).'main/admin/configure_plugin.php?name='.$this->pluginName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get plugin name.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getPluginName()
|
||||
{
|
||||
return $this->pluginName;
|
||||
}
|
||||
|
||||
public static function isExtensionAllowed(string $extension): bool
|
||||
{
|
||||
$officeExtensions = [
|
||||
'ppt',
|
||||
'pptx',
|
||||
'odp',
|
||||
'xls',
|
||||
'xlsx',
|
||||
'ods',
|
||||
'csv',
|
||||
'doc',
|
||||
'docx',
|
||||
'odt',
|
||||
'pdf',
|
||||
];
|
||||
|
||||
return in_array($extension, $officeExtensions);
|
||||
}
|
||||
}
|
||||
150
plugin/onlyoffice/lib/onlyofficeSettingsFormBuilder.php
Normal file
150
plugin/onlyoffice/lib/onlyofficeSettingsFormBuilder.php
Normal file
@@ -0,0 +1,150 @@
|
||||
<?php
|
||||
/**
|
||||
* (c) Copyright Ascensio System SIA 2025.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (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
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
require_once __DIR__.'/../../../main/inc/global.inc.php';
|
||||
|
||||
class OnlyofficeSettingsFormBuilder
|
||||
{
|
||||
/**
|
||||
* Directory with layouts.
|
||||
*/
|
||||
private const ONLYOFFICE_LAYOUT_DIR = '/onlyoffice/layout/';
|
||||
|
||||
/**
|
||||
* Build OnlyofficePlugin settings form.
|
||||
*
|
||||
* @return FormValidator
|
||||
*/
|
||||
public static function buildSettingsForm(OnlyofficeAppsettings $settingsManager)
|
||||
{
|
||||
$plugin = $settingsManager->plugin;
|
||||
$demoData = $settingsManager->getDemoData();
|
||||
$plugin_info = $plugin->get_info();
|
||||
$message = '';
|
||||
$connectDemoCheckbox = $plugin_info['settings_form']->createElement(
|
||||
'checkbox',
|
||||
'connect_demo',
|
||||
'',
|
||||
$plugin->get_lang('connect_demo')
|
||||
);
|
||||
if (true === !$demoData['available']) {
|
||||
$message = $plugin->get_lang('demoPeriodIsOver');
|
||||
$connectDemoCheckbox->setAttribute('disabled');
|
||||
} else {
|
||||
if ($settingsManager->useDemo()) {
|
||||
$message = $plugin->get_lang('demoUsingMessage');
|
||||
$connectDemoCheckbox->setChecked(true);
|
||||
} else {
|
||||
$message = $plugin->get_lang('demoPrevMessage');
|
||||
}
|
||||
}
|
||||
$demoServerMessageHtml = Display::return_message(
|
||||
$message,
|
||||
'info'
|
||||
);
|
||||
$bannerTemplate = self::buildTemplate('get_docs_cloud_banner', [
|
||||
'docs_cloud_link' => $settingsManager->getLinkToDocs(),
|
||||
'banner_title' => $plugin->get_lang('DocsCloudBannerTitle'),
|
||||
'banner_main_text' => $plugin->get_lang('DocsCloudBannerMain'),
|
||||
'banner_button_text' => $plugin->get_lang('DocsCloudBannerButton'),
|
||||
]);
|
||||
$plugin_info['settings_form']->insertElementBefore($connectDemoCheckbox, 'submit_button');
|
||||
$demoServerMessage = $plugin_info['settings_form']->createElement('html', $demoServerMessageHtml);
|
||||
$plugin_info['settings_form']->insertElementBefore($demoServerMessage, 'submit_button');
|
||||
$banner = $plugin_info['settings_form']->createElement('html', $bannerTemplate);
|
||||
$plugin_info['settings_form']->insertElementBefore($banner, 'submit_button');
|
||||
|
||||
return $plugin_info['settings_form'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate OnlyofficePlugin settings form.
|
||||
*
|
||||
* @param OnlyofficeAppsettings $settingsManager - Onlyoffice SettingsManager
|
||||
*
|
||||
* @return OnlyofficePlugin
|
||||
*/
|
||||
public static function validateSettingsForm(OnlyofficeAppsettings $settingsManager)
|
||||
{
|
||||
$plugin = $settingsManager->plugin;
|
||||
$errorMsg = null;
|
||||
$plugin_info = $plugin->get_info();
|
||||
$result = $plugin_info['settings_form']->getSubmitValues();
|
||||
unset($result['submit_button']);
|
||||
$settingsManager->newSettings = $result;
|
||||
if (!$settingsManager->selectDemo(true === (bool) $result['connect_demo'])) {
|
||||
$errorMsg = $plugin->get_lang('demoPeriodIsOver');
|
||||
self::displayError($errorMsg, $plugin->getConfigLink());
|
||||
}
|
||||
if (!empty($settingsManager->getDocumentServerUrl())) {
|
||||
if (false === (bool) $result['connect_demo']) {
|
||||
$httpClient = new OnlyofficeHttpClient();
|
||||
$jwtManager = new OnlyofficeJwtManager($settingsManager);
|
||||
$requestService = new OnlyofficeAppRequests($settingsManager, $httpClient, $jwtManager);
|
||||
list($error, $version) = $requestService->checkDocServiceUrl();
|
||||
if (!empty($error)) {
|
||||
$errorMsg = $plugin->get_lang('connectionError').'('.$error.')'.(!empty($version) ? '(Version '.$version.')' : '');
|
||||
self::displayError($errorMsg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $plugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build HTML-template.
|
||||
*
|
||||
* @param string $templateName - template name (*.tpl)
|
||||
* @param array $params - parameters to assign
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private static function buildTemplate($templateName, $params = [])
|
||||
{
|
||||
$tpl = new Template('', false, false, false, false, false, false);
|
||||
if (!empty($params)) {
|
||||
foreach ($params as $key => $param) {
|
||||
$tpl->assign($key, $param);
|
||||
}
|
||||
}
|
||||
$parsedTemplate = $tpl->fetch(self::ONLYOFFICE_LAYOUT_DIR.$templateName.'.tpl');
|
||||
|
||||
return $parsedTemplate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display error messahe.
|
||||
*
|
||||
* @param string $errorMessage - error message
|
||||
* @param string $location - header location
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private static function displayError($errorMessage, $location = null)
|
||||
{
|
||||
Display::addFlash(
|
||||
Display::return_message(
|
||||
$errorMessage,
|
||||
'error'
|
||||
)
|
||||
);
|
||||
if (null !== $location) {
|
||||
header('Location: '.$location);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
}
|
||||
233
plugin/onlyoffice/lib/onlyofficeTools.php
Normal file
233
plugin/onlyoffice/lib/onlyofficeTools.php
Normal file
@@ -0,0 +1,233 @@
|
||||
<?php
|
||||
/**
|
||||
* (c) Copyright Ascensio System SIA 2025.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (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
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
class OnlyofficeTools
|
||||
{
|
||||
/**
|
||||
* Return button-link to onlyoffice editor for file.
|
||||
*/
|
||||
public static function getButtonEdit(array $document_data): string
|
||||
{
|
||||
$plugin = OnlyofficePlugin::create();
|
||||
|
||||
$appSettings = new OnlyofficeAppsettings($plugin);
|
||||
$documentManager = new OnlyofficeDocumentManager($appSettings, []);
|
||||
$isEnable = 'true' === $plugin->get('enable_onlyoffice_plugin');
|
||||
if (!$isEnable) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$urlToEdit = api_get_path(WEB_PLUGIN_PATH).'onlyoffice/editor.php';
|
||||
|
||||
$extension = strtolower(pathinfo($document_data['title'], PATHINFO_EXTENSION));
|
||||
|
||||
$canEdit = null !== $documentManager->getFormatInfo($extension) ? $documentManager->getFormatInfo($extension)->isEditable() : false;
|
||||
$canView = null !== $documentManager->getFormatInfo($extension) ? $documentManager->getFormatInfo($extension)->isViewable() : false;
|
||||
|
||||
$groupId = api_get_group_id();
|
||||
if (!empty($groupId)) {
|
||||
$urlToEdit = $urlToEdit.'?groupId='.$groupId.'&';
|
||||
} else {
|
||||
$urlToEdit = $urlToEdit.'?';
|
||||
}
|
||||
|
||||
$documentId = $document_data['id'];
|
||||
$urlToEdit = $urlToEdit.'docId='.$documentId;
|
||||
|
||||
if ($canEdit || $canView) {
|
||||
$tooltip = $plugin->get_lang('openByOnlyoffice');
|
||||
if ('pdf' === $extension) {
|
||||
$tooltip = $plugin->get_lang('fillInFormInOnlyoffice');
|
||||
}
|
||||
|
||||
return Display::url(
|
||||
Display::return_icon(
|
||||
'../../plugin/onlyoffice/resources/onlyoffice_edit.png',
|
||||
$tooltip
|
||||
),
|
||||
$urlToEdit
|
||||
);
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Return button-link to onlyoffice editor for view file.
|
||||
*/
|
||||
public static function getButtonView(array $document_data): string
|
||||
{
|
||||
$plugin = OnlyofficePlugin::create();
|
||||
$appSettings = new OnlyofficeAppsettings($plugin);
|
||||
$documentManager = new OnlyofficeDocumentManager($appSettings, []);
|
||||
|
||||
$isEnable = 'true' === $plugin->get('enable_onlyoffice_plugin');
|
||||
if (!$isEnable) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$urlToEdit = api_get_path(WEB_PLUGIN_PATH).'onlyoffice/editor.php';
|
||||
|
||||
$sessionId = api_get_session_id();
|
||||
$courseInfo = api_get_course_info();
|
||||
$documentId = $document_data['id'];
|
||||
$userId = api_get_user_id();
|
||||
|
||||
$docInfo = DocumentManager::get_document_data_by_id($documentId, $courseInfo['code'], false, $sessionId);
|
||||
|
||||
$extension = strtolower(pathinfo($document_data['title'], PATHINFO_EXTENSION));
|
||||
$canView = null !== $documentManager->getFormatInfo($extension) ? $documentManager->getFormatInfo($extension)->isViewable() : false;
|
||||
|
||||
$isGroupAccess = false;
|
||||
$groupId = api_get_group_id();
|
||||
if (!empty($groupId)) {
|
||||
$groupProperties = GroupManager::get_group_properties($groupId);
|
||||
$docInfoGroup = api_get_item_property_info(api_get_course_int_id(), 'document', $documentId, $sessionId);
|
||||
$isGroupAccess = GroupManager::allowUploadEditDocument($userId, $courseInfo['code'], $groupProperties, $docInfoGroup);
|
||||
|
||||
$urlToEdit = $urlToEdit.'?groupId='.$groupId.'&';
|
||||
} else {
|
||||
$urlToEdit = $urlToEdit.'?';
|
||||
}
|
||||
|
||||
$isAllowToEdit = api_is_allowed_to_edit(true, true);
|
||||
$isMyDir = DocumentManager::is_my_shared_folder($userId, $docInfo['absolute_parent_path'], $sessionId);
|
||||
|
||||
$accessRights = $isAllowToEdit || $isMyDir || $isGroupAccess;
|
||||
|
||||
$urlToEdit = $urlToEdit.'docId='.$documentId;
|
||||
|
||||
if ($canView && !$accessRights) {
|
||||
return Display::url(Display::return_icon('../../plugin/onlyoffice/resources/onlyoffice_view.png', $plugin->get_lang('openByOnlyoffice')), $urlToEdit, ['style' => 'float:right; margin-right:8px']);
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Return button-link to onlyoffice create new.
|
||||
*/
|
||||
public static function getButtonCreateNew(): string
|
||||
{
|
||||
$plugin = OnlyofficePlugin::create();
|
||||
|
||||
$isEnable = 'true' === $plugin->get('enable_onlyoffice_plugin');
|
||||
if (!$isEnable) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$courseId = api_get_course_int_id();
|
||||
$sessionId = api_get_session_id();
|
||||
$groupId = api_get_group_id();
|
||||
$userId = api_get_user_id();
|
||||
|
||||
$urlToCreate = api_get_path(WEB_PLUGIN_PATH).'onlyoffice/create.php'
|
||||
.'?folderId='.(empty($_GET['id']) ? '0' : (int) $_GET['id'])
|
||||
.'&courseId='.$courseId
|
||||
.'&groupId='.$groupId
|
||||
.'&sessionId='.$sessionId
|
||||
.'&userId='.$userId;
|
||||
|
||||
return Display::url(
|
||||
Display::return_icon(
|
||||
'../../plugin/onlyoffice/resources/onlyoffice_create.png',
|
||||
$plugin->get_lang('createNew')
|
||||
),
|
||||
$urlToCreate
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return path to OnlyOffice viewer for a given file.
|
||||
*/
|
||||
public static function getPathToView($fileReference, bool $showHeaders = true, ?int $exeId = null, ?int $questionId = null, bool $isReadOnly = false): string
|
||||
{
|
||||
$plugin = OnlyofficePlugin::create();
|
||||
$appSettings = new OnlyofficeAppsettings($plugin);
|
||||
$documentManager = new OnlyofficeDocumentManager($appSettings, []);
|
||||
|
||||
$isEnable = 'true' === $plugin->get('enable_onlyoffice_plugin');
|
||||
if (!$isEnable) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$urlToEdit = api_get_path(WEB_PLUGIN_PATH).'onlyoffice/editor.php';
|
||||
$queryString = $_SERVER['QUERY_STRING'];
|
||||
$isExercise = str_contains($queryString, 'exerciseId=');
|
||||
|
||||
if (is_numeric($fileReference)) {
|
||||
$documentId = (int) $fileReference;
|
||||
$courseInfo = api_get_course_info();
|
||||
$sessionId = api_get_session_id();
|
||||
$userId = api_get_user_id();
|
||||
|
||||
$docInfo = DocumentManager::get_document_data_by_id($documentId, $courseInfo['code'], false, $sessionId);
|
||||
if (!$docInfo) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$extension = strtolower(pathinfo($docInfo['path'], PATHINFO_EXTENSION));
|
||||
$canView = null !== $documentManager->getFormatInfo($extension) ? $documentManager->getFormatInfo($extension)->isViewable() : false;
|
||||
|
||||
$isGroupAccess = false;
|
||||
$groupId = api_get_group_id();
|
||||
if (!empty($groupId)) {
|
||||
$groupProperties = GroupManager::get_group_properties($groupId);
|
||||
$docInfoGroup = api_get_item_property_info(api_get_course_int_id(), 'document', $documentId, $sessionId);
|
||||
$isGroupAccess = GroupManager::allowUploadEditDocument($userId, $courseInfo['code'], $groupProperties, $docInfoGroup);
|
||||
|
||||
$urlToEdit .= '?'.api_get_cidreq().'&';
|
||||
} else {
|
||||
$urlToEdit .= '?'.api_get_cidreq().'&';
|
||||
}
|
||||
|
||||
$isMyDir = DocumentManager::is_my_shared_folder($userId, $docInfo['absolute_parent_path'], $sessionId);
|
||||
$accessRights = $isMyDir || $isGroupAccess;
|
||||
|
||||
$urlToEdit .= 'docId='.$documentId;
|
||||
if (false === $showHeaders) {
|
||||
$urlToEdit .= '&nh=1';
|
||||
}
|
||||
|
||||
if ($canView && !$accessRights) {
|
||||
return $urlToEdit;
|
||||
}
|
||||
} else {
|
||||
$urlToEdit .= '?'.$queryString.'&doc='.urlencode($fileReference);
|
||||
if ($isExercise) {
|
||||
$urlToEdit .= '&type=exercise';
|
||||
if ($exeId) {
|
||||
$urlToEdit .= '&exeId='.$exeId;
|
||||
}
|
||||
|
||||
if ($questionId) {
|
||||
$urlToEdit .= '&questionId='.$questionId;
|
||||
}
|
||||
}
|
||||
if (false === $showHeaders) {
|
||||
$urlToEdit .= '&nh=1';
|
||||
}
|
||||
|
||||
if (true === $isReadOnly) {
|
||||
$urlToEdit .= '&readOnly=1';
|
||||
}
|
||||
|
||||
return $urlToEdit;
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
}
|
||||
36
plugin/onlyoffice/lib/templateManager.php
Normal file
36
plugin/onlyoffice/lib/templateManager.php
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
/**
|
||||
* (c) Copyright Ascensio System SIA 2025.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (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
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
require_once __DIR__.'/../../../main/inc/global.inc.php';
|
||||
|
||||
class TemplateManager
|
||||
{
|
||||
/**
|
||||
* Return path to template new file.
|
||||
*/
|
||||
public static function getEmptyTemplate($fileExtension): string
|
||||
{
|
||||
$langInfo = LangManager::getLangUser();
|
||||
$lang = $langInfo['isocode'];
|
||||
$templateFolder = api_get_path(SYS_PLUGIN_PATH).'onlyoffice/assets/';
|
||||
if (!is_dir($templateFolder.$lang)) {
|
||||
$lang = 'default';
|
||||
}
|
||||
$templateFolder = $templateFolder.$lang;
|
||||
|
||||
return $templateFolder.'/'.ltrim($fileExtension, '.').'.zip';
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user