Как мы интегрировались с ownCloud и Nextcloud: подводные камни и их преодоление +16


Однажды один из наших пользователей написал, что ONLYOFFICE и ownCloud — это брак, заключенный на небесах (простите, в оригинале было match made in heaven) и странно, что никто еще не додумался запилить какой-нибудь плагин. Мы прикинули и подумали, что он прав. Тем более мы очень любим интегрироваться! В плане, что, конечно же, хотим, чтобы нашими редакторами пользовались всегда, везде и там, где удобно.

В общем, мы сами и сделали приложение для интеграции наших редакторов документов с ownCloud (а потом и Nextcloud) и в этой статье немножко об этом расскажем. Непреодолимых преград на нашем пути не было, но кое-какие трудности возникли и мы поделимся с вами опытом их преодоления. Во-первых, может, вам пригодится, а во-вторых, мы больше не можем держать это в себе! То есть, давно ничего не писали в блог.




Создать приложение просто, заставить его работать с ownCloud — нет


Итак, приложение для интеграции, он же коннектор, он же наше золотце — просто мостик между веб-сервисом документооборота ownCloud и нашим Сервером документов (Document server, редакторы наши, в общем). ownCloud милостиво предоставляет API для написания и встраивания приложений в своё рабочее пространство, и мы этим воспользовались.

В создании приложения нам здорово помогла официальная документация ownCloud, она же и помешала. Выполнив указанные там шаги, мы получили готовый шаблон приложения. Это было просто, но вот дальше начались сложности. Внутреннее API задокументированно, мягко говоря, не слишком подробно.

Например, для сохранения файла нам нужно было получить авторизацию под конкретным пользователем. Чтобы выполнить действие авторизации, нужно выполнить определенные команды: какие команды? Где их найти? Как их выполнить? Как вы думаете, что об этом говорится в документации? Правильный ответ: ничего.

Творческий метод


Трудности незадокументированности начались на самом первом этапе. Чтобы создать привязку к ownCloud на одном сервере и нашим Сервером документов на другом и организовать обмен данными между ними, необходимо сначала указать веб-адрес Сервера документов. Этот адрес сохраняется в базе данных для приложения и потом используется при открытии редактора или конвертации документов.

В общем, нам нужно указать адрес, но где? Где мы его будем указывать? Для начала нам нужна страничка настроек ONLYOFFICE в панели администрирования ownCloud, а она почему-то не появилась там сама по себе (хотя мы очень этого хотели). В общем, эту страничку надо как-то написать.

Тут на помощь пришли другие приложения для ownCloud'а с открытым кодом. Пришлось подсмотреть, как с этой задачей справились они. Конкретно со страницей настроек нам помогло официальное приложение ownCloud Antivirus App for files.

Вот что и куда мы добавили, руководствуясь опытом разработчиков этого приложения:

/appinfo/app.php
App::registerAdmin("onlyoffice", "settings")

/settings.php
User::checkAdminUser();
return new Application() -> getContainer() -> query("\OCA\Onlyoffice\Controller\SettingsController") -> index() -> render();

/controller/settingscontroller.php
class SettingsController extends Controller {
    private $config;
    public function __construct($AppName, IRequest $request, AppConfig $config) {
        parent::__construct($AppName, $request);
        $this->config = $config;
    }
    public function index() {
        $data = ["documentserver" => $this->config->GetDocumentServerUrl()];
        return new TemplateResponse($this->appName, "settings", $data, "blank");
    }
}

Информация о том, как получить доступ к файловой системе, есть в документации, но чтобы научиться получать контент файла по ссылке, нам понадобилось изучить официальное приложение Gallery.

Вот как мы это сделали:

/lib/downloadresponse.php
class DownloadResponse extends Response {
    private $content;
    public function __construct(File $file) {
        $this->setStatus(Http::STATUS_OK);
        $this->content = $file->getContent();

        $this->addHeader("Content-type", $file->getMimeType() . "; charset=utf-8");
        $this->addHeader("Content-Disposition", "attachment; filename*=UTF-8''" . rawurlencode($file->getName()) . "; filename=\"" . rawurlencode($file->getName()) . "\"");
    }
    public function render() {
        return $this->content;
    }
}


Добавлять своё действие в меню создания нового файла и в контекстное меню файла мы научились с помощью официального приложения Text Editor.

Вот как файл создается:

/js/main.js
OCA.Onlyoffice.NewFileMenu = {
    attach: function (menu) {
        if (menu.fileList.id !== "files") { return; }
        menu.addMenuEntry({
            id: "onlyofficeDocx",
            displayName: t(OCA.Onlyoffice.AppName, "Document"),
            iconClass: "icon-onlyoffice-new-docx",
            fileType: "docx",
            actionHandler: function (name) { OCA.Onlyoffice.CreateFile(name + ".docx", menu.fileList); }
        });
    }
};
OC.Plugins.register("OCA.Files.NewFileMenu", OCA.Onlyoffice.NewFileMenu);


А вот как он открывается в ONLYOFFICE:

