diff options
author | Sergey Linnik <sergey.linnik@onlyoffice.com> | 2021-11-02 15:53:00 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-11-02 15:53:00 +0300 |
commit | 212be8a29299f7ed87a320fb5517874220e2de4d (patch) | |
tree | 158ada5e86f17dbba9267e21e0ab2aa243c1183f | |
parent | d7cdf800343829f1b96db5662380985eb2c566f3 (diff) | |
parent | 9c3b677e6d681978b7e225144852da8ed86b57eb (diff) |
Merge pull request #542 from ONLYOFFICE/developv7.2.0
Release/7.2.0
47 files changed, 1673 insertions, 759 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index c304915..d41022e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,16 @@ # Change Log +## 7.2.0 +## Added +- set favicon on editor page +- versions restore from editor + +## Changed +- fixed privacy rules for get users when mention +- document server v6.0 and earlier is no longer supported +- editing by link only for available groups +- open share link directly + ## 7.1.2 ## Changed - fix editing from mobile app @@ -25,13 +25,13 @@ ONLYOFFICE Document Server and Nextcloud can be installed either on different co You can install free Community version of ONLYOFFICE Docs or scalable Enterprise Edition with pro features. -To install free Community version, use [Docker](https://github.com/onlyoffice/Docker-DocumentServer) (recommended) or follow [these instructions](https://helpcenter.onlyoffice.com/server/linux/document/linux-installation.aspx) for Debian, Ubuntu, or derivatives. +To install free Community version, use [Docker](https://github.com/onlyoffice/Docker-DocumentServer) (recommended) or follow [these instructions](https://helpcenter.onlyoffice.com/installation/docs-community-install-ubuntu.aspx) for Debian, Ubuntu, or derivatives. -To install Enterprise Edition, follow instructions [here](https://helpcenter.onlyoffice.com/server/integration-edition/index.aspx). +To install Enterprise Edition, follow instructions [here](https://helpcenter.onlyoffice.com/installation/docs-enterprise-index.aspx). Community Edition vs Enterprise Edition comparison can be found [here](#onlyoffice-docs-editions). -To use ONLYOFFICE behind a proxy, please refer to [this article](https://helpcenter.onlyoffice.com/server/document/document-server-proxy.aspx). +To use ONLYOFFICE behind a proxy, please refer to [this article](https://helpcenter.onlyoffice.com/installation/docs-community-proxy.aspx). You can also use our **[Docker installation](https://github.com/ONLYOFFICE/docker-onlyoffice-nextcloud)** to install pre-configured Document Server (free version) and Nextcloud with a couple of commands. @@ -164,7 +164,7 @@ The table below will help you to make the right choice. | Pricing and licensing | Community Edition | Enterprise Edition | | ------------- | ------------- | ------------- | -| | [Get it now](https://www.onlyoffice.com/download.aspx?utm_source=github&utm_medium=cpc&utm_campaign=GitHubNextcloud) | [Start Free Trial](https://www.onlyoffice.com/enterprise-edition-free.aspx?utm_source=github&utm_medium=cpc&utm_campaign=GitHubNextcloud) | +| | [Get it now](https://www.onlyoffice.com/download-docs.aspx?utm_source=github&utm_medium=cpc&utm_campaign=GitHubNextcloud#docs-community) | [Start Free Trial](https://www.onlyoffice.com/download-docs.aspx?utm_source=github&utm_medium=cpc&utm_campaign=GitHubNextcloud#docs-enterprise) | | Cost | FREE | [Go to the pricing page](https://www.onlyoffice.com/docs-enterprise-prices.aspx?utm_source=github&utm_medium=cpc&utm_campaign=GitHubNextcloud) | | Simultaneous connections | up to 20 maximum | As in chosen pricing plan | | Number of users | up to 20 recommended | As in chosen pricing plan | @@ -218,7 +218,7 @@ The table below will help you to make the right choice. | Transitions | + | + | | Presenter mode | + | + | | Notes | + | + | -| | [Get it now](https://www.onlyoffice.com/download.aspx?utm_source=github&utm_medium=cpc&utm_campaign=GitHubNextcloud) | [Start Free Trial](https://www.onlyoffice.com/enterprise-edition-free.aspx?utm_source=github&utm_medium=cpc&utm_campaign=GitHubNextcloud) | +| | [Get it now](https://www.onlyoffice.com/download-docs.aspx?utm_source=github&utm_medium=cpc&utm_campaign=GitHubNextcloud#docs-community) | [Start Free Trial](https://www.onlyoffice.com/download-docs.aspx?utm_source=github&utm_medium=cpc&utm_campaign=GitHubNextcloud#docs-enterprise) | \* It's possible to add documents for comparison from your local drive, from URL and from Nextcloud storage. diff --git a/appinfo/application.php b/appinfo/application.php index 26769ea..f96eee5 100644 --- a/appinfo/application.php +++ b/appinfo/application.php @@ -25,25 +25,31 @@ use OCP\AppFramework\App; use OCP\AppFramework\Bootstrap\IBootContext; use OCP\AppFramework\Bootstrap\IBootstrap; use OCP\AppFramework\Bootstrap\IRegistrationContext; -use OCP\AppFramework\Http\ContentSecurityPolicy; use OCP\Dashboard\RegisterWidgetEvent; use OCP\DirectEditing\RegisterDirectEditorEvent; use OCP\Files\Template\FileCreatedFromTemplateEvent; use OCP\Files\Template\ITemplateManager; use OCP\Files\Template\TemplateFileCreator; +use OCA\Files\Event\LoadAdditionalScriptsEvent; use OCP\IL10N; use OCP\IPreview; use OCP\ITagManager; use OCP\Notification\IManager; -use OCP\Util; +use OCA\Files_Sharing\Event\BeforeTemplateRenderedEvent; use OCA\Viewer\Event\LoadViewer; use OCA\Onlyoffice\AppConfig; use OCA\Onlyoffice\Controller\CallbackController; use OCA\Onlyoffice\Controller\EditorController; +use OCA\Onlyoffice\Controller\EditorApiController; use OCA\Onlyoffice\Controller\SettingsController; use OCA\Onlyoffice\Controller\TemplateController; +use OCA\Onlyoffice\Listeners\FilesListener; +use OCA\Onlyoffice\Listeners\FileSharingListener; +use OCA\Onlyoffice\Listeners\DirectEditorListener; +use OCA\Onlyoffice\Listeners\ViewerListener; +use OCA\Onlyoffice\Listeners\WidgetListener; use OCA\Onlyoffice\Crypt; use OCA\Onlyoffice\DirectEditor; use OCA\Onlyoffice\Hooks; @@ -147,6 +153,24 @@ class Application extends App implements IBootstrap { $this->crypt, $c->get("IManager"), $c->get("Session"), + $c->get("GroupManager") + ); + }); + + $context->registerService("EditorApiController", function (ContainerInterface $c) { + return new EditorApiController( + $c->get("AppName"), + $c->get("Request"), + $c->get("RootStorage"), + $c->get("UserSession"), + $c->get("UserManager"), + $c->get("URLGenerator"), + $c->get("L10N"), + $c->get("Logger"), + $this->appConfig, + $this->crypt, + $c->get("IManager"), + $c->get("Session"), $c->get(ITagManager::class) ); }); @@ -176,6 +200,12 @@ class Application extends App implements IBootstrap { ); }); + $context->registerEventListener(LoadAdditionalScriptsEvent::class, FilesListener::class); + $context->registerEventListener(RegisterDirectEditorEvent::class, DirectEditorListener::class); + $context->registerEventListener(LoadViewer::class, ViewerListener::class); + $context->registerEventListener(BeforeTemplateRenderedEvent::class, FileSharingListener::class); + $context->registerEventListener(RegisterWidgetEvent::class, WidgetListener::class); + if (interface_exists("OCP\Files\Template\ICustomTemplateProvider")) { $context->registerTemplateProvider(TemplateProvider::class); } @@ -186,65 +216,6 @@ class Application extends App implements IBootstrap { $context->injectFn(function (SymfonyAdapter $eventDispatcher) { - $eventDispatcher->addListener('OCA\Files::loadAdditionalScripts', - function() { - if (!empty($this->appConfig->GetDocumentServerUrl()) - && $this->appConfig->SettingsAreSuccessful() - && $this->appConfig->isUserAllowedToUse()) { - - Util::addScript("onlyoffice", "desktop"); - Util::addScript("onlyoffice", "main"); - Util::addScript("onlyoffice", "template"); - - if ($this->appConfig->GetSameTab()) { - Util::addScript("onlyoffice", "listener"); - } - - Util::addStyle("onlyoffice", "main"); - Util::addStyle("onlyoffice", "template"); - } - }); - - $eventDispatcher->addListener(LoadViewer::class, - function () { - if (!empty($this->appConfig->GetDocumentServerUrl()) - && $this->appConfig->SettingsAreSuccessful() - && $this->appConfig->isUserAllowedToUse()) { - Util::addScript("onlyoffice", "viewer"); - Util::addScript("onlyoffice", "listener"); - - Util::addStyle("onlyoffice", "viewer"); - - $csp = new ContentSecurityPolicy(); - $csp->addAllowedFrameDomain("'self'"); - $cspManager = $this->getContainer()->getServer()->getContentSecurityPolicyManager(); - $cspManager->addDefaultPolicy($csp); - } - }); - - $eventDispatcher->addListener('OCA\Files_Sharing::loadAdditionalScripts', - function() { - if (!empty($this->appConfig->GetDocumentServerUrl()) - && $this->appConfig->SettingsAreSuccessful()) { - Util::addScript("onlyoffice", "main"); - - if ($this->appConfig->GetSameTab()) { - Util::addScript("onlyoffice", "listener"); - } - - Util::addStyle("onlyoffice", "main"); - } - }); - - $eventDispatcher->addListener(RegisterWidgetEvent::class, - function () { - if (!empty($this->appConfig->GetDocumentServerUrl()) - && $this->appConfig->SettingsAreSuccessful() - && $this->appConfig->isUserAllowedToUse()) { - Util::addScript("onlyoffice", "desktop"); - } - }); - $container = $this->getContainer(); if (class_exists("OCP\Files\Template\FileCreatedFromTemplateEvent")) { @@ -266,15 +237,6 @@ class Application extends App implements IBootstrap { return $container->query(Preview::class); }); - $eventDispatcher->addListener(RegisterDirectEditorEvent::class, - function (RegisterDirectEditorEvent $event) use ($container) { - if (!empty($this->appConfig->GetDocumentServerUrl()) - && $this->appConfig->SettingsAreSuccessful()) { - $editor = $container->query(DirectEditor::class); - $event->register($editor); - } - }); - }); $context->injectFn(function (IManager $notificationsManager) { diff --git a/appinfo/info.xml b/appinfo/info.xml index 0b47039..16592ff 100644 --- a/appinfo/info.xml +++ b/appinfo/info.xml @@ -6,10 +6,10 @@ <description>ONLYOFFICE connector allows you to view, edit and collaborate on text documents, spreadsheets and presentations within Nextcloud using ONLYOFFICE Docs. This will create a new Edit in ONLYOFFICE action within the document library for Office documents. This allows multiple users to co-author documents in real time from the familiar web interface and save the changes back to your file storage.</description> <licence>apache</licence> <author mail="dev@onlyoffice.com" homepage="https://www.onlyoffice.com/">Ascensio System SIA</author> - <version>7.1.2</version> + <version>7.2.0</version> <namespace>Onlyoffice</namespace> <types> - <filesystem/> + <prevent_group_restriction/> </types> <documentation> <admin>https://api.onlyoffice.com/editors/nextcloud</admin> diff --git a/appinfo/routes.php b/appinfo/routes.php index f4809fa..5a8030b 100644 --- a/appinfo/routes.php +++ b/appinfo/routes.php @@ -29,13 +29,13 @@ return [ ["name" => "editor#public_page", "url" => "/s/{shareToken}", "verb" => "GET"], ["name" => "editor#users", "url" => "/ajax/users", "verb" => "GET"], ["name" => "editor#mention", "url" => "/ajax/mention", "verb" => "POST"], - ["name" => "editor#config", "url" => "/ajax/config/{fileId}", "verb" => "GET"], ["name" => "editor#create", "url" => "/ajax/new", "verb" => "POST"], ["name" => "editor#convert", "url" => "/ajax/convert", "verb" => "POST"], ["name" => "editor#save", "url" => "/ajax/save", "verb" => "POST"], ["name" => "editor#url", "url" => "/ajax/url", "verb" => "GET"], ["name" => "editor#history", "url" => "/ajax/history", "verb" => "GET"], ["name" => "editor#version", "url" => "/ajax/version", "verb" => "GET"], + ["name" => "editor#restore", "url" => "/ajax/restore", "verb" => "PUT"], ["name" => "settings#save_address", "url" => "/ajax/settings/address", "verb" => "PUT"], ["name" => "settings#save_common", "url" => "/ajax/settings/common", "verb" => "PUT"], ["name" => "settings#save_watermark", "url" => "/ajax/settings/watermark", "verb" => "PUT"], @@ -47,6 +47,7 @@ return [ ], "ocs" => [ ["name" => "federation#key", "url" => "/api/v1/key", "verb" => "POST"], - ["name" => "federation#keylock", "url" => "/api/v1/keylock", "verb" => "POST"] + ["name" => "federation#keylock", "url" => "/api/v1/keylock", "verb" => "POST"], + ["name" => "editorapi#config", "url" => "/api/v1/config/{fileId}", "verb" => "GET"] ] ];
\ No newline at end of file diff --git a/controller/editorapicontroller.php b/controller/editorapicontroller.php new file mode 100644 index 0000000..e7c25ae --- /dev/null +++ b/controller/editorapicontroller.php @@ -0,0 +1,816 @@ +<?php +/** + * + * (c) Copyright Ascensio System SIA 2021 + * + * 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. + * + */ + +namespace OCA\Onlyoffice\Controller; + +use OCP\AppFramework\OCSController; +use OCP\AppFramework\Http\JSONResponse; +use OCP\AppFramework\QueryException; +use OCP\Constants; +use OCP\Files\File; +use OCP\Files\Folder; +use OCP\Files\IRootFolder; +use OCP\IL10N; +use OCP\ILogger; +use OCP\IRequest; +use OCP\ISession; +use OCP\ITags; +use OCP\ITagManager; +use OCP\IURLGenerator; +use OCP\IUser; +use OCP\IUserManager; +use OCP\IUserSession; +use OCP\Share\IManager; + +use OCA\Files_Versions\Versions\IVersionManager; +use OCA\FilesLock\Service\LockService; +use OCA\FilesLock\Exceptions\LockNotFoundException; + +use OCA\Onlyoffice\AppConfig; +use OCA\Onlyoffice\Crypt; +use OCA\Onlyoffice\DocumentService; +use OCA\Onlyoffice\FileUtility; +use OCA\Onlyoffice\TemplateManager; + +/** + * Controller with the main functions + */ +class EditorApiController extends OCSController { + + /** + * Current user session + * + * @var IUserSession + */ + private $userSession; + + /** + * User manager + * + * @var IUserManager + */ + private $userManager; + + /** + * Root folder + * + * @var IRootFolder + */ + private $root; + + /** + * Url generator service + * + * @var IURLGenerator + */ + private $urlGenerator; + + /** + * l10n service + * + * @var IL10N + */ + private $trans; + + /** + * Logger + * + * @var ILogger + */ + private $logger; + + /** + * Application configuration + * + * @var AppConfig + */ + private $config; + + /** + * Hash generator + * + * @var Crypt + */ + private $crypt; + + /** + * File utility + * + * @var FileUtility + */ + private $fileUtility; + + /** + * File version manager + * + * @var IVersionManager + */ + private $versionManager; + + /** + * Tag manager + * + * @var ITagManager + */ + private $tagManager; + + /** + * Mobile regex from https://github.com/ONLYOFFICE/CommunityServer/blob/v9.1.1/web/studio/ASC.Web.Studio/web.appsettings.config#L35 + */ + const USER_AGENT_MOBILE = "/android|avantgo|playbook|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od|ad)|iris|kindle|lge |maemo|midp|mmp|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\\/|plucker|pocket|psp|symbian|treo|up\\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i"; + + /** + * @param string $AppName - application name + * @param IRequest $request - request object + * @param IRootFolder $root - root folder + * @param IUserSession $userSession - current user session + * @param IUserManager $userManager - user manager + * @param IURLGenerator $urlGenerator - url generator service + * @param IL10N $trans - l10n service + * @param ILogger $logger - logger + * @param AppConfig $config - application configuration + * @param Crypt $crypt - hash generator + * @param IManager $shareManager - Share manager + * @param ISession $ISession - Session + * @param ITagManager $tagManager - Tag manager + */ + public function __construct($AppName, + IRequest $request, + IRootFolder $root, + IUserSession $userSession, + IUserManager $userManager, + IURLGenerator $urlGenerator, + IL10N $trans, + ILogger $logger, + AppConfig $config, + Crypt $crypt, + IManager $shareManager, + ISession $session, + ITagManager $tagManager + ) { + parent::__construct($AppName, $request); + + $this->userSession = $userSession; + $this->userManager = $userManager; + $this->root = $root; + $this->urlGenerator = $urlGenerator; + $this->trans = $trans; + $this->logger = $logger; + $this->config = $config; + $this->crypt = $crypt; + $this->tagManager = $tagManager; + + if (\OC::$server->getAppManager()->isInstalled("files_versions")) { + try { + $this->versionManager = \OC::$server->query(IVersionManager::class); + } catch (QueryException $e) { + $this->logger->logException($e, ["message" => "VersionManager init error", "app" => $this->appName]); + } + } + + $this->fileUtility = new FileUtility($AppName, $trans, $logger, $config, $shareManager, $session); + } + + /** + * Collecting the file parameters for the document service + * + * @param integer $fileId - file identifier + * @param string $filePath - file path + * @param string $shareToken - access token + * @param string $directToken - direct token + * @param integer $version - file version + * @param bool $inframe - open in frame + * @param bool $desktop - desktop label + * @param string $guestName - nickname not logged user + * @param bool $template - file is template + * @param string $anchor - anchor for file content + * + * @return JSONResponse + * + * @NoAdminRequired + * @PublicPage + */ + public function config($fileId, $filePath = null, $shareToken = null, $directToken = null, $version = 0, $inframe = false, $desktop = false, $guestName = null, $template = false, $anchor = null) { + + if (!empty($directToken)) { + list ($directData, $error) = $this->crypt->ReadHash($directToken); + if ($directData === null) { + $this->logger->error("Config for directEditor with empty or not correct hash: $error", ["app" => $this->appName]); + return new JSONResponse(["error" => $this->trans->t("Not permitted")]); + } + if ($directData->action !== "direct") { + $this->logger->error("Config for directEditor with other data", ["app" => $this->appName]); + return new JSONResponse(["error" => $this->trans->t("Invalid request")]); + } + + $fileId = $directData->fileId; + $userId = $directData->userId; + if ($this->userSession->isLoggedIn() + && $userId === $this->userSession->getUser()->getUID()) { + $redirectUrl = $this->urlGenerator->linkToRouteAbsolute($this->appName . ".editor.index", + [ + "fileId" => $fileId, + "filePath" => $filePath + ]); + return new JSONResponse(["redirectUrl" => $redirectUrl]); + } + + $user = $this->userManager->get($userId); + } else { + $user = $this->userSession->getUser(); + $userId = null; + if (!empty($user)) { + $userId = $user->getUID(); + } + } + + list ($file, $error, $share) = empty($shareToken) ? $this->getFile($userId, $fileId, $filePath, $template) : $this->fileUtility->getFileByToken($fileId, $shareToken); + + if (isset($error)) { + $this->logger->error("Config: $fileId $error", ["app" => $this->appName]); + return new JSONResponse(["error" => $error]); + } + + $checkUserAllowGroups = $userId; + if (!empty($share)) { + $checkUserAllowGroups = $share->getSharedBy(); + } + if (!$this->config->isUserAllowedToUse($checkUserAllowGroups)) { + return new JSONResponse(["error" => $this->trans->t("Not permitted")]); + } + + $fileName = $file->getName(); + $ext = strtolower(pathinfo($fileName, PATHINFO_EXTENSION)); + $format = !empty($ext) ? $this->config->FormatsSetting()[$ext] : null; + if (!isset($format)) { + $this->logger->info("Format is not supported for editing: $fileName", ["app" => $this->appName]); + return new JSONResponse(["error" => $this->trans->t("Format is not supported")]); + } + + $fileUrl = $this->getUrl($file, $user, $shareToken, $version, null, $template); + + $key = null; + if ($version > 0 + && $this->versionManager !== null) { + $owner = $file->getFileInfo()->getOwner(); + if ($owner !== null) { + $versions = array_reverse($this->versionManager->getVersionsForFile($owner, $file->getFileInfo())); + + if ($version <= count($versions)) { + $fileVersion = array_values($versions)[$version - 1]; + + $key = $this->fileUtility->getVersionKey($fileVersion); + } + } + } + if ($key === null) { + $key = $this->fileUtility->getKey($file, true); + } + $key = DocumentService::GenerateRevisionId($key); + + $params = [ + "document" => [ + "fileType" => $ext, + "key" => $key, + "permissions" => [], + "title" => $fileName, + "url" => $fileUrl, + ], + "documentType" => $format["type"], + "editorConfig" => [ + "lang" => str_replace("_", "-", \OC::$server->getL10NFactory("")->get("")->getLanguageCode()), + "region" => str_replace("_", "-", \OC::$server->getL10NFactory("")->findLocale()) + ] + ]; + + $permissions_modifyFilter = $this->config->GetSystemValue($this->config->_permissions_modifyFilter); + if (isset($permissions_modifyFilter)) { + $params["document"]["permissions"]["modifyFilter"] = $permissions_modifyFilter; + } + + $isTempLock = false; + if ($version < 1 + && \OC::$server->getAppManager()->isInstalled("files_lock")) { + try { + $lockService = \OC::$server->get(LockService::class); + $lock = $lockService->getLockFromFileId($file->getId()); + $lockOwner = $lock->getUserId(); + if ($userId !== $lockOwner) { + $isTempLock = true; + $this->logger->debug("File" . $file->getId() . "is locked by $lockOwner", ["app" => $this->appName]); + } + } catch (LockNotFoundException $e) {} + } + + $canEdit = isset($format["edit"]) && $format["edit"]; + $editable = $version < 1 + && !$template + && $file->isUpdateable() + && !$isTempLock + && (empty($shareToken) || ($share->getPermissions() & Constants::PERMISSION_UPDATE) === Constants::PERMISSION_UPDATE); + $params["document"]["permissions"]["edit"] = $editable; + if ($editable && $canEdit) { + $hashCallback = $this->crypt->GetHash(["userId" => $userId, "fileId" => $file->getId(), "filePath" => $filePath, "shareToken" => $shareToken, "action" => "track"]); + $callback = $this->urlGenerator->linkToRouteAbsolute($this->appName . ".callback.track", ["doc" => $hashCallback]); + + if (!empty($this->config->GetStorageUrl())) { + $callback = str_replace($this->urlGenerator->getAbsoluteURL("/"), $this->config->GetStorageUrl(), $callback); + } + + $params["editorConfig"]["callbackUrl"] = $callback; + } else { + $params["editorConfig"]["mode"] = "view"; + } + + if (!$template + && $file->isUpdateable() + && (empty($shareToken) || ($share->getPermissions() & Constants::PERMISSION_UPDATE) === Constants::PERMISSION_UPDATE)) { + + $params["document"]["permissions"]["changeHistory"] = true; + } + + if (\OC::$server->getRequest()->isUserAgent([$this::USER_AGENT_MOBILE])) { + $params["type"] = "mobile"; + } + + if (!empty($userId)) { + $params["editorConfig"]["user"] = [ + "id" => $this->buildUserId($userId), + "name" => $user->getDisplayName() + ]; + } else if (!empty($guestName)) { + $params["editorConfig"]["user"] = [ + "name" => $guestName + ]; + } + + $folderLink = null; + + if (!empty($shareToken)) { + if (method_exists($share, "getHideDownload") && $share->getHideDownload()) { + $params["document"]["permissions"]["download"] = false; + $params["document"]["permissions"]["print"] = false; + $params["document"]["permissions"]["copy"] = false; + } + + $node = $share->getNode(); + if ($node instanceof Folder) { + $sharedFolder = $node; + $folderPath = $sharedFolder->getRelativePath($file->getParent()->getPath()); + if (!empty($folderPath)) { + $linkAttr = [ + "path" => $folderPath, + "scrollto" => $file->getName(), + "token" => $shareToken + ]; + $folderLink = $this->urlGenerator->linkToRouteAbsolute("files_sharing.sharecontroller.showShare", $linkAttr); + } + } + } else if (!empty($userId)) { + $userFolder = $this->root->getUserFolder($userId); + $folderPath = $userFolder->getRelativePath($file->getParent()->getPath()); + if (!empty($folderPath)) { + $linkAttr = [ + "dir" => $folderPath, + "scrollto" => $file->getName() + ]; + $folderLink = $this->urlGenerator->linkToRouteAbsolute("files.view.index", $linkAttr); + } + + switch ($params["documentType"]) { + case "word": + $createName = $this->trans->t("Document") . ".docx"; + break; + case "cell": + $createName = $this->trans->t("Spreadsheet") . ".xlsx"; + break; + case "slide": + $createName = $this->trans->t("Presentation") . ".pptx"; + break; + } + + $createParam = [ + "dir" => "/", + "name" => $createName + ]; + + if (!empty($folderPath)) { + $folder = $userFolder->get($folderPath); + if (!empty($folder) && $folder->isCreatable()) { + $createParam["dir"] = $folderPath; + } + } + + $createUrl = $this->urlGenerator->linkToRouteAbsolute($this->appName . ".editor.create_new", $createParam); + $params["editorConfig"]["createUrl"] = urldecode($createUrl); + + $templatesList = TemplateManager::GetGlobalTemplates($file->getMimeType()); + if (!empty($templatesList)) { + $templates = []; + foreach($templatesList as $templateItem) { + $createParam["templateId"] = $templateItem->getId(); + $createParam["name"] = $templateItem->getName(); + + array_push($templates, [ + "image" => "", + "title" => $templateItem->getName(), + "url" => urldecode($this->urlGenerator->linkToRouteAbsolute($this->appName . ".editor.create_new", $createParam)) + ]); + } + + $params["editorConfig"]["templates"] = $templates; + } + + if (!$template) { + $params["document"]["info"]["favorite"] = $this->isFavorite($fileId, $userId); + } + $params["_file_path"] = $userFolder->getRelativePath($file->getPath()); + } + + if ($folderLink !== null + && $this->config->GetSystemValue($this->config->_customization_goback) !== false) { + $params["editorConfig"]["customization"]["goback"] = [ + "url" => $folderLink + ]; + + if (!$desktop) { + if ($this->config->GetSameTab()) { + $params["editorConfig"]["customization"]["goback"]["blank"] = false; + } + + if ($inframe === true || !empty($directToken)) { + $params["editorConfig"]["customization"]["goback"]["requestClose"] = true; + } + } + } + + if ($inframe === true) { + $params["_files_sharing"] = \OC::$server->getAppManager()->isInstalled("files_sharing"); + } + + $params = $this->setCustomization($params); + + $params = $this->setWatermark($params, !empty($shareToken), $userId, $file); + + if ($this->config->UseDemo()) { + $params["editorConfig"]["tenant"] = $this->config->GetSystemValue("instanceid", true); + } + + if ($anchor !== null) { + try { + $actionLink = json_decode($anchor, true); + + $params["editorConfig"]["actionLink"] = $actionLink; + } catch (\Exception $e) { + $this->logger->logException($e, ["message" => "Config: $fileId decode $anchor", "app" => $this->appName]); + } + } + + if (!empty($this->config->GetDocumentServerSecret())) { + $token = \Firebase\JWT\JWT::encode($params, $this->config->GetDocumentServerSecret()); + $params["token"] = $token; + } + + $this->logger->debug("Config is generated for: $fileId ($version) with key $key", ["app" => $this->appName]); + + return new JSONResponse($params); + } + + /** + * Getting file by identifier + * + * @param string $userId - user identifier + * @param integer $fileId - file identifier + * @param string $filePath - file path + * @param bool $template - file is template + * + * @return array + */ + private function getFile($userId, $fileId, $filePath = null, $template = false) { + if (empty($fileId)) { + return [null, $this->trans->t("FileId is empty"), null]; + } + + try { + $folder = !$template ? $this->root->getUserFolder($userId) : TemplateManager::GetGlobalTemplateDir(); + $files = $folder->getById($fileId); + } catch (\Exception $e) { + $this->logger->logException($e, ["message" => "getFile: $fileId", "app" => $this->appName]); + return [null, $this->trans->t("Invalid request"), null]; + } + + if (empty($files)) { + $this->logger->info("Files not found: $fileId", ["app" => $this->appName]); + return [null, $this->trans->t("File not found"), null]; + } + + $file = $files[0]; + + if (count($files) > 1 && !empty($filePath)) { + $filePath = "/" . $userId . "/files" . $filePath; + foreach ($files as $curFile) { + if ($curFile->getPath() === $filePath) { + $file = $curFile; + break; + } + } + } + + if (!$file->isReadable()) { + return [null, $this->trans->t("You do not have enough permissions to view the file"), null]; + } + + return [$file, null, null]; + } + + /** + * Generate secure link to download document + * + * @param File $file - file + * @param IUser $user - user with access + * @param string $shareToken - access token + * @param integer $version - file version + * @param bool $changes - is required url to file changes + * @param bool $template - file is template + * + * @return string + */ + private function getUrl($file, $user = null, $shareToken = null, $version = 0, $changes = false, $template = false) { + + $data = [ + "action" => "download", + "fileId" => $file->getId() + ]; + + $userId = null; + if (!empty($user)) { + $userId = $user->getUID(); + $data["userId"] = $userId; + } + if (!empty($shareToken)) { + $data["shareToken"] = $shareToken; + } + if ($version > 0) { + $data["version"] = $version; + } + if ($changes) { + $data["changes"] = true; + } + if ($template) { + $data["template"] = true; + } + + $hashUrl = $this->crypt->GetHash($data); + + $fileUrl = $this->urlGenerator->linkToRouteAbsolute($this->appName . ".callback.download", ["doc" => $hashUrl]); + + if (!empty($this->config->GetStorageUrl()) + && !$changes) { + $fileUrl = str_replace($this->urlGenerator->getAbsoluteURL("/"), $this->config->GetStorageUrl(), $fileUrl); + } + + return $fileUrl; + } + + /** + * Generate unique user identifier + * + * @param string $userId - current user identifier + * + * @return string + */ + private function buildUserId($userId) { + $instanceId = $this->config->GetSystemValue("instanceid", true); + $userId = $instanceId . "_" . $userId; + return $userId; + } + + /** + * Set customization parameters + * + * @param array params - file parameters + * + * @return array + */ + private function setCustomization($params) { + //default is true + if ($this->config->GetCustomizationChat() === false) { + $params["editorConfig"]["customization"]["chat"] = false; + } + + //default is false + if ($this->config->GetCustomizationCompactHeader() === true) { + $params["editorConfig"]["customization"]["compactHeader"] = true; + } + + //default is false + if ($this->config->GetCustomizationFeedback() === true) { + $params["editorConfig"]["customization"]["feedback"] = true; + } + + //default is false + if ($this->config->GetCustomizationForcesave() === true) { + $params["editorConfig"]["customization"]["forcesave"] = true; + } + + //default is true + if ($this->config->GetCustomizationHelp() === false) { + $params["editorConfig"]["customization"]["help"] = false; + } + + //default is original + $reviewDisplay = $this->config->GetCustomizationReviewDisplay(); + if ($reviewDisplay !== "original") { + $params["editorConfig"]["customization"]["reviewDisplay"] = $reviewDisplay; + } + + //default is false + if ($this->config->GetCustomizationToolbarNoTabs() === true) { + $params["editorConfig"]["customization"]["toolbarNoTabs"] = true; + } + + + /* from system config */ + + $autosave = $this->config->GetSystemValue($this->config->_customization_autosave); + if (isset($autosave)) { + $params["editorConfig"]["customization"]["autosave"] = $autosave; + } + + $customer = $this->config->GetSystemValue($this->config->_customization_customer); + if (isset($customer)) { + $params["editorConfig"]["customization"]["customer"] = $customer; + } + + $loaderLogo = $this->config->GetSystemValue($this->config->_customization_loaderLogo); + if (isset($loaderLogo)) { + $params["editorConfig"]["customization"]["loaderLogo"] = $loaderLogo; + } + + $loaderName = $this->config->GetSystemValue($this->config->_customization_loaderName); + if (isset($loaderName)) { + $params["editorConfig"]["customization"]["loaderName"] = $loaderName; + } + + $logo = $this->config->GetSystemValue($this->config->_customization_logo); + if (isset($logo)) { + $params["editorConfig"]["customization"]["logo"] = $logo; + } + + $zoom = $this->config->GetSystemValue($this->config->_customization_zoom); + if (isset($zoom)) { + $params["editorConfig"]["customization"]["zoom"] = $zoom; + } + + return $params; + } + + /** + * Set watermark parameters + * + * @param array params - file parameters + * @param bool isPublic - with access token + * @param string userId - user identifier + * @param string file - file + * + * @return array + */ + private function setWatermark($params, $isPublic, $userId, $file) { + $watermarkTemplate = $this->getWatermarkText($isPublic, $userId, $file, + $params["document"]["permissions"]["edit"] !== false, + !array_key_exists("download", $params["document"]["permissions"]) || $params["document"]["permissions"]["download"] !== false); + + if ($watermarkTemplate !== false) { + $replacements = [ + "userId" => $userId, + "date" => (new \DateTime())->format("Y-m-d H:i:s"), + "themingName" => \OC::$server->getThemingDefaults()->getName() + ]; + $watermarkTemplate = preg_replace_callback("/{(.+?)}/", function ($matches) use ($replacements) + { + return $replacements[$matches[1]]; + }, $watermarkTemplate); + + $params["document"]["options"] = [ + "watermark_on_draw" => [ + "align" => 1, + "height" => 100, + "paragraphs" => array([ + "align" => 2, + "runs" => array([ + "fill" => [182, 182, 182], + "font-size" => 70, + "text" => $watermarkTemplate, + ]) + ]), + "rotate" => -45, + "width" => 250, + ] + ]; + } + + return $params; + } + + /** + * Should watermark + * + * @param bool isPublic - with access token + * @param string userId - user identifier + * @param string file - file + * @param bool canEdit - edit permission + * @param bool canDownload - download permission + * + * @return bool|string + */ + private function getWatermarkText($isPublic, $userId, $file, $canEdit, $canDownload) { + $watermarkSettings = $this->config->GetWatermarkSettings(); + if (!$watermarkSettings["enabled"]) { + return false; + } + + $watermarkText = $watermarkSettings["text"]; + $fileId = $file->getId(); + + if ($isPublic) { + if ($watermarkSettings["linkAll"]) { + return $watermarkText; + } + if ($watermarkSettings["linkRead"] && !$canEdit) { + return $watermarkText; + } + if ($watermarkSettings["linkSecure"] && !$canDownload) { + return $watermarkText; + } + if ($watermarkSettings["linkTags"]) { + $tags = $watermarkSettings["linkTagsList"]; + $fileTags = \OC::$server->getSystemTagObjectMapper()->getTagIdsForObjects([$fileId], "files")[$fileId]; + foreach ($fileTags as $tagId) { + if (in_array($tagId, $tags, true)) { + return $watermarkText; + } + } + } + } else { + if ($watermarkSettings["shareAll"] + && ($file->getOwner() === null || $file->getOwner()->getUID() !== $userId)) { + return $watermarkText; + } + if ($watermarkSettings["shareRead"] && !$canEdit) { + return $watermarkText; + } + } + if ($watermarkSettings["allGroups"]) { + $groups = $watermarkSettings["allGroupsList"]; + foreach ($groups as $group) { + if (\OC::$server->getGroupManager()->isInGroup($userId, $group)) { + return $watermarkText; + } + } + } + if ($watermarkSettings["allTags"]) { + $tags = $watermarkSettings["allTagsList"]; + $fileTags = \OC::$server->getSystemTagObjectMapper()->getTagIdsForObjects([$fileId], "files")[$fileId]; + foreach ($fileTags as $tagId) { + if (in_array($tagId, $tags, true)) { + return $watermarkText; + } + } + } + + return false; + } + + /** + * Check file favorite + * + * @param integer $fileId - file identifier + * @param string $userId - user identifier + * + * @return bool + */ + private function isFavorite($fileId, $userId = null) { + $currentTags = $this->tagManager->load("files", [], false, $userId)->getTagsForObjects([$fileId]); + if ($currentTags) { + return in_array(ITags::TAG_FAVORITE, $currentTags[$fileId]); + } + + return false; + } +}
\ No newline at end of file diff --git a/controller/editorcontroller.php b/controller/editorcontroller.php index 7c4a776..1bb8c87 100644 --- a/controller/editorcontroller.php +++ b/controller/editorcontroller.php @@ -28,19 +28,17 @@ use OCP\AppFramework\Http\Template\PublicTemplateResponse; use OCP\AppFramework\QueryException; use OCP\Constants; use OCP\Files\File; -use OCP\Files\Folder; use OCP\Files\IRootFolder; use OCP\Files\NotPermittedException; use OCP\IL10N; use OCP\ILogger; use OCP\IRequest; use OCP\ISession; -use OCP\ITags; -use OCP\ITagManager; use OCP\IURLGenerator; use OCP\IUser; use OCP\IUserManager; use OCP\IUserSession; +use OCP\IGroupManager; use OCP\Share\IManager; use OCP\Share\IShare; @@ -137,16 +135,11 @@ class EditorController extends Controller { private $shareManager; /** - * Tag manager + * Group manager * - * @var ITagManager - */ - private $tagManager; - - /** - * Mobile regex from https://github.com/ONLYOFFICE/CommunityServer/blob/v9.1.1/web/studio/ASC.Web.Studio/web.appsettings.config#L35 + * @var IGroupManager */ - const USER_AGENT_MOBILE = "/android|avantgo|playbook|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od|ad)|iris|kindle|lge |maemo|midp|mmp|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\\/|plucker|pocket|psp|symbian|treo|up\\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i"; + private $groupManager; /** * @param string $AppName - application name @@ -160,8 +153,8 @@ class EditorController extends Controller { * @param AppConfig $config - application configuration * @param Crypt $crypt - hash generator * @param IManager $shareManager - Share manager - * @param ISession $ISession - Session - * @param ITagManager $tagManager - Tag manager + * @param ISession $session - Session + * @param IGroupManager $groupManager - group Manager */ public function __construct($AppName, IRequest $request, @@ -175,7 +168,7 @@ class EditorController extends Controller { Crypt $crypt, IManager $shareManager, ISession $session, - ITagManager $tagManager + IGroupManager $groupManager ) { parent::__construct($AppName, $request); @@ -188,7 +181,7 @@ class EditorController extends Controller { $this->config = $config; $this->crypt = $crypt; $this->shareManager = $shareManager; - $this->tagManager = $tagManager; + $this->groupManager = $groupManager; if (\OC::$server->getAppManager()->isInstalled("files_versions")) { try { @@ -320,25 +313,84 @@ class EditorController extends Controller { /** * Get users * + * @param $fileId - file identifier + * * @return array * * @NoAdminRequired * @NoCSRFRequired */ - public function users() { + public function users($fileId) { $this->logger->debug("Search users", ["app" => $this->appName]); $result = []; + $currentUserGroups = []; if (!$this->config->isUserAllowedToUse()) { return $result; } - $userId = $this->userSession->getUser()->getUID(); - $users = $this->userManager->search(""); + if (!$this->shareManager->allowEnumeration()) { + return $result; + } + + $autocompleteMemberGroup = false; + if ($this->shareManager->limitEnumerationToGroups()) { + $autocompleteMemberGroup = true; + } + + $currentUser = $this->userSession->getUser(); + $currentUserId = $currentUser->getUID(); + + $currentUserGroups = $this->groupManager->getUserGroupIds($currentUser); + + $excludedGroups = $this->getShareExcludedGroups(); + $isMemberExcludedGroups = true; + if (count(array_intersect($currentUserGroups, $excludedGroups)) !== count($currentUserGroups)) { + $isMemberExcludedGroups = false; + } + + list ($file, $error, $share) = $this->getFile($currentUserId, $fileId); + if (isset($error)) { + $this->logger->error("Users: $fileId $error", ["app" => $this->appName]); + return $result; + } + + $canShare = (($file->getPermissions() & Constants::PERMISSION_SHARE) === Constants::PERMISSION_SHARE) + && !$isMemberExcludedGroups; + + $shareMemberGroups = $this->shareManager->shareWithGroupMembersOnly(); + + $all = false; + $users = []; + if ($canShare) { + if ($shareMemberGroups || $autocompleteMemberGroup) { + foreach ($currentUserGroups as $currentUserGroup) { + $group = $this->groupManager->get($currentUserGroup); + foreach ($group->getUsers() as $user) { + if (!in_array($user, $users)) { + array_push($users, $user); + } + } + } + } else { + $users = $this->userManager->search(""); + $all = true; + } + } + + if (!$all) { + $accessList = $this->shareManager->getAccessList($file); + foreach ($accessList["users"] as $accessUser) { + $user = $this->userManager->get($accessUser); + if (!in_array($user, $users)) { + array_push($users, $this->userManager->get($accessUser)); + } + } + } + foreach ($users as $user) { $email = $user->getEMailAddress(); - if ($user->getUID() != $userId - && !empty($email)) { + if ($user->getUID() != $currentUserId && !empty($email)) { array_push($result, [ "email" => $email, "name" => $user->getDisplayName() @@ -390,6 +442,14 @@ class EditorController extends Controller { $userId = $user->getUID(); } + $currentUserGroups = $this->groupManager->getUserGroupIds($user); + + $excludedGroups = $this->getShareExcludedGroups(); + $isMemberExcludedGroups = true; + if (count(array_intersect($currentUserGroups, $excludedGroups)) !== count($currentUserGroups)) { + $isMemberExcludedGroups = false; + } + list ($file, $error, $share) = $this->getFile($userId, $fileId); if (isset($error)) { $this->logger->error("Mention: $fileId $error", ["app" => $this->appName]); @@ -408,7 +468,9 @@ class EditorController extends Controller { "anchor" => $anchor ]); - $canShare = ($file->getPermissions() & Constants::PERMISSION_SHARE) === Constants::PERMISSION_SHARE; + $shareMemberGroups = $this->shareManager->shareWithGroupMembersOnly(); + $canShare = (($file->getPermissions() & Constants::PERMISSION_SHARE) === Constants::PERMISSION_SHARE) + && !$isMemberExcludedGroups; $accessList = $this->shareManager->getAccessList($file); @@ -417,6 +479,13 @@ class EditorController extends Controller { if (!$canShare) { continue; } + if ($shareMemberGroups) { + $recipient = $this->userManager->get($recipientId); + $recipientGroups = $this->groupManager->getUserGroupIds($recipient); + if (empty(array_intersect($currentUserGroups, $recipientGroups))) { + continue; + } + } $share = $this->shareManager->newShare(); $share->setNode($file) @@ -490,10 +559,10 @@ class EditorController extends Controller { $internalExtension = "docx"; switch ($format["type"]) { - case "spreadsheet": + case "cell": $internalExtension = "xlsx"; break; - case "presentation": + case "slide": $internalExtension = "pptx"; break; } @@ -607,7 +676,6 @@ class EditorController extends Controller { * @return array * * @NoAdminRequired - * @PublicPage */ public function history($fileId, $shareToken = null) { $this->logger->debug("Request history for: $fileId", ["app" => $this->appName]); @@ -728,7 +796,6 @@ class EditorController extends Controller { * @return array * * @NoAdminRequired - * @PublicPage */ public function version($fileId, $version, $shareToken = null) { $this->logger->debug("Request version for: $fileId ($version)", ["app" => $this->appName]); @@ -819,6 +886,61 @@ class EditorController extends Controller { } /** + * Restore file version + * + * @param integer $fileId - file identifier + * @param integer $version - file version + * @param string $shareToken - access token + * + * @return array + * + * @NoAdminRequired + * @PublicPage + */ + public function restore($fileId, $version, $shareToken = null) { + $this->logger->debug("Request restore version for: $fileId ($version)", ["app" => $this->appName]); + + if (empty($shareToken) && !$this->config->isUserAllowedToUse()) { + return ["error" => $this->trans->t("Not permitted")]; + } + + $version = empty($version) ? null : $version; + + $user = $this->userSession->getUser(); + $userId = null; + if (!empty($user)) { + $userId = $user->getUID(); + } + + list ($file, $error, $share) = empty($shareToken) ? $this->getFile($userId, $fileId) : $this->fileUtility->getFileByToken($fileId, $shareToken); + + if (isset($error)) { + $this->logger->error("Restore: $fileId $error", ["app" => $this->appName]); + return ["error" => $error]; + } + + if ($fileId === 0) { + $fileId = $file->getId(); + } + + $owner = null; + $versions = array(); + if ($this->versionManager !== null) { + $owner = $file->getFileInfo()->getOwner(); + if ($owner !== null) { + $versions = array_reverse($this->versionManager->getVersionsForFile($owner, $file->getFileInfo())); + } + + if (count($versions) >= $version) { + $fileVersion = array_values($versions)[$version - 1]; + $this->versionManager->rollback($fileVersion); + } + } + + return $this->history($fileId, $shareToken); + } + + /** * Get presigned url to file * * @param string $filePath - file path @@ -971,7 +1093,15 @@ class EditorController extends Controller { return new RedirectResponse($redirectUrl); } - if (empty($shareToken) && !$this->config->isUserAllowedToUse()) { + $shareBy = null; + if (!empty($shareToken) && !$isLoggedIn) { + list ($share, $error) = $this->fileUtility->getShare($shareToken); + if (!empty($share)) { + $shareBy = $share->getSharedBy(); + } + } + + if (!$this->config->isUserAllowedToUse($shareBy)) { return $this->renderError($this->trans->t("Not permitted")); } @@ -1044,285 +1174,6 @@ class EditorController extends Controller { } /** - * Collecting the file parameters for the document service - * - * @param integer $fileId - file identifier - * @param string $filePath - file path - * @param string $shareToken - access token - * @param string $directToken - direct token - * @param integer $version - file version - * @param bool $inframe - open in frame - * @param bool $desktop - desktop label - * @param string $guestName - nickname not logged user - * @param bool $template - file is template - * @param string $anchor - anchor for file content - * - * @return array - * - * @NoAdminRequired - * @PublicPage - */ - public function config($fileId, $filePath = null, $shareToken = null, $directToken = null, $version = 0, $inframe = false, $desktop = false, $guestName = null, $template = false, $anchor = null) { - - if (!empty($directToken)) { - list ($directData, $error) = $this->crypt->ReadHash($directToken); - if ($directData === null) { - $this->logger->error("Config for directEditor with empty or not correct hash: $error", ["app" => $this->appName]); - return ["error" => $this->trans->t("Not permitted")]; - } - if ($directData->action !== "direct") { - $this->logger->error("Config for directEditor with other data", ["app" => $this->appName]); - return ["error" => $this->trans->t("Invalid request")]; - } - - $fileId = $directData->fileId; - $userId = $directData->userId; - if ($this->userSession->isLoggedIn() - && $userId === $this->userSession->getUser()->getUID()) { - $redirectUrl = $this->urlGenerator->linkToRouteAbsolute($this->appName . ".editor.index", - [ - "fileId" => $fileId, - "filePath" => $filePath - ]); - return ["redirectUrl" => $redirectUrl]; - } - - $user = $this->userManager->get($userId); - } else { - if (empty($shareToken) && !$this->config->isUserAllowedToUse()) { - return ["error" => $this->trans->t("Not permitted")]; - } - - $user = $this->userSession->getUser(); - $userId = null; - if (!empty($user)) { - $userId = $user->getUID(); - } - } - - list ($file, $error, $share) = empty($shareToken) ? $this->getFile($userId, $fileId, $filePath, $template) : $this->fileUtility->getFileByToken($fileId, $shareToken); - - if (isset($error)) { - $this->logger->error("Config: $fileId $error", ["app" => $this->appName]); - return ["error" => $error]; - } - - $fileName = $file->getName(); - $ext = strtolower(pathinfo($fileName, PATHINFO_EXTENSION)); - $format = !empty($ext) ? $this->config->FormatsSetting()[$ext] : null; - if (!isset($format)) { - $this->logger->info("Format is not supported for editing: $fileName", ["app" => $this->appName]); - return ["error" => $this->trans->t("Format is not supported")]; - } - - $fileUrl = $this->getUrl($file, $user, $shareToken, $version, null, $template); - - $key = null; - if ($version > 0 - && $this->versionManager !== null) { - $owner = $file->getFileInfo()->getOwner(); - if ($owner !== null) { - $versions = array_reverse($this->versionManager->getVersionsForFile($owner, $file->getFileInfo())); - - if ($version <= count($versions)) { - $fileVersion = array_values($versions)[$version - 1]; - - $key = $this->fileUtility->getVersionKey($fileVersion); - } - } - } - if ($key === null) { - $key = $this->fileUtility->getKey($file, true); - } - $key = DocumentService::GenerateRevisionId($key); - - $params = [ - "document" => [ - "fileType" => $ext, - "key" => $key, - "permissions" => [], - "title" => $fileName, - "url" => $fileUrl, - ], - "documentType" => $format["type"], - "editorConfig" => [ - "lang" => str_replace("_", "-", \OC::$server->getL10NFactory("")->get("")->getLanguageCode()), - "region" => str_replace("_", "-", \OC::$server->getL10NFactory("")->findLocale()) - ] - ]; - - $permissions_modifyFilter = $this->config->GetSystemValue($this->config->_permissions_modifyFilter); - if (isset($permissions_modifyFilter)) { - $params["document"]["permissions"]["modifyFilter"] = $permissions_modifyFilter; - } - - $canEdit = isset($format["edit"]) && $format["edit"]; - $editable = $version < 1 - && !$template - && $file->isUpdateable() - && (empty($shareToken) || ($share->getPermissions() & Constants::PERMISSION_UPDATE) === Constants::PERMISSION_UPDATE); - $params["document"]["permissions"]["edit"] = $editable; - if ($editable && $canEdit) { - $hashCallback = $this->crypt->GetHash(["userId" => $userId, "fileId" => $file->getId(), "filePath" => $filePath, "shareToken" => $shareToken, "action" => "track"]); - $callback = $this->urlGenerator->linkToRouteAbsolute($this->appName . ".callback.track", ["doc" => $hashCallback]); - - if (!empty($this->config->GetStorageUrl())) { - $callback = str_replace($this->urlGenerator->getAbsoluteURL("/"), $this->config->GetStorageUrl(), $callback); - } - - $params["editorConfig"]["callbackUrl"] = $callback; - } else { - $params["editorConfig"]["mode"] = "view"; - } - - if (\OC::$server->getRequest()->isUserAgent([$this::USER_AGENT_MOBILE])) { - $params["type"] = "mobile"; - } - - if (!empty($userId)) { - $params["editorConfig"]["user"] = [ - "id" => $this->buildUserId($userId), - "name" => $user->getDisplayName() - ]; - } else if (!empty($guestName)) { - $params["editorConfig"]["user"] = [ - "name" => $guestName - ]; - } - - $folderLink = null; - - if (!empty($shareToken)) { - if (method_exists($share, "getHideDownload") && $share->getHideDownload()) { - $params["document"]["permissions"]["download"] = false; - $params["document"]["permissions"]["print"] = false; - $params["document"]["permissions"]["copy"] = false; - } - - $node = $share->getNode(); - if ($node instanceof Folder) { - $sharedFolder = $node; - $folderPath = $sharedFolder->getRelativePath($file->getParent()->getPath()); - if (!empty($folderPath)) { - $linkAttr = [ - "path" => $folderPath, - "scrollto" => $file->getName(), - "token" => $shareToken - ]; - $folderLink = $this->urlGenerator->linkToRouteAbsolute("files_sharing.sharecontroller.showShare", $linkAttr); - } - } - } else if (!empty($userId)) { - $userFolder = $this->root->getUserFolder($userId); - $folderPath = $userFolder->getRelativePath($file->getParent()->getPath()); - if (!empty($folderPath)) { - $linkAttr = [ - "dir" => $folderPath, - "scrollto" => $file->getName() - ]; - $folderLink = $this->urlGenerator->linkToRouteAbsolute("files.view.index", $linkAttr); - } - - switch($params["documentType"]) { - case "text": - $createName = $this->trans->t("Document") . ".docx"; - break; - case "spreadsheet": - $createName = $this->trans->t("Spreadsheet") . ".xlsx"; - break; - case "presentation": - $createName = $this->trans->t("Presentation") . ".pptx"; - break; - } - - $createParam = [ - "dir" => "/", - "name" => $createName - ]; - - if (!empty($folderPath)) { - $folder = $userFolder->get($folderPath); - if (!empty($folder) && $folder->isCreatable()) { - $createParam["dir"] = $folderPath; - } - } - - $createUrl = $this->urlGenerator->linkToRouteAbsolute($this->appName . ".editor.create_new", $createParam); - $params["editorConfig"]["createUrl"] = urldecode($createUrl); - - $templatesList = TemplateManager::GetGlobalTemplates($file->getMimeType()); - if (!empty($templatesList)) { - $templates = []; - foreach($templatesList as $templateItem) { - $createParam["templateId"] = $templateItem->getId(); - $createParam["name"] = $templateItem->getName(); - - array_push($templates, [ - "image" => "", - "title" => $templateItem->getName(), - "url" => urldecode($this->urlGenerator->linkToRouteAbsolute($this->appName . ".editor.create_new", $createParam)) - ]); - } - - $params["editorConfig"]["templates"] = $templates; - } - - if (!$template) { - $params["document"]["info"]["favorite"] = $this->isFavorite($fileId, $userId); - } - $params["_file_path"] = $userFolder->getRelativePath($file->getPath()); - } - - if ($folderLink !== null - && $this->config->GetSystemValue($this->config->_customization_goback) !== false) { - $params["editorConfig"]["customization"]["goback"] = [ - "url" => $folderLink - ]; - - if (!$desktop) { - if ($this->config->GetSameTab()) { - $params["editorConfig"]["customization"]["goback"]["blank"] = false; - } - - if ($inframe === true || !empty($directToken)) { - $params["editorConfig"]["customization"]["goback"]["requestClose"] = true; - } - } - } - - if ($inframe === true) { - $params["_files_sharing"] = \OC::$server->getAppManager()->isInstalled("files_sharing"); - } - - $params = $this->setCustomization($params); - - $params = $this->setWatermark($params, !empty($shareToken), $userId, $file); - - if ($this->config->UseDemo()) { - $params["editorConfig"]["tenant"] = $this->config->GetSystemValue("instanceid", true); - } - - if ($anchor !== null) { - try { - $actionLink = json_decode($anchor, true); - - $params["editorConfig"]["actionLink"] = $actionLink; - } catch (\Exception $e) { - $this->logger->logException($e, ["message" => "Config: $fileId decode $anchor", "app" => $this->appName]); - } - } - - if (!empty($this->config->GetDocumentServerSecret())) { - $token = \Firebase\JWT\JWT::encode($params, $this->config->GetDocumentServerSecret()); - $params["token"] = $token; - } - - $this->logger->debug("Config is generated for: $fileId ($version) with key $key", ["app" => $this->appName]); - - return $params; - } - - /** * Getting file by identifier * * @param string $userId - user identifier @@ -1419,229 +1270,31 @@ class EditorController extends Controller { } /** - * Generate unique user identifier - * - * @param string $userId - current user identifier - * - * @return string - */ - private function buildUserId($userId) { - $instanceId = $this->config->GetSystemValue("instanceid", true); - $userId = $instanceId . "_" . $userId; - return $userId; - } - - /** - * Set customization parameters - * - * @param array params - file parameters + * Return excluded groups list for share * * @return array */ - private function setCustomization($params) { - //default is true - if ($this->config->GetCustomizationChat() === false) { - $params["editorConfig"]["customization"]["chat"] = false; - } - - //default is false - if ($this->config->GetCustomizationCompactHeader() === true) { - $params["editorConfig"]["customization"]["compactHeader"] = true; - } - - //default is false - if ($this->config->GetCustomizationFeedback() === true) { - $params["editorConfig"]["customization"]["feedback"] = true; - } - - //default is false - if ($this->config->GetCustomizationForcesave() === true) { - $params["editorConfig"]["customization"]["forcesave"] = true; - } - - //default is true - if ($this->config->GetCustomizationHelp() === false) { - $params["editorConfig"]["customization"]["help"] = false; - } - - //default is original - $reviewDisplay = $this->config->GetCustomizationReviewDisplay(); - if ($reviewDisplay !== "original") { - $params["editorConfig"]["customization"]["reviewDisplay"] = $reviewDisplay; - } - - //default is false - if ($this->config->GetCustomizationToolbarNoTabs() === true) { - $params["editorConfig"]["customization"]["toolbarNoTabs"] = true; - } - - - /* from system config */ - - $autosave = $this->config->GetSystemValue($this->config->_customization_autosave); - if (isset($autosave)) { - $params["editorConfig"]["customization"]["autosave"] = $autosave; - } - - $customer = $this->config->GetSystemValue($this->config->_customization_customer); - if (isset($customer)) { - $params["editorConfig"]["customization"]["customer"] = $customer; - } - - $loaderLogo = $this->config->GetSystemValue($this->config->_customization_loaderLogo); - if (isset($loaderLogo)) { - $params["editorConfig"]["customization"]["loaderLogo"] = $loaderLogo; - } - - $loaderName = $this->config->GetSystemValue($this->config->_customization_loaderName); - if (isset($loaderName)) { - $params["editorConfig"]["customization"]["loaderName"] = $loaderName; - } + private function getShareExcludedGroups() { + $excludedGroups = []; - $logo = $this->config->GetSystemValue($this->config->_customization_logo); - if (isset($logo)) { - $params["editorConfig"]["customization"]["logo"] = $logo; - } - - $zoom = $this->config->GetSystemValue($this->config->_customization_zoom); - if (isset($zoom)) { - $params["editorConfig"]["customization"]["zoom"] = $zoom; - } - - return $params; - } - - /** - * Set watermark parameters - * - * @param array params - file parameters - * @param bool isPublic - with access token - * @param string userId - user identifier - * @param string file - file - * - * @return array - */ - private function setWatermark($params, $isPublic, $userId, $file) { - $watermarkTemplate = $this->getWatermarkText($isPublic, $userId, $file, - $params["document"]["permissions"]["edit"] !== false, - !array_key_exists("download", $params["document"]["permissions"]) || $params["document"]["permissions"]["download"] !== false); - - if ($watermarkTemplate !== false) { - $replacements = [ - "userId" => $userId, - "date" => (new \DateTime())->format("Y-m-d H:i:s"), - "themingName" => \OC::$server->getThemingDefaults()->getName() - ]; - $watermarkTemplate = preg_replace_callback("/{(.+?)}/", function ($matches) use ($replacements) - { - return $replacements[$matches[1]]; - }, $watermarkTemplate); - - $params["document"]["options"] = [ - "watermark_on_draw" => [ - "align" => 1, - "height" => 100, - "paragraphs" => array([ - "align" => 2, - "runs" => array([ - "fill" => [182, 182, 182], - "font-size" => 70, - "text" => $watermarkTemplate, - ]) - ]), - "rotate" => -45, - "width" => 250, - ] - ]; + if (\OC::$server->getConfig()->getAppValue("core", "shareapi_exclude_groups", "no") === "yes") { + $excludedGroups = json_decode(\OC::$server->getConfig()->getAppValue("core", "shareapi_exclude_groups_list", ""), true); } - return $params; + return $excludedGroups; } /** - * Should watermark - * - * @param bool isPublic - with access token - * @param string userId - user identifier - * @param string file - file - * @param bool canEdit - edit permission - * @param bool canDownload - download permission - * - * @return bool|string - */ - private function getWatermarkText($isPublic, $userId, $file, $canEdit, $canDownload) { - $watermarkSettings = $this->config->GetWatermarkSettings(); - if (!$watermarkSettings["enabled"]) { - return false; - } - - $watermarkText = $watermarkSettings["text"]; - $fileId = $file->getId(); - - if ($isPublic) { - if ($watermarkSettings["linkAll"]) { - return $watermarkText; - } - if ($watermarkSettings["linkRead"] && !$canEdit) { - return $watermarkText; - } - if ($watermarkSettings["linkSecure"] && !$canDownload) { - return $watermarkText; - } - if ($watermarkSettings["linkTags"]) { - $tags = $watermarkSettings["linkTagsList"]; - $fileTags = \OC::$server->getSystemTagObjectMapper()->getTagIdsForObjects([$fileId], "files")[$fileId]; - foreach ($fileTags as $tagId) { - if (in_array($tagId, $tags, true)) { - return $watermarkText; - } - } - } - } else { - if ($watermarkSettings["shareAll"] - && ($file->getOwner() === null || $file->getOwner()->getUID() !== $userId)) { - return $watermarkText; - } - if ($watermarkSettings["shareRead"] && !$canEdit) { - return $watermarkText; - } - } - if ($watermarkSettings["allGroups"]) { - $groups = $watermarkSettings["allGroupsList"]; - foreach ($groups as $group) { - if (\OC::$server->getGroupManager()->isInGroup($userId, $group)) { - return $watermarkText; - } - } - } - if ($watermarkSettings["allTags"]) { - $tags = $watermarkSettings["allTagsList"]; - $fileTags = \OC::$server->getSystemTagObjectMapper()->getTagIdsForObjects([$fileId], "files")[$fileId]; - foreach ($fileTags as $tagId) { - if (in_array($tagId, $tags, true)) { - return $watermarkText; - } - } - } - - return false; - } - - /** - * Check file favorite + * Generate unique user identifier * - * @param integer $fileId - file identifier - * @param string $userId - user identifier + * @param string $userId - current user identifier * - * @return bool + * @return string */ - private function isFavorite($fileId, $userId = null) { - $currentTags = $this->tagManager->load("files", [], false, $userId)->getTagsForObjects([$fileId]); - if ($currentTags) { - return in_array(ITags::TAG_FAVORITE, $currentTags[$fileId]); - } - - return false; + private function buildUserId($userId) { + $instanceId = $this->config->GetSystemValue("instanceid", true); + $userId = $instanceId . "_" . $userId; + return $userId; } /** diff --git a/img/cell.ico b/img/cell.ico Binary files differnew file mode 100644 index 0000000..05ecd8c --- /dev/null +++ b/img/cell.ico diff --git a/img/slide.ico b/img/slide.ico Binary files differnew file mode 100644 index 0000000..888c7a8 --- /dev/null +++ b/img/slide.ico diff --git a/img/word.ico b/img/word.ico Binary files differnew file mode 100644 index 0000000..31f9ca4 --- /dev/null +++ b/img/word.ico diff --git a/js/editor.js b/js/editor.js index 062af8f..dcfe748 100644 --- a/js/editor.js +++ b/js/editor.js @@ -27,11 +27,6 @@ }, OCA.Onlyoffice); OCA.Onlyoffice.InitEditor = function () { - var displayError = function (error) { - OCP.Toast.error(error, { - timeout: -1 - }); - }; OCA.Onlyoffice.fileId = $("#iframeEditor").data("id"); OCA.Onlyoffice.shareToken = $("#iframeEditor").data("sharetoken"); @@ -42,20 +37,22 @@ OCA.Onlyoffice.filePath = $("#iframeEditor").data("path"); OCA.Onlyoffice.anchor = $("#iframeEditor").attr("data-anchor"); var guestName = localStorage.getItem("nick"); + + if (OCA.Onlyoffice.inframe) { + OCA.Onlyoffice.faviconBase = $('link[rel="icon"]').attr("href"); + } + if (!OCA.Onlyoffice.fileId && !OCA.Onlyoffice.shareToken && !directToken) { - displayError(t(OCA.Onlyoffice.AppName, "FileId is empty")); + OCA.Onlyoffice.showMessage(t(OCA.Onlyoffice.AppName, "FileId is empty"), "error", {timeout: -1}); return; } if (typeof DocsAPI === "undefined") { - displayError(t(OCA.Onlyoffice.AppName, "ONLYOFFICE cannot be reached. Please contact admin")); + OCA.Onlyoffice.showMessage(t(OCA.Onlyoffice.AppName, "ONLYOFFICE cannot be reached. Please contact admin"), "error", {timeout: -1}); return; } - var configUrl = OC.generateUrl("apps/" + OCA.Onlyoffice.AppName + "/ajax/config/{fileId}", - { - fileId: OCA.Onlyoffice.fileId || 0 - }); + var configUrl = OC.linkToOCS("apps/" + OCA.Onlyoffice.AppName + "/api/v1/config", 2) + (OCA.Onlyoffice.fileId || 0); var params = []; var filePath = $("#iframeEditor").data("path"); @@ -98,7 +95,7 @@ success: function onSuccess(config) { if (config) { if (config.error != null) { - displayError(config.error); + OCA.Onlyoffice.showMessage(config.error, "error", {timeout: -1}); return; } @@ -136,15 +133,6 @@ "onMakeActionLink": OCA.Onlyoffice.onMakeActionLink, }; - if (!OCA.Onlyoffice.template) { - config.events.onRequestHistory = OCA.Onlyoffice.onRequestHistory; - config.events.onRequestHistoryData = OCA.Onlyoffice.onRequestHistoryData; - - if (!OCA.Onlyoffice.version) { - config.events.onRequestHistoryClose = OCA.Onlyoffice.onRequestHistoryClose; - } - } - if (config.editorConfig.tenant) { config.events.onAppReady = function () { OCA.Onlyoffice.docEditor.showMessage(t(OCA.Onlyoffice.AppName, "You are using public demo ONLYOFFICE Docs server. Please do not store private sensitive data.")); @@ -164,6 +152,16 @@ if (!OCA.Onlyoffice.filePath) { OCA.Onlyoffice.filePath = config._file_path; } + + if (!OCA.Onlyoffice.template) { + config.events.onRequestHistory = OCA.Onlyoffice.onRequestHistory; + config.events.onRequestHistoryData = OCA.Onlyoffice.onRequestHistoryData; + config.events.onRequestRestore = OCA.Onlyoffice.onRequestRestore; + + if (!OCA.Onlyoffice.version) { + config.events.onRequestHistoryClose = OCA.Onlyoffice.onRequestHistoryClose; + } + } } if (OCA.Onlyoffice.directEditor || OCA.Onlyoffice.inframe) { @@ -186,6 +184,17 @@ && config.type === "mobile" && $("#app > iframe").css("position") === "fixed") { $("#app > iframe").css("height", "calc(100% - 50px)"); } + + var favicon = OC.filePath(OCA.Onlyoffice.AppName, "img", OCA.Onlyoffice.documentType + ".ico"); + if (OCA.Onlyoffice.inframe) { + window.parent.postMessage({ + method: "changeFavicon", + param: favicon + }, + "*"); + } else { + $('link[rel="icon"]').attr("href", favicon); + } } } }); @@ -198,33 +207,7 @@ shareToken: OCA.Onlyoffice.shareToken || "", }), function onSuccess(response) { - if (response.error) { - var data = {error: response.error}; - } else { - var currentVersion = 0; - $.each(response, function (i, fileVersion) { - if (fileVersion.version >= currentVersion) { - currentVersion = fileVersion.version; - } - - fileVersion.created = moment(fileVersion.created * 1000).format("L LTS"); - if (fileVersion.changes) { - $.each(fileVersion.changes, function (j, change) { - change.created = moment(change.created + "+00:00").format("L LTS"); - }); - } - }); - - if (version) { - currentVersion = Math.min(currentVersion, version); - } - - data = { - currentVersion: currentVersion, - history: response, - }; - } - OCA.Onlyoffice.docEditor.refreshHistory(data); + OCA.Onlyoffice.refreshHistory(response, version); }); }; @@ -248,6 +231,30 @@ }); }; + OCA.Onlyoffice.onRequestRestore = function (event) { + var version = event.data.version; + + $.ajax({ + method: "PUT", + url: OC.generateUrl("apps/" + OCA.Onlyoffice.AppName + "/ajax/restore?fileId={fileId}&version={version}&shareToken={shareToken}", + { + fileId: OCA.Onlyoffice.fileId || 0, + version: version, + shareToken: OCA.Onlyoffice.shareToken || "", + }), + success: function onSuccess(response) { + OCA.Onlyoffice.refreshHistory(response, version); + + if (OCA.Onlyoffice.inframe) { + window.parent.postMessage({ + method: "onRefreshVersionsDialog" + }, + "*"); + } + } + }); + }; + OCA.Onlyoffice.onRequestHistoryClose = function () { location.reload(true); }; @@ -304,11 +311,11 @@ saveData, function onSuccess(response) { if (response.error) { - OCP.Toast.error(response.error); + OCA.Onlyoffice.showMessage(response.error, "error"); return; } - OCP.Toast.success(t(OCA.Onlyoffice.AppName, "File saved") + " (" + response.name + ")"); + OCA.Onlyoffice.showMessage(t(OCA.Onlyoffice.AppName, "File saved") + " (" + response.name + ")"); }); }; @@ -346,7 +353,7 @@ }), function onSuccess(response) { if (response.error) { - OCP.Toast.error(response.error); + OCA.Onlyoffice.showMessage(response.error, "error"); return; } @@ -385,7 +392,7 @@ }), function onSuccess(response) { if (response.error) { - OCP.Toast.error(response.error); + OCA.Onlyoffice.showMessage(response.error, "error"); return; } @@ -478,7 +485,10 @@ }; OCA.Onlyoffice.onRequestUsers = function (event) { - $.get(OC.generateUrl("apps/" + OCA.Onlyoffice.AppName + "/ajax/users"), + $.get(OC.generateUrl("apps/" + OCA.Onlyoffice.AppName + "/ajax/users?fileId={fileId}", + { + fileId: OCA.Onlyoffice.fileId || 0 + }), function onSuccess(response) { OCA.Onlyoffice.docEditor.setUsers({ "users": response @@ -502,11 +512,11 @@ }, function onSuccess(response) { if (response.error) { - OCP.Toast.error(response.error); + OCA.Onlyoffice.showMessage(response.error, "error"); return; } - OCP.Toast.success(response.message); + OCA.Onlyoffice.showMessage(response.message); }); }; @@ -527,6 +537,60 @@ } } + OCA.Onlyoffice.showMessage = function (message, type = "success", props = null) { + if (OCA.Onlyoffice.inframe) { + window.parent.postMessage({ + method: "onShowMessage", + param: { + message: message, + type: type, + props: props + } + }, + "*"); + return; + } + + switch (type) { + case "success": + OCP.Toast.success(message, props); + break; + case "error": + OCP.Toast.error(message, props); + break; + } + }; + + OCA.Onlyoffice.refreshHistory = function (response, version) { + if (response.error) { + var data = {error: response.error}; + } else { + var currentVersion = 0; + $.each(response, function (i, fileVersion) { + if (fileVersion.version >= currentVersion) { + currentVersion = fileVersion.version; + } + + fileVersion.created = moment(fileVersion.created * 1000).format("L LTS"); + if (fileVersion.changes) { + $.each(fileVersion.changes, function (j, change) { + change.created = moment(change.created + "+00:00").format("L LTS"); + }); + } + }); + + if (version) { + currentVersion = Math.min(currentVersion, version); + } + + data = { + currentVersion: currentVersion, + history: response, + }; + } + OCA.Onlyoffice.docEditor.refreshHistory(data); + } + OCA.Onlyoffice.InitEditor(); })(jQuery, OCA); diff --git a/js/listener.js b/js/listener.js index 0e5dbc2..2f2c5f4 100644 --- a/js/listener.js +++ b/js/listener.js @@ -75,7 +75,7 @@ }; OCA.Onlyoffice.onDocumentReady = function (documentType) { - if (documentType === "text") { + if (documentType === "word") { if (OCA.Onlyoffice.bindVersionClick) { OCA.Onlyoffice.bindVersionClick(); } @@ -84,6 +84,21 @@ } }; + OCA.Onlyoffice.changeFavicon = function (favicon) { + $('link[rel="icon"]').attr("href", favicon); + }; + + OCA.Onlyoffice.onShowMessage = function (messageObj) { + switch (messageObj.type) { + case "success": + OCP.Toast.success(messageObj.message, messageObj.props); + break; + case "error": + OCP.Toast.error(messageObj.message, messageObj.props); + break; + } + } + window.addEventListener("message", function (event) { if (!$(OCA.Onlyoffice.frameSelector).length || $(OCA.Onlyoffice.frameSelector)[0].contentWindow !== event.source @@ -99,6 +114,11 @@ OCA.Onlyoffice.OpenShareDialog(); } break; + case "onRefreshVersionsDialog": + if (OCA.Onlyoffice.RefreshVersionsDialog) { + OCA.Onlyoffice.RefreshVersionsDialog(); + } + break; case "editorRequestSaveAs": OCA.Onlyoffice.onRequestSaveAs(event.data.param); break; @@ -114,6 +134,11 @@ case "onDocumentReady": OCA.Onlyoffice.onDocumentReady(event.data.param); break; + case "changeFavicon": + OCA.Onlyoffice.changeFavicon(event.data.param); + break; + case "onShowMessage": + OCA.Onlyoffice.onShowMessage(event.data.param); } }, false); @@ -123,4 +148,10 @@ } }); + window.addEventListener("DOMNodeRemoved", function(event) { + if ($(event.target).length && $(OCA.Onlyoffice.frameSelector).length + && ($(event.target)[0].id === "viewer" || $(event.target)[0].id === $(OCA.Onlyoffice.frameSelector)[0].id)) { + OCA.Onlyoffice.changeFavicon($(OCA.Onlyoffice.frameSelector)[0].contentWindow.OCA.Onlyoffice.faviconBase); + } + }); })(OCA); @@ -26,7 +26,8 @@ }, OCA.Onlyoffice); OCA.Onlyoffice.setting = {}; - OCA.Onlyoffice.mobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|BB|PlayBook|IEMobile|Windows Phone|Kindle|Silk|Opera Mini/i.test(navigator.userAgent); + OCA.Onlyoffice.mobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|BB|PlayBook|IEMobile|Windows Phone|Kindle|Silk|Opera Mini|Macintosh/i.test(navigator.userAgent) + && navigator.maxTouchPoints && navigator.maxTouchPoints > 1; OCA.Onlyoffice.CreateFile = function (name, fileList, templateId) { var dir = fileList.getCurrentDirectory(); @@ -146,6 +147,16 @@ } }; + OCA.Onlyoffice.RefreshVersionsDialog = function () { + if (OCA.Onlyoffice.context) { + if ($("#app-sidebar-vue").is(":visible")) { + OCA.Files.Sidebar.close(); + OCA.Files.Sidebar.open(OCA.Onlyoffice.context.dir + "/" + OCA.Onlyoffice.context.fileName); + OCA.Files.Sidebar.setActiveTab("versionsTabView"); + } + } + }; + OCA.Onlyoffice.FileClick = function (fileName, context) { var fileInfoModel = context.fileInfoModel || context.fileList.getModelForFile(fileName); OCA.Onlyoffice.OpenEditor(fileInfoModel.id, context.dir, fileName); @@ -190,7 +201,7 @@ dialog_title: t("onlyoffice", "Download as") }); - $(dialog[0].querySelectorAll("p")).text(fileName + " " + t(OCA.Onlyoffice.AppName, "Convert into")); + $(dialog[0].querySelectorAll("p")).text(t(OCA.Onlyoffice.AppName, "Choose a format to convert {fileName}", {fileName: fileName})); var extension = getFileExtension(fileName); var selectNode = dialog[0].querySelectorAll("select")[0]; @@ -430,16 +441,27 @@ return; } - var button = document.createElement("a"); - button.href = OC.generateUrl("apps/" + OCA.Onlyoffice.AppName + "/s/" + encodeURIComponent($("#sharingToken").val())); - button.className = "onlyoffice-public-open button"; - button.innerText = t(OCA.Onlyoffice.AppName, "Open in ONLYOFFICE") + var editorUrl = OC.generateUrl("apps/" + OCA.Onlyoffice.AppName + "/s/" + encodeURIComponent($("#sharingToken").val())); - if (!OCA.Onlyoffice.setting.sameTab) { - button.target = "_blank"; - } + if (_oc_appswebroots.richdocuments + || _oc_appswebroots.files_pdfviewer && extension === "pdf" + || _oc_appswebroots.text && extension === "txt") { + + var button = document.createElement("a"); + button.href = editorUrl; + button.className = "onlyoffice-public-open button"; + button.innerText = t(OCA.Onlyoffice.AppName, "Open in ONLYOFFICE") - $("#preview").prepend(button); + if (!OCA.Onlyoffice.setting.sameTab) { + button.target = "_blank"; + } + + $("#preview").prepend(button); + } else { + OCA.Onlyoffice.frameSelector = "#onlyofficeFrame"; + var $iframe = $("<iframe id=\"onlyofficeFrame\" nonce=\"" + btoa(OC.requestToken) + "\" scrolling=\"no\" allowfullscreen src=\"" + editorUrl + "?inframe=true\" />"); + $("#app-content").append($iframe); + } }; OCA.Onlyoffice.GetSettings(initSharedButton); diff --git a/js/viewer.js b/js/viewer.js index 8e57c1a..3886b06 100644 --- a/js/viewer.js +++ b/js/viewer.js @@ -106,6 +106,8 @@ } }; - initPage(); + $(document).ready(function() { + initPage(); + }); })(OCA); @@ -104,11 +104,11 @@ OC.L10N.register( "File has been converted. Its content might look different.": "Файлът бе преобразуван. Съдържанието му може да изглежда различно.", "Download as": "Изтегли като", "Download": "Изтегли", - "Convert into": "Конвертирай в", "Origin format": "Формат на произход", "Failed to send notification": "Неуспешно изпращане на известие", "Notification sent successfully": "Успешно изпратено известие", "%1\$s mentioned in the %2\$s: \"%3\$s\".": "%1\$s, споменат във %2\$s: \"%3\$s\".", - "{notifier} mentioned in the {file}: \"%1\$s\".": "{notifier} ha mencionado en {file}: \"%1\$s\"." + "{notifier} mentioned in the {file}: \"%1\$s\".": "{notifier} ha mencionado en {file}: \"%1\$s\".", + "Choose a format to convert {fileName}": "Изберете формат за конвертиране {fileName}" }, "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"); diff --git a/l10n/bg.json b/l10n/bg.json index 88f466a..334e09d 100644 --- a/l10n/bg.json +++ b/l10n/bg.json @@ -102,11 +102,11 @@ "File has been converted. Its content might look different.": "Файлът бе преобразуван. Съдържанието му може да изглежда различно.", "Download as": "Изтегли като", "Download": "Изтегли", - "Convert into": "Конвертирай в", "Origin format": "Формат на произход", "Failed to send notification": "Неуспешно изпращане на известие", "Notification sent successfully": "Успешно изпратено известие", "%1$s mentioned in the %2$s: \"%3$s\".": "%1$s, споменат във %2$s: \"%3$s\".", - "{notifier} mentioned in the {file}: \"%1$s\".": "{notifier}, споменат във {file}: \"%1$s\"." + "{notifier} mentioned in the {file}: \"%1$s\".": "{notifier}, споменат във {file}: \"%1$s\".", + "Choose a format to convert {fileName}": "Изберете формат за конвертиране {fileName}" },"pluralForm" :"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);" }
\ No newline at end of file @@ -104,11 +104,11 @@ OC.L10N.register( "File has been converted. Its content might look different.": "Die Datei wurde konvertiert. Der Inhalt könnte anders aussehen.", "Download as": "Herunterladen als", "Download": "Herunterladen", - "Convert into": "Konvertieren in", "Origin format": "Ursprüngliches Format", "Failed to send notification": "Fehler beim Senden einer Benachrichtigung", "Notification sent successfully": "Benachrichtigung erfolgreich gesendet", "%1\$s mentioned in the %2\$s: \"%3\$s\".": "%1\$s hat in %2\$s erwähnt: \"%3\$s\".", - "{notifier} mentioned in the {file}: \"%1\$s\".": "{notifier} hat in {file} erwähnt: \"%1\$s\"." + "{notifier} mentioned in the {file}: \"%1\$s\".": "{notifier} hat in {file} erwähnt: \"%1\$s\".", + "Choose a format to convert {fileName}": "Wählen Sie das Format für {fileName} aus" }, "nplurals=2; plural=(n != 1);"); diff --git a/l10n/de.json b/l10n/de.json index 048a12f..72bba77 100644 --- a/l10n/de.json +++ b/l10n/de.json @@ -102,11 +102,11 @@ "File has been converted. Its content might look different.": "Die Datei wurde konvertiert. Der Inhalt könnte anders aussehen.", "Download as": "Herunterladen als", "Download": "Herunterladen", - "Convert into": "Konvertieren in", "Origin format": "Ursprüngliches Format", "Failed to send notification": "Fehler beim Senden einer Benachrichtigung", "Notification sent successfully": "Benachrichtigung erfolgreich gesendet", "%1$s mentioned in the %2$s: \"%3$s\".": "%1$s hat in %2$s erwähnt: \"%3$s\".", - "{notifier} mentioned in the {file}: \"%1$s\".": "{notifier} hat in {file} erwähnt: \"%1$s\"." + "{notifier} mentioned in the {file}: \"%1$s\".": "{notifier} hat in {file} erwähnt: \"%1$s\".", + "Choose a format to convert {fileName}": "Wählen Sie das Format für {fileName} aus" },"pluralForm" :"nplurals=2; plural=(n != 1);" }
\ No newline at end of file diff --git a/l10n/de_DE.js b/l10n/de_DE.js index 5819f73..e8b5676 100644 --- a/l10n/de_DE.js +++ b/l10n/de_DE.js @@ -104,11 +104,11 @@ OC.L10N.register( "File has been converted. Its content might look different.": "Die Datei wurde konvertiert. Der Inhalt könnte anders aussehen.", "Download as": "Herunterladen als", "Download": "Herunterladen", - "Convert into": "Konvertieren in", "Origin format": "Ursprüngliches Format", "Failed to send notification": "Fehler beim Senden einer Benachrichtigung", "Notification sent successfully": "Benachrichtigung erfolgreich gesendet", "%1\$s mentioned in the %2\$s: \"%3\$s\".": "%1\$s hat in %2\$s erwähnt: \"%3\$s\".", - "{notifier} mentioned in the {file}: \"%1\$s\".": "{notifier} hat in {file} erwähnt: \"%1\$s\"." + "{notifier} mentioned in the {file}: \"%1\$s\".": "{notifier} hat in {file} erwähnt: \"%1\$s\".", + "Choose a format to convert {fileName}": "Wählen Sie das Format für {fileName} aus" }, "nplurals=2; plural=(n != 1);"); diff --git a/l10n/de_DE.json b/l10n/de_DE.json index 71a103c..91740b0 100644 --- a/l10n/de_DE.json +++ b/l10n/de_DE.json @@ -102,11 +102,11 @@ "File has been converted. Its content might look different.": "Die Datei wurde konvertiert. Der Inhalt könnte anders aussehen.", "Download as": "Herunterladen als", "Download": "Herunterladen", - "Convert into": "Konvertieren in", "Origin format": "Ursprüngliches Format", "Failed to send notification": "Fehler beim Senden einer Benachrichtigung", "Notification sent successfully": "Benachrichtigung erfolgreich gesendet", "%1$s mentioned in the %2$s: \"%3$s\".": "%1$s hat in %2$s erwähnt: \"%3$s\".", - "{notifier} mentioned in the {file}: \"%1$s\".": "{notifier} hat in {file} erwähnt: \"%1$s\"." + "{notifier} mentioned in the {file}: \"%1$s\".": "{notifier} hat in {file} erwähnt: \"%1$s\".", + "Choose a format to convert {fileName}": "Wählen Sie das Format für {fileName} aus" },"pluralForm" :"nplurals=2; plural=(n != 1);" }
\ No newline at end of file @@ -104,11 +104,11 @@ OC.L10N.register( "File has been converted. Its content might look different.": "El archivo se ha convertido. Su contenido puede ser distinto.", "Download as": "Descargar como", "Download": "Descargar", - "Convert into": "Convertir en", "Origin format": "Formato original", "Failed to send notification": "Error al enviar la notificación", "Notification sent successfully": "Notificación enviada correctamente", "%1\$s mentioned in the %2\$s: \"%3\$s\".": "%1\$s ha mencionado en %2\$s: \"%3\$s\".", - "{notifier} mentioned in the {file}: \"%1\$s\".": "{notifier} ha mencionado en {file}: \"%1\$s\"." + "{notifier} mentioned in the {file}: \"%1\$s\".": "{notifier} ha mencionado en {file}: \"%1\$s\".", + "Choose a format to convert {fileName}": "Elija un formato para convertir {fileName}" }, "nplurals=2; plural=(n != 1);"); diff --git a/l10n/es.json b/l10n/es.json index 82dcc57..4f2b097 100644 --- a/l10n/es.json +++ b/l10n/es.json @@ -102,11 +102,11 @@ "File has been converted. Its content might look different.": "El archivo se ha convertido. Su contenido puede ser distinto.", "Download as": "Descargar como", "Download": "Descargar", - "Convert into": "Convertir en", "Origin format": "Formato original", "Failed to send notification": "Error al enviar la notificación", "Notification sent successfully": "Notificación enviada correctamente", "%1$s mentioned in the %2$s: \"%3$s\".": "%1$s ha mencionado en %2$s: \"%3$s\".", - "{notifier} mentioned in the {file}: \"%1$s\".": "{notifier} ha mencionado en {file}: \"%1$s\"." + "{notifier} mentioned in the {file}: \"%1$s\".": "{notifier} ha mencionado en {file}: \"%1$s\".", + "Choose a format to convert {fileName}": "Elija un formato para convertir {fileName}" },"pluralForm" :"nplurals=2; plural=(n != 1);" }
\ No newline at end of file @@ -104,11 +104,11 @@ OC.L10N.register( "File has been converted. Its content might look different.": "Le fichier a été converti. Son contenu peut s'afficher différemment.", "Download as": "Télécharger sous", "Download": "Télécharger", - "Convert into": "Convertir en", "Origin format": "Format d’origin", "Failed to send notification": "Échec de l’envoi de la notification", "Notification sent successfully": "Notification a été envoyée avec succès", "%1\$s mentioned in the %2\$s: \"%3\$s\".": "%1\$s a mentionné dans %2\$s: \"%3\$s\".", - "{notifier} mentioned in the {file}: \"%1\$s\".": "{notifier} a mentionné dans {file}: \"%1\$s\"." + "{notifier} mentioned in the {file}: \"%1\$s\".": "{notifier} a mentionné dans {file}: \"%1\$s\".", + "Choose a format to convert {fileName}": "Choisissez un format à convertir {fileName}" }, "nplurals=2; plural=(n != 1);"); diff --git a/l10n/fr.json b/l10n/fr.json index c433938..f25d362 100644 --- a/l10n/fr.json +++ b/l10n/fr.json @@ -102,11 +102,11 @@ "File has been converted. Its content might look different.": "Le fichier a été converti. Son contenu peut s'afficher différemment.", "Download as": "Télécharger sous", "Download": "Télécharger", - "Convert into": "Convertir en", "Origin format": "Format d’origin", "Failed to send notification": "Échec de l’envoi de la notification", "Notification sent successfully": "Notification a été envoyée avec succès", "%1$s mentioned in the %2$s: \"%3$s\".": "%1$s a mentionné dans %2$s: \"%3$s\".", - "{notifier} mentioned in the {file}: \"%1$s\".": "{notifier} a mentionné dans {file}: \"%1$s\"." + "{notifier} mentioned in the {file}: \"%1$s\".": "{notifier} a mentionné dans {file}: \"%1$s\".", + "Choose a format to convert {fileName}": "Choisissez un format à convertir {fileName}" },"pluralForm" :"nplurals=2; plural=(n != 1);" } @@ -104,11 +104,11 @@ OC.L10N.register( "File has been converted. Its content might look different.": "Il file è stato convertito. Il suo contenuto potrebbe avere un aspetto diverso.", "Download as": "Scaricare come", "Download": "Scaricare", - "Convert into": "Convertire in", "Origin format": "Formato di origine", "Failed to send notification": "Invio di notifica non riuscito", "Notification sent successfully": "Notifica è stata inviata con successo", "%1\$s mentioned in the %2\$s: \"%3\$s\".": "%1\$s ha menzionato in %2\$s: \"%3\$s\".", - "{notifier} mentioned in the {file}: \"%1\$s\".": "{notifier} ha menzionato nel {file}: \"%1\$s\"." + "{notifier} mentioned in the {file}: \"%1\$s\".": "{notifier} ha menzionato nel {file}: \"%1\$s\".", + "Choose a format to convert {fileName}": "Scegli un formato per convertire {fileName}" }, "nplurals=2; plural=(n != 1);");
\ No newline at end of file diff --git a/l10n/it.json b/l10n/it.json index b6867d4..70878d5 100644 --- a/l10n/it.json +++ b/l10n/it.json @@ -102,11 +102,11 @@ "File has been converted. Its content might look different.": "Il file è stato convertito. Il suo contenuto potrebbe avere un aspetto diverso.", "Download as": "Scaricare come", "Download": "Scaricare", - "Convert into": "Convertire in", "Origin format": "Formato di origine", "Failed to send notification": "Invio di notifica non riuscito", "Notification sent successfully": "Notifica è stata inviata con successo", "%1$s mentioned in the %2$s: \"%3$s\".": "%1$s ha menzionato in %2$s: \"%3$s\".", - "{notifier} mentioned in the {file}: \"%1$s\".": "{notifier} ha menzionato nel {file}: \"%1$s\"." + "{notifier} mentioned in the {file}: \"%1$s\".": "{notifier} ha menzionato nel {file}: \"%1$s\".", + "Choose a format to convert {fileName}": "Scegli un formato per convertire {fileName}" },"pluralForm" :"nplurals=2; plural=(n != 1);" }
\ No newline at end of file @@ -104,11 +104,11 @@ OC.L10N.register( "File has been converted. Its content might look different.": "ファイルが変換されました。 その内容は異なって見えるかもしれません。", "Download as": "別の形式でダウンロード", "Download": "ダウンロード", - "Convert into": "に変換する", "Origin format": "オリジンの形式", "Failed to send notification": "通知を送信できませんでした", "Notification sent successfully": "通知を送信しました", "%1\$s mentioned in the %2\$s: \"%3\$s\".": "%1\$s は %2\$s: \"%3\$s\"に記載されました。", - "{notifier} mentioned in the {file}: \"%1\$s\".": "{notifier} は {file}: \"%1\$s\"に記載しました。" + "{notifier} mentioned in the {file}: \"%1\$s\".": "{notifier} は {file}: \"%1\$s\"に記載しました。", + "Choose a format to convert {fileName}": "{fileName}を変換する形式を選択してください" }, "nplurals=2; plural=(n != 1);"); diff --git a/l10n/ja.json b/l10n/ja.json index 4c1f4bd..90eb6ce 100644 --- a/l10n/ja.json +++ b/l10n/ja.json @@ -102,11 +102,11 @@ "File has been converted. Its content might look different.": "ファイルが変換されました。 その内容は異なって見えるかもしれません。", "Download as": "別の形式でダウンロード", "Download": "ダウンロード", - "Convert into": "に変換する", "Origin format": "オリジンの形式", "Failed to send notification": "通知を送信できませんでした", "Notification sent successfully": "通知を送信しました", "%1$s mentioned in the %2$s: \"%3$s\".": "%1$s は %2$s: \"%3$s\"に記載されました。", - "{notifier} mentioned in the {file}: \"%1$s\".": "{notifier} は {file}: \"%1$s\"に記載しました。" + "{notifier} mentioned in the {file}: \"%1$s\".": "{notifier} は {file}: \"%1$s\"に記載しました。", + "Choose a format to convert {fileName}": "{fileName}を変換する形式を選択してください" },"pluralForm" :"nplurals=2; plural=(n != 1);" }
\ No newline at end of file @@ -104,11 +104,11 @@ OC.L10N.register( "File has been converted. Its content might look different.": "Plik został przekonwertowany. Jego zawartość może wyglądać inaczej.",
"Download as": "Pobierz jako",
"Download": "Pobierz",
- "Convert into": "Konwertuj do",
"Origin format": "Oryginalny format",
"Failed to send notification": "Nie udało się wysłać powiadomienia",
"Notification sent successfully": "Powiadomienie zostało wysłane",
"%1\$s mentioned in the %2\$s: \"%3\$s\".": "%1\$s dodał(a) w %2\$s następujący komentarz: \"%3\$s\".",
- "{notifier} mentioned in the {file}: \"%1\$s\".": "{notifier} dodał(a) w {file} następujący komentarz: \"%1\$s\"."
+ "{notifier} mentioned in the {file}: \"%1\$s\".": "{notifier} dodał(a) w {file} następujący komentarz: \"%1\$s\".",
+ "Choose a format to convert {fileName}": "Wybierz format, do którego chcesz przekonwertować {fileName}"
},
"nplurals=2; plural=(n != 1);");
\ No newline at end of file diff --git a/l10n/pl.json b/l10n/pl.json index e265268..73f35f1 100644 --- a/l10n/pl.json +++ b/l10n/pl.json @@ -102,11 +102,11 @@ "File has been converted. Its content might look different.": "Plik został przekonwertowany. Jego zawartość może wyglądać inaczej.",
"Download as": "Pobierz jako",
"Download": "Pobierz",
- "Convert into": "Konwertuj do",
"Origin format": "Oryginalny format",
"Failed to send notification": "Nie udało się wysłać powiadomienia",
"Notification sent successfully": "Powiadomienie zostało wysłane",
"%1$s mentioned in the %2$s: \"%3$s\".": "%1$s dodał(a) w %2$s następujący komentarz: \"%3$s\".",
- "{notifier} mentioned in the {file}: \"%1$s\".": "{notifier} dodał(a) w {file} następujący komentarz: \"%1$s\"."
+ "{notifier} mentioned in the {file}: \"%1$s\".": "{notifier} dodał(a) w {file} następujący komentarz: \"%1$s\".",
+ "Choose a format to convert {fileName}": "Wybierz format, do którego chcesz przekonwertować {fileName}"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
}
\ No newline at end of file diff --git a/l10n/pt_BR.js b/l10n/pt_BR.js index 6558701..88c9a5e 100644 --- a/l10n/pt_BR.js +++ b/l10n/pt_BR.js @@ -104,11 +104,11 @@ OC.L10N.register( "File has been converted. Its content might look different.": "O arquivo foi convertido. Seu conteúdo pode ser diferente.", "Download as": "Baixar", "Download": "Baixar como", - "Convert into": "Converter em", "Origin format": "Formato de origem", "Failed to send notification": "Falha ao enviar notificação", "Notification sent successfully": "Notificação enviada com sucesso", "%1\$s mentioned in the %2\$s: \"%3\$s\".": "%1\$s mencionado em %2\$s: \"%3\$s\".", - "{notifier} mentioned in the {file}: \"%1\$s\".": "{notifier} mencionado em {file}: \"%1\$s\"." + "{notifier} mentioned in the {file}: \"%1\$s\".": "{notifier} mencionado em {file}: \"%1\$s\".", + "Choose a format to convert {fileName}": "Escolha um formato para converter {fileName}" }, "nplurals=2; plural=(n != 1);"); diff --git a/l10n/pt_BR.json b/l10n/pt_BR.json index 75557f0..215e5b9 100644 --- a/l10n/pt_BR.json +++ b/l10n/pt_BR.json @@ -102,11 +102,11 @@ "File has been converted. Its content might look different.": "O arquivo foi convertido. Seu conteúdo pode ser diferente.", "Download as": "Baixar", "Download": "Baixar como", - "Convert into": "Converter em", "Origin format": "Formato de origem", "Failed to send notification": "Falha ao enviar notificação", "Notification sent successfully": "Notificação enviada com sucesso", "%1$s mentioned in the %2$s: \"%3$s\".": "%1$s mencionado em %2$s: \"%3$s\".", - "{notifier} mentioned in the {file}: \"%1$s\".": "{notifier} mencionado em {file}: \"%1$s\"." + "{notifier} mentioned in the {file}: \"%1$s\".": "{notifier} mencionado em {file}: \"%1$s\".", + "Choose a format to convert {fileName}": "Escolha um formato para converter {fileName}" },"pluralForm" :"nplurals=2; plural=(n != 1);" } @@ -104,11 +104,11 @@ OC.L10N.register( "File has been converted. Its content might look different.": "Файл был сконвертирован. Его форматирование могло измениться.", "Download as": "Скачать как", "Download": "Скачать", - "Convert into": "Конвертировать в", "Origin format": "Оригинальный формат", "Failed to send notification": "Ошибка отправки оповещения", "Notification sent successfully": "Оповещение успешно отправлено", - "%1\$s mentioned in the %2\$s: \"%3\$s\".": "%1\$s упоминул в %2\$s: \"%3\$s\".", - "{notifier} mentioned in the {file}: \"%1\$s\".": "{notifier} упоминул в {file}: \"%1\$s\"." + "%1\$s mentioned in the %2\$s: \"%3\$s\".": "%1\$s упомянул в %2\$s: \"%3\$s\".", + "{notifier} mentioned in the {file}: \"%1\$s\".": "{notifier} упомянул в {file}: \"%1\$s\".", + "Choose a format to convert {fileName}": "Выберите формат для {fileName}" }, "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"); diff --git a/l10n/ru.json b/l10n/ru.json index 38b928e..81b2801 100644 --- a/l10n/ru.json +++ b/l10n/ru.json @@ -102,11 +102,11 @@ "File has been converted. Its content might look different.": "Файл был сконвертирован. Его форматирование могло измениться.", "Download as": "Скачать как", "Download": "Скачать", - "Convert into": "Конвертировать в", "Origin format": "Оригинальный формат", "Failed to send notification": "Ошибка отправки оповещения", "Notification sent successfully": "Оповещение успешно отправлено", - "%1$s mentioned in the %2$s: \"%3$s\".": "%1$s упоминул в %2$s: \"%3$s\".", - "{notifier} mentioned in the {file}: \"%1$s\".": "{notifier} упоминул в {file}: \"%1$s\"." + "%1$s mentioned in the %2$s: \"%3$s\".": "%1$s упомянул в %2$s: \"%3$s\".", + "{notifier} mentioned in the {file}: \"%1$s\".": "{notifier} упомянул в {file}: \"%1$s\".", + "Choose a format to convert {fileName}": "Выберите формат для {fileName}" },"pluralForm" :"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);" }
\ No newline at end of file @@ -104,11 +104,11 @@ OC.L10N.register( "File has been converted. Its content might look different.": "Filen har konverterats. Dess innehåll kan se annorlunda ut.", "Download as": "Ladda ned som", "Download": "Ladda ned", - "Convert into": "Konvertera till", "Origin format": "Ursprungsformat", "Failed to send notification": "Det gick inte att skicka aviseringen", "Notification sent successfully": "Aviseringen har skickats", "%1\$s mentioned in the %2\$s: \"%3\$s\".": "%1\$s har nämnt i %2\$s: \"%3\$s\".", - "{notifier} mentioned in the {file}: \"%1\$s\".": "{notifier} har nämnt i {file}: \"%1\$s\"." + "{notifier} mentioned in the {file}: \"%1\$s\".": "{notifier} har nämnt i {file}: \"%1\$s\".", + "Choose a format to convert {fileName}": "Välj det filformat som {fileName} ska konverteras till." }, "nplurals=2; plural=(n != 1);"); diff --git a/l10n/sv.json b/l10n/sv.json index 99c8845..3cab206 100644 --- a/l10n/sv.json +++ b/l10n/sv.json @@ -102,11 +102,11 @@ "File has been converted. Its content might look different.": "Filen har konverterats. Dess innehåll kan se annorlunda ut.", "Download as": "Ladda ned som", "Download": "Ladda ned", - "Convert into": "Konvertera till", "Origin format": "Ursprungsformat", "Failed to send notification": "Det gick inte att skicka aviseringen", "Notification sent successfully": "Aviseringen har skickats", "%1$s mentioned in the %2$s: \"%3$s\".": "%1$s har nämnt i %2$s: \"%3$s\".", - "{notifier} mentioned in the {file}: \"%1$s\".": "{notifier} har nämnt i {file}: \"%1$s\"." + "{notifier} mentioned in the {file}: \"%1$s\".": "{notifier} har nämnt i {file}: \"%1$s\".", + "Choose a format to convert {fileName}": "Välj det filformat som {fileName} ska konverteras till." },"pluralForm" :"nplurals=2; plural=(n != 1);" }
\ No newline at end of file diff --git a/l10n/zh_CN.js b/l10n/zh_CN.js index 81512d0..59e6c9e 100644 --- a/l10n/zh_CN.js +++ b/l10n/zh_CN.js @@ -104,11 +104,11 @@ OC.L10N.register( "File has been converted. Its content might look different.": "文件已被转换。其内容可能看起来有所不同。", "Download as": "下载为", "Download": "下载", - "Convert into": "转换为", "Origin format": "原产地格式", "Failed to send notification": "发送通知失败", "Notification sent successfully": "通知发送成功", "%1\$s mentioned in the %2\$s: \"%3\$s\".": "%1\$s 提到 %2\$s: \"%3\$s\".", - "{notifier} mentioned in the {file}: \"%1\$s\".": "{notifier} 提到 {file}: \"%1\$s\"." + "{notifier} mentioned in the {file}: \"%1\$s\".": "{notifier} 提到 {file}: \"%1\$s\".", + "Choose a format to convert {fileName}": "选择要转换{fileName}的格式" }, "nplurals=2; plural=(n != 1);"); diff --git a/l10n/zh_CN.json b/l10n/zh_CN.json index 4b082de..54028f1 100644 --- a/l10n/zh_CN.json +++ b/l10n/zh_CN.json @@ -102,11 +102,11 @@ "File has been converted. Its content might look different.": "文件已被转换。其内容可能看起来有所不同。", "Download as": "下载为", "Download": "下载", - "Convert into": "转换为", "Origin format": "原产地格式", "Failed to send notification": "发送通知失败", "Notification sent successfully": "通知发送成功", "%1$s mentioned in the %2$s: \"%3$s\".": "%1$s 提到 %2$s: \"%3$s\".", - "{notifier} mentioned in the {file}: \"%1$s\".": "{notifier} 提到 {file}: \"%1$s\"." + "{notifier} mentioned in the {file}: \"%1$s\".": "{notifier} 提到 {file}: \"%1$s\".", + "Choose a format to convert {fileName}": "选择要转换{fileName}的格式" },"pluralForm" :"nplurals=2; plural=(n != 1);" }
\ No newline at end of file diff --git a/lib/appconfig.php b/lib/appconfig.php index 87865dc..b6cdacd 100644 --- a/lib/appconfig.php +++ b/lib/appconfig.php @@ -945,12 +945,14 @@ class AppConfig { /** * Check access for group * + * @param string $userId - user identifier + * * @return bool */ - public function isUserAllowedToUse() { + public function isUserAllowedToUse($userId = null) { // no user -> no $userSession = \OC::$server->getUserSession(); - if ($userSession === null || !$userSession->isLoggedIn()) { + if (is_null($userId) && ($userSession === null || !$userSession->isLoggedIn())) { return false; } @@ -960,7 +962,14 @@ class AppConfig { return true; } - $user = $userSession->getUser(); + if (is_null($userId)) { + $user = $userSession->getUser(); + } else { + $user = \OC::$server->getUserManager()->get($userId); + if (empty($user)) { + return false; + } + } foreach ($groups as $groupName) { // group unknown -> error and allow nobody @@ -1088,39 +1097,39 @@ class AppConfig { * @var array */ private $formats = [ - "csv" => [ "mime" => "text/csv", "type" => "spreadsheet", "edit" => true, "editable" => true, "saveas" => ["ods", "pdf", "xlsx"] ], - "doc" => [ "mime" => "application/msword", "type" => "text", "conv" => true, "saveas" => ["docx", "odt", "pdf", "rtf", "txt"] ], - "docm" => [ "mime" => "application/vnd.ms-word.document.macroEnabled.12", "type" => "text", "conv" => true, "saveas" => ["docx", "odt", "pdf", "rtf", "txt"] ], - "docx" => [ "mime" => "application/vnd.openxmlformats-officedocument.wordprocessingml.document", "type" => "text", "edit" => true, "def" => true, "saveas" => ["odt", "pdf", "rtf", "txt"] ], - "dot" => [ "type" => "text", "conv" => true, "saveas" => ["docx", "odt", "pdf", "rtf", "txt"] ], - "dotx" => [ "mime" => "application/vnd.openxmlformats-officedocument.wordprocessingml.template", "type" => "text", "conv" => true, "saveas" => ["docx", "odt", "pdf", "rtf", "txt"] ], - "epub" => [ "mime" => "application/epub+zip", "type" => "text", "conv" => true, "saveas" => ["docx", "odt", "pdf", "rtf", "txt"] ], - "htm" => [ "type" => "text", "conv" => true ], - "html" => [ "mime" => "text/html", "type" => "text", "conv" => true, "saveas" => ["docx", "odt", "pdf", "rtf", "txt"] ], - "odp" => [ "mime" => "application/vnd.oasis.opendocument.presentation", "type" => "presentation", "conv" => true, "editable" => true, "saveas" => ["pdf", "pptx"] ], - "ods" => [ "mime" => "application/vnd.oasis.opendocument.spreadsheet", "type" => "spreadsheet", "conv" => true, "editable" => true, "saveas" => ["csv", "pdf", "xlsx"] ], - "odt" => [ "mime" => "application/vnd.oasis.opendocument.text", "type" => "text", "conv" => true, "editable" => true, "saveas" => ["docx", "pdf", "rtf", "txt"] ], - "otp" => [ "mime" => "application/vnd.oasis.opendocument.presentation-template", "type" => "presentation", "conv" => true, "saveas" => ["pdf", "pptx", "odp"] ], - "ots" => [ "mime" => "application/vnd.oasis.opendocument.spreadsheet-template", "type" => "spreadsheet", "conv" => true, "saveas" => ["csv", "ods", "pdf", "xlsx"] ], - "ott" => [ "mime" => "application/vnd.oasis.opendocument.text-template", "type" => "text", "conv" => true, "saveas" => ["docx", "odt", "pdf", "rtf", "txt"] ], - "pdf" => [ "mime" => "application/pdf", "type" => "text" ], - "pot" => [ "type" => "presentation", "conv" => true, "saveas" => ["pdf", "pptx", "odp"] ], - "potm" => [ "mime" => "application/vnd.ms-powerpoint.template.macroEnabled.12", "type" => "presentation", "conv" => true, "saveas" => ["pdf", "pptx", "odp"] ], - "potx" => [ "mime" => "application/vnd.openxmlformats-officedocument.presentationml.template", "type" => "presentation", "conv" => true, "saveas" => ["pdf", "pptx", "odp"] ], - "pps" => [ "type" => "presentation", "conv" => true, "saveas" => ["pdf", "pptx", "odp"] ], - "ppsm" => [ "mime" => "application/vnd.ms-powerpoint.slideshow.macroEnabled.12", "type" => "presentation", "conv" => true, "saveas" => ["pdf", "pptx", "odp"] ], - "ppsx" => [ "mime" => "application/vnd.openxmlformats-officedocument.presentationml.slideshow", "type" => "presentation", "conv" => true, "saveas" => ["pdf", "pptx", "odp"] ], - "ppt" => [ "mime" => "application/vnd.ms-powerpoint", "type" => "presentation", "conv" => true, "saveas" => ["pdf", "pptx", "odp"] ], - "pptm" => [ "mime" => "application/vnd.ms-powerpoint.presentation.macroEnabled.12", "type" => "presentation", "conv" => true, "saveas" => ["pdf", "pptx", "odp"] ], - "pptx" => [ "mime" => "application/vnd.openxmlformats-officedocument.presentationml.presentation", "type" => "presentation", "edit" => true, "def" => true, "saveas" => ["pdf", "odp"] ], - "rtf" => [ "mime" => "text/rtf", "type" => "text", "conv" => true, "editable" => true, "saveas" => ["docx", "odt", "pdf", "txt"] ], - "txt" => [ "mime" => "text/plain", "type" => "text", "edit" => true, "editable" => true, "saveas" => ["docx", "odt", "pdf", "rtf"] ], - "xls" => [ "mime" => "application/vnd.ms-excel", "type" => "spreadsheet", "conv" => true, "saveas" => ["csv", "ods", "pdf", "xlsx"] ], - "xlsm" => [ "mime" => "application/vnd.ms-excel.sheet.macroEnabled.12", "type" => "spreadsheet", "conv" => true, "saveas" => ["csv", "ods", "pdf", "xlsx"] ], - "xlsx" => [ "mime" => "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "type" => "spreadsheet", "edit" => true, "def" => true, "saveas" => ["csv", "ods", "pdf"] ], - "xlt" => [ "type" => "spreadsheet", "conv" => true, "saveas" => ["csv", "ods", "pdf", "xlsx"] ], - "xltm" => [ "mime" => "application/vnd.ms-excel.template.macroEnabled.12", "type" => "spreadsheet", "conv" => true, "saveas" => ["csv", "ods", "pdf", "xlsx"] ], - "xltx" => [ "mime" => "application/vnd.openxmlformats-officedocument.spreadsheetml.template", "type" => "spreadsheet", "conv" => true, "saveas" => ["csv", "ods", "pdf", "xlsx"] ] + "csv" => [ "mime" => "text/csv", "type" => "cell", "edit" => true, "editable" => true, "saveas" => ["ods", "pdf", "xlsx"] ], + "doc" => [ "mime" => "application/msword", "type" => "word", "conv" => true, "saveas" => ["docx", "odt", "pdf", "rtf", "txt"] ], + "docm" => [ "mime" => "application/vnd.ms-word.document.macroEnabled.12", "type" => "word", "conv" => true, "saveas" => ["docx", "odt", "pdf", "rtf", "txt"] ], + "docx" => [ "mime" => "application/vnd.openxmlformats-officedocument.wordprocessingml.document", "type" => "word", "edit" => true, "def" => true, "saveas" => ["odt", "pdf", "rtf", "txt"] ], + "dot" => [ "type" => "word", "conv" => true, "saveas" => ["docx", "odt", "pdf", "rtf", "txt"] ], + "dotx" => [ "mime" => "application/vnd.openxmlformats-officedocument.wordprocessingml.template", "type" => "word", "conv" => true, "saveas" => ["docx", "odt", "pdf", "rtf", "txt"] ], + "epub" => [ "mime" => "application/epub+zip", "type" => "word", "conv" => true, "saveas" => ["docx", "odt", "pdf", "rtf", "txt"] ], + "htm" => [ "type" => "word", "conv" => true ], + "html" => [ "mime" => "text/html", "type" => "word", "conv" => true, "saveas" => ["docx", "odt", "pdf", "rtf", "txt"] ], + "odp" => [ "mime" => "application/vnd.oasis.opendocument.presentation", "type" => "slide", "conv" => true, "editable" => true, "saveas" => ["pdf", "pptx"] ], + "ods" => [ "mime" => "application/vnd.oasis.opendocument.spreadsheet", "type" => "cell", "conv" => true, "editable" => true, "saveas" => ["csv", "pdf", "xlsx"] ], + "odt" => [ "mime" => "application/vnd.oasis.opendocument.text", "type" => "word", "conv" => true, "editable" => true, "saveas" => ["docx", "pdf", "rtf", "txt"] ], + "otp" => [ "mime" => "application/vnd.oasis.opendocument.presentation-template", "type" => "slide", "conv" => true, "saveas" => ["pdf", "pptx", "odp"] ], + "ots" => [ "mime" => "application/vnd.oasis.opendocument.spreadsheet-template", "type" => "cell", "conv" => true, "saveas" => ["csv", "ods", "pdf", "xlsx"] ], + "ott" => [ "mime" => "application/vnd.oasis.opendocument.text-template", "type" => "word", "conv" => true, "saveas" => ["docx", "odt", "pdf", "rtf", "txt"] ], + "pdf" => [ "mime" => "application/pdf", "type" => "word" ], + "pot" => [ "type" => "slide", "conv" => true, "saveas" => ["pdf", "pptx", "odp"] ], + "potm" => [ "mime" => "application/vnd.ms-powerpoint.template.macroEnabled.12", "type" => "slide", "conv" => true, "saveas" => ["pdf", "pptx", "odp"] ], + "potx" => [ "mime" => "application/vnd.openxmlformats-officedocument.presentationml.template", "type" => "slide", "conv" => true, "saveas" => ["pdf", "pptx", "odp"] ], + "pps" => [ "type" => "slide", "conv" => true, "saveas" => ["pdf", "pptx", "odp"] ], + "ppsm" => [ "mime" => "application/vnd.ms-powerpoint.slideshow.macroEnabled.12", "type" => "slide", "conv" => true, "saveas" => ["pdf", "pptx", "odp"] ], + "ppsx" => [ "mime" => "application/vnd.openxmlformats-officedocument.presentationml.slideshow", "type" => "slide", "conv" => true, "saveas" => ["pdf", "pptx", "odp"] ], + "ppt" => [ "mime" => "application/vnd.ms-powerpoint", "type" => "slide", "conv" => true, "saveas" => ["pdf", "pptx", "odp"] ], + "pptm" => [ "mime" => "application/vnd.ms-powerpoint.presentation.macroEnabled.12", "type" => "slide", "conv" => true, "saveas" => ["pdf", "pptx", "odp"] ], + "pptx" => [ "mime" => "application/vnd.openxmlformats-officedocument.presentationml.presentation", "type" => "slide", "edit" => true, "def" => true, "saveas" => ["pdf", "odp"] ], + "rtf" => [ "mime" => "text/rtf", "type" => "word", "conv" => true, "editable" => true, "saveas" => ["docx", "odt", "pdf", "txt"] ], + "txt" => [ "mime" => "text/plain", "type" => "word", "edit" => true, "editable" => true, "saveas" => ["docx", "odt", "pdf", "rtf"] ], + "xls" => [ "mime" => "application/vnd.ms-excel", "type" => "cell", "conv" => true, "saveas" => ["csv", "ods", "pdf", "xlsx"] ], + "xlsm" => [ "mime" => "application/vnd.ms-excel.sheet.macroEnabled.12", "type" => "cell", "conv" => true, "saveas" => ["csv", "ods", "pdf", "xlsx"] ], + "xlsx" => [ "mime" => "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "type" => "cell", "edit" => true, "def" => true, "saveas" => ["csv", "ods", "pdf"] ], + "xlt" => [ "type" => "cell", "conv" => true, "saveas" => ["csv", "ods", "pdf", "xlsx"] ], + "xltm" => [ "mime" => "application/vnd.ms-excel.template.macroEnabled.12", "type" => "cell", "conv" => true, "saveas" => ["csv", "ods", "pdf", "xlsx"] ], + "xltx" => [ "mime" => "application/vnd.openxmlformats-officedocument.spreadsheetml.template", "type" => "cell", "conv" => true, "saveas" => ["csv", "ods", "pdf", "xlsx"] ] ]; /** diff --git a/lib/directeditor.php b/lib/directeditor.php index f7f694c..02bfc4c 100644 --- a/lib/directeditor.php +++ b/lib/directeditor.php @@ -207,8 +207,14 @@ class DirectEditor implements IEditor { $token->useTokenScope(); $file = $token->getFile(); $fileId = $file->getId(); + $userId = $token->getUser(); + $this->logger->debug("DirectEditor open: $fileId", ["app" => $this->appName]); + if (!$this->config->isUserAllowedToUse($userId)) { + return $this->renderError($this->trans->t("Not permitted")); + } + $documentServerUrl = $this->config->GetDocumentServerUrl(); if (empty($documentServerUrl)) { @@ -216,7 +222,6 @@ class DirectEditor implements IEditor { return $this->renderError($this->trans->t("ONLYOFFICE app is not configured. Please contact admin")); } - $userId = $token->getUser(); $directToken = $this->crypt->GetHash([ "userId" => $userId, "fileId" => $fileId, diff --git a/lib/fileutility.php b/lib/fileutility.php index 2cf0508..7ddfd20 100644 --- a/lib/fileutility.php +++ b/lib/fileutility.php @@ -183,7 +183,7 @@ class FileUtility { * * @return array */ - private function getShare($shareToken) { + public function getShare($shareToken) { if (empty($shareToken)) { return [null, $this->trans->t("FileId is empty")]; } diff --git a/lib/listeners/directeditorlistener.php b/lib/listeners/directeditorlistener.php new file mode 100644 index 0000000..6a28b98 --- /dev/null +++ b/lib/listeners/directeditorlistener.php @@ -0,0 +1,69 @@ +<?php +/** + * + * (c) Copyright Ascensio System SIA 2021 + * + * 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. + * + */ + +namespace OCA\Onlyoffice\Listeners; + +use OCP\EventDispatcher\Event; +use OCP\EventDispatcher\IEventListener; +use OCP\DirectEditing\RegisterDirectEditorEvent; + +use OCA\Onlyoffice\AppConfig; +use OCA\Onlyoffice\DirectEditor; + +/** + * DirectEditor listener + */ +class DirectEditorListener implements IEventListener { + + /** + * Application configuration + * + * @var AppConfig + */ + private $appConfig; + + /** + * Direct editor + * + * @var DirectEditor + */ + private $editor; + + /** + * @param AppConfig $config - application configuration + * @param DirectEditor $editor - direct editor + */ + public function __construct(AppConfig $appConfig, + DirectEditor $editor) { + $this->appConfig = $appConfig; + $this->editor = $editor; + } + + public function handle(Event $event): void { + if (!$event instanceof RegisterDirectEditorEvent) { + return; + } + + if (!empty($this->appConfig->GetDocumentServerUrl()) + && $this->appConfig->SettingsAreSuccessful()) { + + $event->register($this->editor); + } + } +}
\ No newline at end of file diff --git a/lib/listeners/filesharinglistener.php b/lib/listeners/filesharinglistener.php new file mode 100644 index 0000000..fbebbd4 --- /dev/null +++ b/lib/listeners/filesharinglistener.php @@ -0,0 +1,65 @@ +<?php +/** + * + * (c) Copyright Ascensio System SIA 2021 + * + * 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. + * + */ + +namespace OCA\Onlyoffice\Listeners; + +use OCP\EventDispatcher\Event; +use OCP\EventDispatcher\IEventListener; +use OCP\Util; + +use OCA\Files_Sharing\Event\BeforeTemplateRenderedEvent; + +use OCA\Onlyoffice\AppConfig; + +/** + * File Sharing listener + */ +class FileSharingListener implements IEventListener { + + /** + * Application configuration + * + * @var AppConfig + */ + private $appConfig; + + /** + * @param AppConfig $config - application configuration + */ + public function __construct(AppConfig $appConfig) { + $this->appConfig = $appConfig; + } + + public function handle(Event $event): void { + if (!$event instanceof BeforeTemplateRenderedEvent) { + return; + } + + if (!empty($this->appConfig->GetDocumentServerUrl()) + && $this->appConfig->SettingsAreSuccessful()) { + Util::addScript("onlyoffice", "main"); + + if ($this->appConfig->GetSameTab()) { + Util::addScript("onlyoffice", "listener"); + } + + Util::addStyle("onlyoffice", "main"); + } + } +}
\ No newline at end of file diff --git a/lib/listeners/fileslistener.php b/lib/listeners/fileslistener.php new file mode 100644 index 0000000..1c1abab --- /dev/null +++ b/lib/listeners/fileslistener.php @@ -0,0 +1,70 @@ +<?php +/** + * + * (c) Copyright Ascensio System SIA 2021 + * + * 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. + * + */ + +namespace OCA\Onlyoffice\Listeners; + +use OCP\EventDispatcher\Event; +use OCP\EventDispatcher\IEventListener; +use OCP\Util; + +use OCA\Files\Event\LoadAdditionalScriptsEvent; + +use OCA\Onlyoffice\AppConfig; + +/** + * File listener + */ +class FilesListener implements IEventListener { + + /** + * Application configuration + * + * @var AppConfig + */ + private $appConfig; + + /** + * @param AppConfig $config - application configuration + */ + public function __construct(AppConfig $appConfig) { + $this->appConfig = $appConfig; + } + + public function handle(Event $event): void { + if (!$event instanceof LoadAdditionalScriptsEvent) { + return; + } + + if (!empty($this->appConfig->GetDocumentServerUrl()) + && $this->appConfig->SettingsAreSuccessful() + && $this->appConfig->isUserAllowedToUse()) { + + Util::addScript("onlyoffice", "desktop"); + Util::addScript("onlyoffice", "main"); + Util::addScript("onlyoffice", "template"); + + if ($this->appConfig->GetSameTab()) { + Util::addScript("onlyoffice", "listener"); + } + + Util::addStyle("onlyoffice", "main"); + Util::addStyle("onlyoffice", "template"); + } + } +}
\ No newline at end of file diff --git a/lib/listeners/viewerlistener.php b/lib/listeners/viewerlistener.php new file mode 100644 index 0000000..c124145 --- /dev/null +++ b/lib/listeners/viewerlistener.php @@ -0,0 +1,69 @@ +<?php +/** + * + * (c) Copyright Ascensio System SIA 2021 + * + * 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. + * + */ + +namespace OCA\Onlyoffice\Listeners; + +use OCP\EventDispatcher\Event; +use OCP\EventDispatcher\IEventListener; +use OCP\Util; +use OCP\AppFramework\Http\ContentSecurityPolicy; + +use OCA\Viewer\Event\LoadViewer; + +use OCA\Onlyoffice\AppConfig; + +/** + * Viewer listener + */ +class ViewerListener implements IEventListener { + + /** + * Application configuration + * + * @var AppConfig + */ + private $appConfig; + + /** + * @param AppConfig $config - application configuration + */ + public function __construct(AppConfig $appConfig) { + $this->appConfig = $appConfig; + } + + public function handle(Event $event): void { + if (!$event instanceof LoadViewer) { + return; + } + + if (!empty($this->appConfig->GetDocumentServerUrl()) + && $this->appConfig->SettingsAreSuccessful() + && $this->appConfig->isUserAllowedToUse()) { + Util::addScript("onlyoffice", "viewer"); + Util::addScript("onlyoffice", "listener"); + + Util::addStyle("onlyoffice", "viewer"); + + $csp = new ContentSecurityPolicy(); + $csp->addAllowedFrameDomain("'self'"); + $cspManager = \OC::$server->getContentSecurityPolicyManager(); + $cspManager->addDefaultPolicy($csp); + } + } +}
\ No newline at end of file diff --git a/lib/listeners/widgetlistener.php b/lib/listeners/widgetlistener.php new file mode 100644 index 0000000..918ad1a --- /dev/null +++ b/lib/listeners/widgetlistener.php @@ -0,0 +1,59 @@ +<?php +/** + * + * (c) Copyright Ascensio System SIA 2021 + * + * 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. + * + */ + +namespace OCA\Onlyoffice\Listeners; + +use OCP\EventDispatcher\Event; +use OCP\EventDispatcher\IEventListener; +use OCP\Util; +use OCP\Dashboard\RegisterWidgetEvent; + +use OCA\Onlyoffice\AppConfig; + +/** + * Widget listener + */ +class WidgetListener implements IEventListener { + + /** + * Application configuration + * + * @var AppConfig + */ + private $appConfig; + + /** + * @param AppConfig $config - application configuration + */ + public function __construct(AppConfig $appConfig) { + $this->appConfig = $appConfig; + } + + public function handle(Event $event): void { + if (!$event instanceof RegisterWidgetEvent) { + return; + } + + if (!empty($this->appConfig->GetDocumentServerUrl()) + && $this->appConfig->SettingsAreSuccessful() + && $this->appConfig->isUserAllowedToUse()) { + Util::addScript("onlyoffice", "desktop"); + } + } +}
\ No newline at end of file diff --git a/lib/templatemanager.php b/lib/templatemanager.php index dcadfb0..59d8443 100644 --- a/lib/templatemanager.php +++ b/lib/templatemanager.php @@ -19,6 +19,8 @@ namespace OCA\Onlyoffice; +use OCP\Files\NotFoundException; + use OCP\Files\File; /** @@ -48,12 +50,17 @@ class TemplateManager { * @return Folder */ public static function GetGlobalTemplateDir() { - $rootFolder = \OC::$server->getRootFolder(); + $dirPath = "appdata_" . \OC::$server->getConfig()->GetSystemValue("instanceid", null) + . "/" . self::$appName + . "/" . self::$templateFolderName; - $appData = $rootFolder->get("appdata_" . \OC::$server->getConfig()->GetSystemValue("instanceid", null)); - - $appDir = $appData->nodeExists(self::$appName) ? $appData->get(self::$appName) : $appData->newFolder(self::$appName); - $templateDir = $appDir->nodeExists(self::$templateFolderName) ? $appDir->get(self::$templateFolderName) : $appDir->newFolder(self::$templateFolderName); + $rootFolder = \OC::$server->getRootFolder(); + $templateDir = null; + try { + $templateDir = $rootFolder->get($dirPath); + } catch (NotFoundException $e) { + $templateDir = $rootFolder->newFolder($dirPath); + } return $templateDir; } @@ -68,11 +75,10 @@ class TemplateManager { public static function GetGlobalTemplates($mimetype = null) { $templateDir = self::GetGlobalTemplateDir(); - if (!empty($mimetype)) { + $templatesList = $templateDir->getDirectoryListing(); + if (!empty($mimetype) + && is_array($templatesList) && count($templatesList) > 0) { $templatesList = $templateDir->searchByMime($mimetype); - - } else { - $templatesList = $templateDir->getDirectoryListing(); } return $templatesList; |