This commit is contained in:
Xes
2025-08-14 22:39:38 +02:00
parent 3641e93527
commit 5403f346e3
3370 changed files with 327179 additions and 0 deletions

View 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;
}
}

View 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;
}
}
}

View 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;
}
}

View 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]);
}
}

View 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];
}
}

View 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;
}
}

View 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];
}
}

View 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));
}
}

View 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;
}
}

View 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;
}
}
}

View 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);
}
}

View 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());
}
}

View 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);
}
}

View 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;
}
}
}

View 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 '';
}
}

View 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';
}
}