OCA.Onlyoffice.FileList = {
    attach: function (fileList) {
        if (fileList.id == "trashbin") { return; }
        $.each(OCA.Onlyoffice.mimes, function (ext, attr) {
            fileList.fileActions.registerAction({
                name: "onlyofficeOpen",
                displayName: t(OCA.Onlyoffice.AppName, "Open in ONLYOFFICE"),
                mime: attr.mime,
                permissions: OC.PERMISSION_READ,
                icon: function () { return OC.imagePath(OCA.Onlyoffice.AppName, "btn-edit"); },
                actionHandler: function (fileName, context) { OCA.Onlyoffice.FileClick(fileName, context, attr); }
            });
        });
    }
};
OC.Plugins.register("OCA.Files.FileList", OCA.Onlyoffice.FileList);


Итак, мы молодцы — в контекстном меню файлов появилось действие Open in ONLYOFFICE и возможность создать новый файл: документ, таблицу или презентацию (создание файла реализовано на сервере как копирование в указанную папку с указанным именем заготовленного файла OOXML формата — docx, xlsx, pptx).

Дополнительная информация о форматах


Редакторы ONLYOFFICE работают со следующими форматами (но по-разному): DOCX, XLSX, PPTX, PPSX, TXT, CSV, ODT, ODS, ODP, DOC, XLS, PPT, PPS, EPUB, RTF, MHT, HTML, XPS, PDF, DJVU.

При выборе действия для ODT, ODS, ODP, DOC, XLS, PPT, PPS, EPUB, RTF, MHT, HTML файл сначала будет отправлен на конвертацию в соответствующий OOXML формат. Для DOCX, XLSX, PPTX, PPSX, TXT будет открываться новая вкладка с редактором, а для CSV, XPS, PDF, DJVU вкладка с редактором в режиме просмотра.

Теперь про Nextcloud


Как только мы сообщили миру о том, что работаем с ownCloud'ом мир сразу потребовал от нас работать с Nextcloud тоже. Мы сочли эти требования справедливыми, но слету начать работать и в этой системе не получилось.

Вот какие трудности возникли:

  1. Поехавшие иконки (понятное дело, поправить стили не проблема).
  2. В Nextcloud'е добавилась Content Security Policy (инлайн скрипт инициализации редактора потребовалось подписать).
  3. Новые требования к странице Settings.

Именно из-за третьего пункта мы некоторое время думали, что нам придется делать два отдельных приложения для родственных систем. Вот как это было — чтобы реализовать новый интерфейс в NextCloud, нужно было зарегистрировать наш класс настроек в описании приложения:

/appinfo/inxo.xml
<settings>
    <admin>OCA\Onlyoffice\Controller\SettingsController</admin>
</settings>


А затем в классе реализовать требуемый интерфейс ISettings:

/controller/settingscontroller.php
class SettingsController extends Controller implements ISettings {
    public function getForm() {
        return $this-index();
    }

    public function getSection() {
        return "server";
    }

    public function getPriority() {
        return 50;
    }
...


Но тут у нас образовалась небольшая проблемка. Натыкаясь на эту строчку, ownCloud падал, так как в его среде никакого интерфейса ISettings не существует:

class SettingsController extends Controller implements ISettings


Пришлось сделать всё по-хитрому: реализацию интерфейса ISettings сделать в отдельном классе, оставив формирование верстки для ownCloud и Nextcloud единым.

/appinfo/inxo.xml
<settings>
    <admin>OCA\Onlyoffice\AdminSettings</admin>
</settings>


/lib/adminsettings.php
class AdminSettings implements ISettings {
    public function getForm() {
        $app = new Application();
        $container = $app->getContainer();
        $response = $container->query("\OCA\Onlyoffice\Controller\SettingsController")->index();
        return $response;
    }

    public function getSection() {
        return "server";
    }

    public function getPriority() {
        return 50;
    }
}


Таким образом страница настроек для ownCloud подключается по старому алгоритму, а для Nexcloud — по новому. Кстати, были инициативные ребята, которые вывели fork от нашего приложения и допиливали до Nextcloud самостоятельно. На форумах писали, что это работает, и мы, естественно, заинтересовались, как там всё сделано. Но решения проблемы с настройками не нашли и сделали всё по-своему.

Что получилось?


Мы получили приложение, позволяющее работать с документами с помощью редакторов ONLYOFFICE в интерфейсе популярных ownCloud и NextCloud. Официально обе компании сотрудничают с Collabora, но, как известно, развернуть её удается не всем, а полноценного совместного редактирования там пока нет. Плюс ко всему, мы выбрали разные форматы в качестве основных, и если вы больше любите «иксовые», то ONLYOFFICE заточен именно под них. С помощью коннектора вы сможете подключить ownCloud или NextCloud и к бесплатной версии Community, и к Enterprise.

Подробные инструкции в нашей документации.

P.S. Если покопаться в документации, вы можете найти там также плагины для Confluence и Alfresco. Последний изначально писался не нами, но в порыве вдохновения мы недавно довели его до ума, вдруг вам пригодится? В ближайшее время также порадуем вас интересными интеграциями, undo в быстром совместном редактировании и еще кое-какими важными и хорошими новостями. Оставайтесь с нами!
-->


К сожалению, не доступен сервер mySQL