Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/ONLYOFFICE/onlyoffice-nextcloud.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Linnik <sergey.linnik@onlyoffice.com>2021-11-02 15:53:00 +0300
committerGitHub <noreply@github.com>2021-11-02 15:53:00 +0300
commit212be8a29299f7ed87a320fb5517874220e2de4d (patch)
tree158ada5e86f17dbba9267e21e0ab2aa243c1183f
parentd7cdf800343829f1b96db5662380985eb2c566f3 (diff)
parent9c3b677e6d681978b7e225144852da8ed86b57eb (diff)
Merge pull request #542 from ONLYOFFICE/developv7.2.0
Release/7.2.0
-rw-r--r--CHANGELOG.md11
-rw-r--r--README.md10
-rw-r--r--appinfo/application.php102
-rw-r--r--appinfo/info.xml4
-rw-r--r--appinfo/routes.php5
-rw-r--r--controller/editorapicontroller.php816
-rw-r--r--controller/editorcontroller.php685
-rw-r--r--img/cell.icobin0 -> 8348 bytes
-rw-r--r--img/slide.icobin0 -> 8348 bytes
-rw-r--r--img/word.icobin0 -> 8348 bytes
-rw-r--r--js/editor.js174
-rw-r--r--js/listener.js33
-rw-r--r--js/main.js42
-rw-r--r--js/viewer.js4
-rw-r--r--l10n/bg.js4
-rw-r--r--l10n/bg.json4
-rw-r--r--l10n/de.js4
-rw-r--r--l10n/de.json4
-rw-r--r--l10n/de_DE.js4
-rw-r--r--l10n/de_DE.json4
-rw-r--r--l10n/es.js4
-rw-r--r--l10n/es.json4
-rw-r--r--l10n/fr.js4
-rw-r--r--l10n/fr.json4
-rw-r--r--l10n/it.js4
-rw-r--r--l10n/it.json4
-rw-r--r--l10n/ja.js4
-rw-r--r--l10n/ja.json4
-rw-r--r--l10n/pl.js4
-rw-r--r--l10n/pl.json4
-rw-r--r--l10n/pt_BR.js4
-rw-r--r--l10n/pt_BR.json4
-rw-r--r--l10n/ru.js6
-rw-r--r--l10n/ru.json6
-rw-r--r--l10n/sv.js4
-rw-r--r--l10n/sv.json4
-rw-r--r--l10n/zh_CN.js4
-rw-r--r--l10n/zh_CN.json4
-rw-r--r--lib/appconfig.php81
-rw-r--r--lib/directeditor.php7
-rw-r--r--lib/fileutility.php2
-rw-r--r--lib/listeners/directeditorlistener.php69
-rw-r--r--lib/listeners/filesharinglistener.php65
-rw-r--r--lib/listeners/fileslistener.php70
-rw-r--r--lib/listeners/viewerlistener.php69
-rw-r--r--lib/listeners/widgetlistener.php59
-rw-r--r--lib/templatemanager.php24
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
diff --git a/README.md b/README.md
index 48d6bd7..37ebe09 100644
--- a/README.md
+++ b/README.md
@@ -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
new file mode 100644
index 0000000..05ecd8c
--- /dev/null
+++ b/img/cell.ico
Binary files differ
diff --git a/img/slide.ico b/img/slide.ico
new file mode 100644
index 0000000..888c7a8
--- /dev/null
+++ b/img/slide.ico
Binary files differ
diff --git a/img/word.ico b/img/word.ico
new file mode 100644
index 0000000..31f9ca4
--- /dev/null
+++ b/img/word.ico
Binary files differ
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);
diff --git a/js/main.js b/js/main.js
index be7dba0..027b61e 100644
--- a/js/main.js
+++ b/js/main.js
@@ -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);
diff --git a/l10n/bg.js b/l10n/bg.js
index 7f9f793..026a007 100644
--- a/l10n/bg.js
+++ b/l10n/bg.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} 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
diff --git a/l10n/de.js b/l10n/de.js
index 23682f8..170c66e 100644
--- a/l10n/de.js
+++ b/l10n/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.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
diff --git a/l10n/es.js b/l10n/es.js
index 196b931..081207b 100644
--- a/l10n/es.js
+++ b/l10n/es.js
@@ -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
diff --git a/l10n/fr.js b/l10n/fr.js
index c81a006..7536c5e 100644
--- a/l10n/fr.js
+++ b/l10n/fr.js
@@ -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);"
}
diff --git a/l10n/it.js b/l10n/it.js
index 2b8ac6e..901f3bc 100644
--- a/l10n/it.js
+++ b/l10n/it.js
@@ -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
diff --git a/l10n/ja.js b/l10n/ja.js
index 86a16b8..4eb00f7 100644
--- a/l10n/ja.js
+++ b/l10n/ja.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/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
diff --git a/l10n/pl.js b/l10n/pl.js
index 70b40f7..c8b04a9 100644
--- a/l10n/pl.js
+++ b/l10n/pl.js
@@ -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);"
}
diff --git a/l10n/ru.js b/l10n/ru.js
index 6543f1b..63ac85a 100644
--- a/l10n/ru.js
+++ b/l10n/ru.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\"."
+ "%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
diff --git a/l10n/sv.js b/l10n/sv.js
index 3d00d9c..6032107 100644
--- a/l10n/sv.js
+++ b/l10n/sv.js
@@ -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;