diff --git a/.gitmodules b/.gitmodules index 8ed023cd..1ba956e0 100644 --- a/.gitmodules +++ b/.gitmodules @@ -64,10 +64,6 @@ [submodule "web/documentserver-example/csharp/assets/document-formats"] path = web/documentserver-example/csharp/assets/document-formats url = https://github.com/ONLYOFFICE/document-formats -[submodule "web/documentserver-example/php-laravel/public/assets/document-formats"] - path = web/documentserver-example/php-laravel/public/assets/document-formats - url = https://github.com/ONLYOFFICE/document-formats - branch = master [submodule "web/documentserver-example/php-laravel/public/assets/document-templates"] path = web/documentserver-example/php-laravel/public/assets/document-templates url = https://github.com/ONLYOFFICE/document-templates diff --git a/CHANGELOG.md b/CHANGELOG.md index d2e0d6c9..bf445fdd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ - php-laravel: create, edit, and submit pdf forms - php-laravel: show forgotten files on a seperate page - php-laravel: fetch files +- php-laravel: integrate sdk - restore by url - refresh config - on uploading xml convert to supported type only diff --git a/web/documentserver-example/php-laravel/.env.example b/web/documentserver-example/php-laravel/.env.example index a9eb71f6..2c765ebc 100644 --- a/web/documentserver-example/php-laravel/.env.example +++ b/web/documentserver-example/php-laravel/.env.example @@ -1,3 +1,10 @@ +# PHP SDK ENV VARIABLES + +## COMMAND SERVICE +DOCS_INTEGRATION_SDK_COMMAND_SERVICE_URL=/command +DOCS_INTEGRATION_SDK_CONVERT_SERVICE_URL=/converter + + ## DOCUMENT STORAGE ENV VARIABLES DOCUMENT_STORAGE_PUBLIC_URL=http://localhost diff --git a/web/documentserver-example/php-laravel/app/Helpers/URL/FileURL.php b/web/documentserver-example/php-laravel/app/Helpers/URL/FileURL.php index cc85d1e6..4d55a1cc 100644 --- a/web/documentserver-example/php-laravel/app/Helpers/URL/FileURL.php +++ b/web/documentserver-example/php-laravel/app/Helpers/URL/FileURL.php @@ -18,15 +18,15 @@ namespace App\Helpers\URL; -use App\Services\StorageConfig; +use App\OnlyOffice\Managers\SettingsManager; class FileURL extends URL { public static function download(string $filename, string $address = ''): string { - $config = app(StorageConfig::class); + $settings = app(SettingsManager::class); - return static::build($config->get('url.private'), 'files/download', [ + return static::build($settings->getSetting('url.storage.private'), 'files/download', [ 'fileName' => $filename, 'userAddress' => $address, ]); @@ -34,9 +34,9 @@ class FileURL extends URL public static function changes(string $filename, string $address, int $version): string { - $config = app(StorageConfig::class); + $settings = app(SettingsManager::class); - return static::build($config->get('url.private'), 'files/versions/changes', [ + return static::build($settings->getSetting('url.storage.private'), 'files/versions/changes', [ 'filename' => $filename, 'userAddress' => $address, 'version' => $version, @@ -45,9 +45,9 @@ class FileURL extends URL public static function previous(string $filename, string $address, int $version): string { - $config = app(StorageConfig::class); + $settings = app(SettingsManager::class); - return static::build($config->get('url.private'), 'files/versions/previous', [ + return static::build($settings->getSetting('url.storage.private'), 'files/versions/previous', [ 'filename' => $filename, 'userAddress' => $address, 'version' => $version, @@ -56,9 +56,9 @@ class FileURL extends URL public static function history(string $filename, string $address): string { - $config = app(StorageConfig::class); + $settings = app(SettingsManager::class); - return static::build($config->get('url.private'), 'files/download', [ + return static::build($settings->getSetting('url.storage.private'), 'files/download', [ 'fileName' => $filename, 'userAddress' => $address, ]); @@ -66,9 +66,9 @@ class FileURL extends URL public static function create(string $extension, string $user): string { - $config = app(StorageConfig::class); + $settings = app(SettingsManager::class); - return static::build($config->get('url.public'), 'editor', [ + return static::build($settings->getSetting('url.storage.public'), 'editor', [ 'fileExt' => $extension, 'user' => $user, ]); @@ -76,9 +76,9 @@ class FileURL extends URL public static function callback(string $filename, string $user): string { - $config = app(StorageConfig::class); + $settings = app(SettingsManager::class); - return static::build($config->get('url.private'), 'editor/track', [ + return static::build($settings->getSetting('url.storage.private'), 'editor/track', [ 'fileName' => $filename, 'userAddress' => $user, ]); diff --git a/web/documentserver-example/php-laravel/app/Helpers/URL/TemplateURL.php b/web/documentserver-example/php-laravel/app/Helpers/URL/TemplateURL.php index aff2716f..300f94d8 100644 --- a/web/documentserver-example/php-laravel/app/Helpers/URL/TemplateURL.php +++ b/web/documentserver-example/php-laravel/app/Helpers/URL/TemplateURL.php @@ -18,13 +18,13 @@ namespace App\Helpers\URL; -use App\Services\StorageConfig; +use App\OnlyOffice\Managers\SettingsManager; class TemplateURL extends URL { public static function image(string $type) { - $config = app(StorageConfig::class); + $settings = app(SettingsManager::class); $name = 'file_docx.svg'; $name = match ($type) { @@ -34,6 +34,6 @@ class TemplateURL extends URL default => 'file_docx.svg', }; - return static::build($config->get('url.public'), "/images/$name"); + return static::build($settings->getSetting('url.storage.public'), "/images/$name"); } } diff --git a/web/documentserver-example/php-laravel/app/Http/Controllers/API/Files/ReferenceController.php b/web/documentserver-example/php-laravel/app/Http/Controllers/API/Files/ReferenceController.php index d0fe8d4e..8cc73a34 100644 --- a/web/documentserver-example/php-laravel/app/Http/Controllers/API/Files/ReferenceController.php +++ b/web/documentserver-example/php-laravel/app/Http/Controllers/API/Files/ReferenceController.php @@ -5,9 +5,8 @@ namespace App\Http\Controllers\API\Files; use App\Helpers\Path\PathInfo; use App\Helpers\URL\URL; use App\Http\Controllers\Controller; -use App\Services\JWT; -use App\Services\ServerConfig; -use App\Services\StorageConfig; +use App\OnlyOffice\Managers\JWTManager; +use App\OnlyOffice\Managers\SettingsManager; use App\UseCases\Document\Find\FindDocumentQuery; use App\UseCases\Document\Find\FindDocumentQueryHandler; use Exception; @@ -17,10 +16,10 @@ use Illuminate\Support\Str; class ReferenceController extends Controller { - public function get(Request $request, StorageConfig $storageConfig, ServerConfig $serverConfig, JWT $jwt) + public function get(Request $request, SettingsManager $settings, JWTManager $jwt) { - $storagePrivateUrl = $storageConfig->get('url.private'); - $storagePublicUrl = $storageConfig->get('url.public'); + $storagePrivateUrl = $settings->getSetting('url.storage.private'); + $storagePublicUrl = $settings->getSetting('url.storage.public'); $referenceData = $request->input('referenceData'); $link = $request->input('link'); $path = $request->input('path'); @@ -94,8 +93,8 @@ class ReferenceController extends Controller 'link' => "$storagePublicUrl/editor?fileID=$filename", ]; - if ($serverConfig->get('jwt.enabled')) { - $data['token'] = $jwt->encode($data); + if ($settings->getSetting('jwt.enabled')) { + $data['token'] = $jwt->encode($data, $settings->getSetting('jwt.secret')); } return response()->json($data); diff --git a/web/documentserver-example/php-laravel/app/Http/Controllers/API/FormatController.php b/web/documentserver-example/php-laravel/app/Http/Controllers/API/FormatController.php index 9e5a4766..cb4c31fe 100644 --- a/web/documentserver-example/php-laravel/app/Http/Controllers/API/FormatController.php +++ b/web/documentserver-example/php-laravel/app/Http/Controllers/API/FormatController.php @@ -19,14 +19,14 @@ namespace App\Http\Controllers\API; use App\Http\Controllers\Controller; -use App\Repositories\FormatRepository; +use App\OnlyOffice\Managers\FormatManager; class FormatController extends Controller { - public function index(FormatRepository $formats) + public function index(FormatManager $formats) { return response()->json([ - 'formats' => $formats->all(), + 'formats' => $formats->getFormatsList(), ]); } } diff --git a/web/documentserver-example/php-laravel/app/Http/Controllers/EditorController.php b/web/documentserver-example/php-laravel/app/Http/Controllers/EditorController.php index 0acc2b10..2cf8e547 100644 --- a/web/documentserver-example/php-laravel/app/Http/Controllers/EditorController.php +++ b/web/documentserver-example/php-laravel/app/Http/Controllers/EditorController.php @@ -18,32 +18,20 @@ namespace App\Http\Controllers; -use App\Helpers\Path\Path; use App\Helpers\Path\PathInfo; -use App\Helpers\URL\FileURL; -use App\Helpers\URL\TemplateURL; use App\Helpers\URL\URL; -use App\Services\JWT; -use App\Services\ServerConfig; -use App\Services\StorageConfig; +use App\OnlyOffice\Managers\DocumentManager; +use App\OnlyOffice\Managers\JWTManager; +use App\OnlyOffice\Managers\SettingsManager; +use App\OnlyOffice\Services\CallbackService; use App\UseCases\Common\Http\DownloadFileCommand; use App\UseCases\Common\Http\DownloadFileRequest; -use App\UseCases\Docs\Command\ForceSaveCommad; -use App\UseCases\Docs\Command\ForceSaveRequest; -use App\UseCases\Docs\Conversion\ConvertCommand; -use App\UseCases\Docs\Conversion\ConvertRequest; use App\UseCases\Document\Create\CreateDocumentCommand; use App\UseCases\Document\Create\CreateDocumentFromTemplateCommand; use App\UseCases\Document\Create\CreateDocumentFromTemplateRequest; use App\UseCases\Document\Create\CreateDocumentRequest; use App\UseCases\Document\Find\FindDocumentQuery; use App\UseCases\Document\Find\FindDocumentQueryHandler; -use App\UseCases\Document\Save\ForceSaveDocumentCommand; -use App\UseCases\Document\Save\ForceSaveDocumentRequest; -use App\UseCases\Document\Save\SaveDocumentCommand; -use App\UseCases\Document\Save\SaveDocumentFormCommand; -use App\UseCases\Document\Save\SaveDocumentFormRequest; -use App\UseCases\Document\Save\SaveDocumentRequest; use App\UseCases\Editor\Create\CreateConfigCommand; use App\UseCases\Editor\Create\CreateConfigRequest; use App\UseCases\File\Find\FileExistsQuery; @@ -55,16 +43,16 @@ use App\UseCases\User\Find\FindUserQueryHandler; use Exception; use Illuminate\Http\Request; use Illuminate\Support\Facades\Log; -use Illuminate\Support\Str; +use Onlyoffice\DocsIntegrationSdk\Models\Callback; +use Onlyoffice\DocsIntegrationSdk\Models\CallbackDocStatus; +use Onlyoffice\DocsIntegrationSdk\Models\CallbackForceSaveType; +use Onlyoffice\DocsIntegrationSdk\Models\History; class EditorController extends Controller { - public function __construct( - private StorageConfig $storageConfig, - private ServerConfig $serverConfig, - ) {} + public function __construct(private SettingsManager $settings) {} - public function index(Request $request, JWT $jwt) + public function index(Request $request, JWTManager $jwt) { $request->validate([ 'fileUrl' => 'required_without_all:fileID,fileExt|string', @@ -86,8 +74,8 @@ class EditorController extends Controller $lang = $request->cookie('ulang', 'en'); $fileExt = $request->input('fileExt'); $withSample = $request->has('sample') && $request->sample === 'true'; - $storagePublicUrl = $this->storageConfig->get('url.public'); - $storagePrivateUrl = $this->storageConfig->get('url.private'); + $storagePublicUrl = $this->settings->getSetting('url.storage.public'); + $storagePrivateUrl = $this->settings->getSetting('url.storage.private'); $user = app(FindUserQueryHandler::class) ->__invoke(new FindUserQuery($userId)); @@ -142,7 +130,7 @@ class EditorController extends Controller $file = app(FindDocumentQueryHandler::class) ->__invoke(new FindDocumentQuery($filename, $request->ip())); - if (! $file['format']->type) { + if (! $file['format']->getType()) { $message = 'The format '.$file['format']->extension().' has undefined format.'; Log::error($message); @@ -152,10 +140,13 @@ class EditorController extends Controller ]); } - $downloadUrl = FileURL::download($filename, $request->ip()); - $templatesImageUrl = TemplateURL::image($file['format']->type->value); - $createUrl = FileURL::create($file['format']->extension(), $user['id']); - $callbackUrl = FileURL::callback($filename, $request->ip()); + $file['user'] = $userId; + $file['address'] = $request->ip(); + $fileId = $file['key']; + + $documentManager = new DocumentManager($file); + + $downloadUrl = $documentManager->getFileUrl($fileId); $imagesUrl = "$storagePublicUrl/images/"; $mode = $request->action ?? 'edit'; @@ -172,10 +163,10 @@ class EditorController extends Controller lang: $lang, userAddress: $request->ip(), serverAddress: $storagePublicUrl, - createUrl: $createUrl, - templatesImageUrl: $templatesImageUrl, + createUrl: $documentManager->getCreateUrl($fileId), + templatesImageUrl: $documentManager->getTemplateImageUrl($fileId), actionLink: $actionLink, - callbackUrl: $callbackUrl, + callbackUrl: $documentManager->getCallbackUrl($fileId), imagesUrl: $imagesUrl, directUrl: $directUrlEnabled ? $downloadUrl : '', )); @@ -227,14 +218,15 @@ class EditorController extends Controller } // check if the secret key to generate token exists - if ($this->serverConfig->get('jwt.enabled')) { - $config['token'] = $jwt->encode($config); // encode config into the token + if ($this->settings->getSetting('jwt.enabled')) { + // encode config into the token + $config['token'] = $jwt->encode($config, $this->settings->getSetting('jwt.secret')); // encode the dataInsertImage object into the token - $dataInsertImage['token'] = $jwt->encode($dataInsertImage); + $dataInsertImage['token'] = $jwt->encode($dataInsertImage, $this->settings->getSetting('jwt.secret')); // encode the dataDocument object into the token - $dataDocument['token'] = $jwt->encode($dataDocument); + $dataDocument['token'] = $jwt->encode($dataDocument, $this->settings->getSetting('jwt.secret')); // encode the dataSpreadsheet object into the token - $dataSpreadsheet['token'] = $jwt->encode($dataSpreadsheet); + $dataSpreadsheet['token'] = $jwt->encode($dataSpreadsheet, $this->settings->getSetting('jwt.secret')); } $historyLayout = ''; @@ -267,8 +259,8 @@ class EditorController extends Controller $editorConfig = [ 'fileName' => $file['filename'], - 'docType' => $file['format']->type, - 'apiUrl' => $this->serverConfig->get('url.api'), + 'docType' => $file['format']->getType(), + 'apiUrl' => $this->settings->getSetting('url.api'), 'dataInsertImage' => mb_strimwidth( json_encode($dataInsertImage), 1, @@ -308,152 +300,36 @@ class EditorController extends Controller } $data = $request->input('payload'); - $status = $data['status']; + $data['filename'] = $filename; + $data['address'] = $address; + $actions = array_key_exists('actions', $data) ? $data['actions'] : []; + $changesUrl = array_key_exists('changesurl', $data) ? $data['changesurl'] : ''; + $formsDataUrl = array_key_exists('formsdataurl', $data) ? $data['formsdataurl'] : ''; + $fileType = array_key_exists('filetype', $data) ? $data['filetype'] : ''; + $forceSaveType = array_key_exists('forcesavetype', $data) ? new CallbackForceSaveType($data['forcesavetype']) : null; + $history = array_key_exists('history', $data) && $data['history'] + ? new History($data['history']['serverVersion'], $data['history']['changes']) + : null; + $users = array_key_exists('users', $data) ? $data['users'] : []; + $url = array_key_exists('url', $data) ? $data['url'] : ''; - switch ($status) { - case 1: - if ($data['actions'] && $data['actions'][0]['type'] == 0) { - $user = $data['actions'][0]['userid']; - if (array_search($user, $data['users']) === false) { - app(ForceSaveCommad::class) - ->__invoke(new ForceSaveRequest(key: $data['key'])); - } - } - break; - case 2: - case 3: - $url = $data['url']; - $key = $data['key']; - $user = $data['users'][0]; - $changes = null; + $callback = new Callback( + $actions, + $changesUrl, + $fileType, + $forceSaveType, + $history, + $data['key'], + new CallbackDocStatus($data['status']), + $url, + $users, + '', + $formsDataUrl + ); - $url = Str::replace(URL::origin($url), $this->serverConfig->get('url.private'), $url); + $callbackService = new CallbackService($this->settings, app(JWTManager::class), $data); + $result = $callbackService->processCallback($callback, $filename); - $fileExtension = PathInfo::extension($filename); - $downloadExtension = PathInfo::extension($url); - - if ($fileExtension !== $downloadExtension) { - $result = app(ConvertCommand::class) - ->__invoke(new ConvertRequest( - filename: $filename, - fileType: $downloadExtension, - outputType: $fileExtension, - url: $url, - password: null, - user: $user, - userAddress: $address, - )); - - if (array_key_exists('step', $result) || array_key_exists('error', $result)) { - $filename = PathInfo::filename($filename).".$downloadExtension"; - } else { - $url = $result['fileUrl']; - } - } - - $content = app(DownloadFileCommand::class) - ->__invoke(new DownloadFileRequest(url: $url))['content']; - - if (array_key_exists('changesurl', $data)) { - $changesUrl = $data['changesurl']; - $changesUrl = Str::replace(URL::origin($changesUrl), $this->serverConfig->get('url.private'), $changesUrl); - - $changes = app(DownloadFileCommand::class) - ->__invoke(new DownloadFileRequest(url: $changesUrl))['content']; - } - - $history = array_key_exists('history', $data) ? $data['history']['changes'] : null; - $serverVersion = array_key_exists('history', $data) ? $data['history']['serverVersion'] : null; - $user = $data['users'][0]; - - app(SaveDocumentCommand::class)->__invoke( - new SaveDocumentRequest( - Path::join($address, $filename), - $fileExtension, - $key, - $content, - $user, - $serverVersion, - $history, - $changes, - ) - ); - - break; - case 6: - case 7: - $isSubmitForm = $data['forcesavetype'] === 3; - - if ($isSubmitForm && ! array_key_exists('formsdataurl', $data)) { - abort(500, 'Document editing service did not return formsDataUrl'); - } - - $url = $data['url']; - $key = $data['key']; - $user = $data['users'][0]; - - $url = Str::replace(URL::origin($url), $this->serverConfig->get('url.private'), $url); - - $fileExtension = PathInfo::extension($filename); - $downloadExtension = PathInfo::extension($url); - - if ($fileExtension !== $downloadExtension) { - $result = app(ConvertCommand::class) - ->__invoke(new ConvertRequest( - filename: $filename, - fileType: $downloadExtension, - outputType: $fileExtension, - url: $url, - password: null, - user: $user, - userAddress: $address, - )); - - if (array_key_exists('step', $result) || array_key_exists('error', $result)) { - $filename = PathInfo::filename($filename).".$downloadExtension"; - } else { - $url = $result['fileUrl']; - } - } - - $content = app(DownloadFileCommand::class) - ->__invoke(new DownloadFileRequest(url: $url))['content']; - - if ($isSubmitForm) { - $formsDataUrl = $data['formsdataurl']; - $formsDataUrl = Str::replace( - URL::origin($formsDataUrl), - $this->serverConfig->get('url.private'), - $formsDataUrl - ); - - $formData = app(DownloadFileCommand::class) - ->__invoke(new DownloadFileRequest(url: $formsDataUrl))['content']; - - app(SaveDocumentFormCommand::class) - ->__invoke(new SaveDocumentFormRequest( - filename: $filename, - userDirectory: $address, - user: $user, - formContent: $content, - formDataContent: $formData, - )); - } else { - app(ForceSaveDocumentCommand::class) - ->__invoke( - new ForceSaveDocumentRequest( - filename: $filename, - userDirectory: $address, - content: $content - ) - ); - } - - break; - } - - return response()->json([ - 'error' => 0, - ]); + return response()->json($result); } } diff --git a/web/documentserver-example/php-laravel/app/Http/Controllers/FileController.php b/web/documentserver-example/php-laravel/app/Http/Controllers/FileController.php index 8191c020..05e0e092 100644 --- a/web/documentserver-example/php-laravel/app/Http/Controllers/FileController.php +++ b/web/documentserver-example/php-laravel/app/Http/Controllers/FileController.php @@ -22,10 +22,9 @@ use App\Helpers\Path\Path; use App\Helpers\Path\PathInfo; use App\Helpers\URL\FileURL; use App\Helpers\URL\URL; -use App\Repositories\FormatRepository; -use App\Services\JWT; -use App\Services\ServerConfig; -use App\Services\StorageConfig; +use App\OnlyOffice\Managers\FormatManager; +use App\OnlyOffice\Managers\JWTManager; +use App\OnlyOffice\Managers\SettingsManager; use App\UseCases\Common\Http\DownloadFileCommand; use App\UseCases\Common\Http\DownloadFileRequest; use App\UseCases\Docs\Command\UpdateMetaCommand; @@ -54,9 +53,8 @@ use Illuminate\Support\Str; class FileController extends Controller { public function __construct( - private ServerConfig $serverConfig, - private StorageConfig $storageConfig, - private FormatRepository $formatRepository, + private SettingsManager $settings, + private FormatManager $formatManager, ) {} public function index(Request $request) @@ -130,7 +128,7 @@ class FileController extends Controller $user = $request->input('user', ''); - $url = Str::replace(URL::origin($request->url), $this->serverConfig->get('url.private'), $request->url); + $url = Str::replace(URL::origin($request->url), $this->settings->getSetting('url.server.private'), $request->url); $downloadedFile = app(DownloadFileCommand::class) ->__invoke(new DownloadFileRequest(url: $url)); @@ -188,13 +186,13 @@ class FileController extends Controller ], 500); } - if (empty($this->formatRepository->find($result['fileType'])->actions)) { + if (empty($this->formatManager->find($result['fileType'])->getActions())) { return response() ->json([ 'step' => 100, 'filename' => str_replace( - $this->serverConfig->get('url.private'), - $this->serverConfig->get('url.public'), + $this->settings->getSetting('url.server.private'), + $this->settings->getSetting('url.server.public'), $result['fileUrl'] ), 'error' => 'FileTypeIsNotSupported', @@ -317,7 +315,7 @@ class FileController extends Controller return response(status: 201); } - public function config(Request $request, JWT $jwt) + public function config(Request $request, JWTManager $jwt) { try { $request->validate([ @@ -361,8 +359,8 @@ class FileController extends Controller ], ]; - if ($this->serverConfig->get('jwt.enabled')) { - $config['token'] = $jwt->encode($config); + if ($this->settings->getSetting('jwt.enabled')) { + $config['token'] = $jwt->encode($config, $this->settings->getSetting('jwt.secret')); } return response() diff --git a/web/documentserver-example/php-laravel/app/Http/Controllers/IndexController.php b/web/documentserver-example/php-laravel/app/Http/Controllers/IndexController.php index ffed1e38..35371bba 100644 --- a/web/documentserver-example/php-laravel/app/Http/Controllers/IndexController.php +++ b/web/documentserver-example/php-laravel/app/Http/Controllers/IndexController.php @@ -19,8 +19,7 @@ namespace App\Http\Controllers; use App\Helpers\URL\URL; -use App\Services\ServerConfig; -use App\Services\StorageConfig; +use App\OnlyOffice\Managers\SettingsManager; use App\UseCases\Document\Find\FindAllDocumentsQuery; use App\UseCases\Document\Find\FindAllDocumentsQueryHandler; use App\UseCases\Language\Find\FindAllLanguagesQueryHandler; @@ -31,12 +30,12 @@ use Illuminate\Support\Str; class IndexController extends Controller { - public function index(Request $request, ServerConfig $serverConfig, StorageConfig $storageConfig) + public function index(Request $request, SettingsManager $settings) { $directUrlEnabled = $request->has('directUrl') && $request->directUrl === 'true'; $directUrlArg = 'directUrl='.($directUrlEnabled ? 'true' : 'false'); - $preloaderUrl = $serverConfig->get('url.preloader'); + $preloaderUrl = $settings->getSetting('url.preloader'); $files = app(FindAllDocumentsQueryHandler::class) ->__invoke(new FindAllDocumentsQuery($request->ip())); @@ -50,7 +49,7 @@ class IndexController extends Controller foreach ($files as &$file) { $url = route('files.download', ['fileName' => urlencode($file['filename']), 'dmode' => true]); - $file['url'] = Str::replace(URL::origin($url), $storageConfig->get('url.public'), $url); + $file['url'] = Str::replace(URL::origin($url), $settings->getSetting('url.storage.public'), $url); } return view('index', [ diff --git a/web/documentserver-example/php-laravel/app/Http/Middleware/CheckAndDecodeJWTPayload.php b/web/documentserver-example/php-laravel/app/Http/Middleware/CheckAndDecodeJWTPayload.php index f57619c9..4795e0da 100644 --- a/web/documentserver-example/php-laravel/app/Http/Middleware/CheckAndDecodeJWTPayload.php +++ b/web/documentserver-example/php-laravel/app/Http/Middleware/CheckAndDecodeJWTPayload.php @@ -2,8 +2,8 @@ namespace App\Http\Middleware; -use App\Services\JWT; -use App\Services\ServerConfig; +use App\OnlyOffice\Managers\JWTManager; +use App\OnlyOffice\Managers\SettingsManager; use Closure; use Illuminate\Http\Request; use Symfony\Component\HttpFoundation\Response; @@ -17,18 +17,17 @@ class CheckAndDecodeJWTPayload */ public function handle(Request $request, Closure $next): Response { - $config = app(ServerConfig::class); - $jwt = app(JWT::class); + $jwt = app(JWTManager::class); + $settings = app(SettingsManager::class); $payload = null; $embeded = $request->has('dmode'); - if ($config->get('jwt.enabled') && $embeded == null && $config->get('jwt.use_for_request')) { + if ($settings->getSetting('jwt.enabled') && $embeded == null && $settings->getSetting('jwt.use_for_request')) { if ($request->token) { - $payload = $jwt->decode($request->token); + $payload = $jwt->decode($request->token, $settings->getSetting('jwt.secret')); $payload = json_decode(json_encode($payload), true); - } elseif ($request->hasHeader($config->get('jwt.header'))) { - $payload = $jwt->decode($request->bearerToken()); - $payload = json_decode($payload); + } elseif ($request->hasHeader($settings->getSetting('jwt.header'))) { + $payload = $jwt->decode($request->bearerToken(), $settings->getSetting('jwt.secret')); } else { abort(499, 'Expected JWT token'); } diff --git a/web/documentserver-example/php-laravel/app/Http/Middleware/EnsureJWTTokenIsPresent.php b/web/documentserver-example/php-laravel/app/Http/Middleware/EnsureJWTTokenIsPresent.php index 2e02c57e..2091777c 100644 --- a/web/documentserver-example/php-laravel/app/Http/Middleware/EnsureJWTTokenIsPresent.php +++ b/web/documentserver-example/php-laravel/app/Http/Middleware/EnsureJWTTokenIsPresent.php @@ -2,8 +2,8 @@ namespace App\Http\Middleware; -use App\Services\JWT; -use App\Services\ServerConfig; +use App\OnlyOffice\Managers\JWTManager; +use App\OnlyOffice\Managers\SettingsManager; use Closure; use Illuminate\Http\Request; use Symfony\Component\HttpFoundation\Response; @@ -17,13 +17,13 @@ class EnsureJWTTokenIsPresent */ public function handle(Request $request, Closure $next): Response { - $config = app(ServerConfig::class); - $jwt = app(JWT::class); + $jwt = app(JWTManager::class); + $settings = app(SettingsManager::class); $embeded = $request->has('dmode'); - if ($config->get('jwt.enabled') && $embeded == null && $config->get('jwt.use_for_request')) { - if ($request->hasHeader($config->get('jwt.header'))) { - $token = $jwt->decode($request->bearerToken()); + if ($settings->getSetting('jwt.enabled') && $embeded == null && $settings->getSetting('jwt.use_for_request')) { + if ($request->hasHeader($settings->getSetting('jwt.header'))) { + $token = $jwt->decode($request->bearerToken(), $settings->getSetting('jwt.secret')); if (empty($token)) { abort(498, 'Invalid JWT signature'); diff --git a/web/documentserver-example/php-laravel/app/Models/Document.php b/web/documentserver-example/php-laravel/app/Models/Document.php index 24bef6d8..4eea781b 100644 --- a/web/documentserver-example/php-laravel/app/Models/Document.php +++ b/web/documentserver-example/php-laravel/app/Models/Document.php @@ -18,6 +18,8 @@ namespace App\Models; +use App\OnlyOffice\Models\Format; + class Document { public function __construct( diff --git a/web/documentserver-example/php-laravel/app/Models/Editor/Editor.php b/web/documentserver-example/php-laravel/app/Models/Editor/Editor.php index 6c972ddb..0d6749b9 100644 --- a/web/documentserver-example/php-laravel/app/Models/Editor/Editor.php +++ b/web/documentserver-example/php-laravel/app/Models/Editor/Editor.php @@ -42,7 +42,7 @@ class Editor 'url' => $this->document->url, 'directUrl' => $this->config->directUrl, ], - 'documentType' => $this->document->format->type, + 'documentType' => $this->document->format->getType(), 'editorConfig' => $this->buildEditorConfig(), 'type' => $this->config->type, ]; diff --git a/web/documentserver-example/php-laravel/app/Models/Editor/EditorPermissions.php b/web/documentserver-example/php-laravel/app/Models/Editor/EditorPermissions.php index b56aa1f8..af7f2003 100644 --- a/web/documentserver-example/php-laravel/app/Models/Editor/EditorPermissions.php +++ b/web/documentserver-example/php-laravel/app/Models/Editor/EditorPermissions.php @@ -18,8 +18,8 @@ namespace App\Models\Editor; -use App\Models\Format; use App\Models\User; +use App\OnlyOffice\Models\Format; class EditorPermissions { @@ -101,12 +101,12 @@ class EditorPermissions private function editable(): bool { - return $this->action === 'edit' && $this->format->editable(); + return $this->action === 'edit' && $this->format->isEditable(); } private function fillable(): bool { - return (($this->action === 'edit' && ! $this->format->editable()) - || $this->action === 'fillForms') && $this->format->fillable(); + return (($this->action === 'edit' && ! $this->format->isEditable()) + || $this->action === 'fillForms') && $this->format->isFillable(); } } diff --git a/web/documentserver-example/php-laravel/app/OnlyOffice/Managers/DocumentManager.php b/web/documentserver-example/php-laravel/app/OnlyOffice/Managers/DocumentManager.php new file mode 100644 index 00000000..482dca2c --- /dev/null +++ b/web/documentserver-example/php-laravel/app/OnlyOffice/Managers/DocumentManager.php @@ -0,0 +1,81 @@ +file = $file; + } + + public function getDocumentKey(string $fileId, bool $embedded) + { + return $this->file['key']; + } + + public function getDocumentName(string $fileId) + { + return $this->file['filename']; + } + + public static function getLangMapping() + { + return null; + } + + public function getFileUrl(string $fileId) + { + return FileURL::download($this->file['filename'], $this->file['address']); + } + + public function getCallbackUrl(string $fileId) + { + return FileURL::callback($this->file['filename'], $this->file['address']); + } + + public function getTemplateImageUrl(string $fileId) + { + return TemplateURL::image($this->file['format']->getType()); + } + + public function getGobackUrl(string $fileId) + { + return $this->file['goback'] !== null ? $this->file['goback'] : ''; + } + + public function getCreateUrl(string $fileId) + { + return FileURL::create($this->file['format']->extension(), $this->file['user']); + } + + public function getFile(): array + { + return $this->file; + } +} diff --git a/web/documentserver-example/php-laravel/app/OnlyOffice/Managers/FormatManager.php b/web/documentserver-example/php-laravel/app/OnlyOffice/Managers/FormatManager.php new file mode 100644 index 00000000..2968fff2 --- /dev/null +++ b/web/documentserver-example/php-laravel/app/OnlyOffice/Managers/FormatManager.php @@ -0,0 +1,59 @@ +createCustomList(); + } + + private function createCustomList() + { + $newFormats = []; + + foreach ($this->formatsList as $format) { + $newFormats[] = new Format( + $format->getName(), + $format->getType(), + $format->getActions(), + $format->getConvert(), + $format->getMimes(), + ); + } + + $this->formatsList = $newFormats; + } + + public function find(string $extension): ?Format + { + foreach ($this->formatsList as $format) { + if ($format->extension() === $extension) { + return $format; + } + } + + return null; + } +} diff --git a/web/documentserver-example/php-laravel/app/Services/Docs/Command/ForgottenFileRequest.php b/web/documentserver-example/php-laravel/app/OnlyOffice/Managers/JWTManager.php similarity index 50% rename from web/documentserver-example/php-laravel/app/Services/Docs/Command/ForgottenFileRequest.php rename to web/documentserver-example/php-laravel/app/OnlyOffice/Managers/JWTManager.php index e9a2f2a8..3ac88e06 100644 --- a/web/documentserver-example/php-laravel/app/Services/Docs/Command/ForgottenFileRequest.php +++ b/web/documentserver-example/php-laravel/app/OnlyOffice/Managers/JWTManager.php @@ -16,22 +16,28 @@ * limitations under the License. */ -namespace App\Services\Docs\Command; +namespace App\OnlyOffice\Managers; -class ForgottenFileRequest extends CommandRequest +use Firebase\JWT\JWT; +use Firebase\JWT\Key; +use Onlyoffice\DocsIntegrationSdk\Manager\Security\JwtManager as OnlyOfficeJWTManager; + +class JWTManager extends OnlyOfficeJWTManager { - public function get(string $key): array + public function __construct(SettingsManager $settings) { - $content = [ - 'c' => 'getForgotten', - 'key' => $key, - ]; + parent::__construct($settings); + } - $result = $this->send($content, $key); + public function encode($payload, $key, $algorithm = 'HS256') + { + return JWT::encode($payload, $key, $algorithm); + } - return [ - 'key' => $result['key'], - 'url' => $result['url'], - ]; + public function decode($token, $key, $algorithm = 'HS256') + { + $payload = JWT::decode($token, new Key($key, $algorithm)); + + return $payload; } } diff --git a/web/documentserver-example/php-laravel/app/Services/ServerConfig.php b/web/documentserver-example/php-laravel/app/OnlyOffice/Managers/SettingsManager.php similarity index 55% rename from web/documentserver-example/php-laravel/app/Services/ServerConfig.php rename to web/documentserver-example/php-laravel/app/OnlyOffice/Managers/SettingsManager.php index a127a8cc..e0e0ca92 100644 --- a/web/documentserver-example/php-laravel/app/Services/ServerConfig.php +++ b/web/documentserver-example/php-laravel/app/OnlyOffice/Managers/SettingsManager.php @@ -16,12 +16,19 @@ * limitations under the License. */ -namespace App\Services; +namespace App\OnlyOffice\Managers; -class ServerConfig extends Config +use Exception; +use Onlyoffice\DocsIntegrationSdk\Manager\Settings\SettingsManager as OnlyOfficeSettingsManager; + +class SettingsManager extends OnlyOfficeSettingsManager { + private array $config; + public function __construct() { + parent::__construct(); + $publicServerUrl = rtrim(env('DOCUMENT_SERVER_PUBLIC_URL', 'http://documentserver'), '/'); $privateServerUrl = rtrim(env('DOCUMENT_SERVER_PRIVATE_URL', $publicServerUrl), '/'); $apiUrl = $publicServerUrl.'/'.env('DOCUMENT_SERVER_API_PATH', 'web-apps/apps/api/documents/api.js'); @@ -30,8 +37,14 @@ class ServerConfig extends Config $commandUrl = $privateServerUrl.'/'.env('DOCUMENT_SERVER_COMMAND_PATH', 'command'); $jwtSecret = env('DOCUMENT_SERVER_JWT_SECRET', 'secret'); $jwtUseForRequest = env('DOCUMENT_SERVER_JWT_USE_FOR_REQUEST', true); + $publicStorageUrl = rtrim(env('DOCUMENT_STORAGE_PUBLIC_URL', request()->schemeAndHttpHost()), '/'); + $privateStorageUrl = rtrim(env('DOCUMENT_STORAGE_PRIVATE_URL', $publicStorageUrl), '/'); $this->config = [ + 'documentServerInternalUrl' => $privateServerUrl, + 'jwtKey' => $jwtSecret, + 'jwtHeader' => env('DOCUMENT_SERVER_JWT_HEADER', 'Authorization'), + 'jwtPrefix' => env('DOCUMENT_SERVER_JWT_HEADER', 'Bearer '), 'conversion' => [ 'timeout' => env('DOCUMENT_SERVER_CONVERSION_TIMEOUT', 120 * 1000), 'url' => $conversionUrl, @@ -47,11 +60,48 @@ class ServerConfig extends Config ], 'url' => [ 'api' => $apiUrl, - 'public' => $publicServerUrl, - 'private' => $privateServerUrl, 'preloader' => $preloaderUrl, 'command' => $commandUrl, + 'server' => [ + 'public' => $publicServerUrl, + 'private' => $privateServerUrl, + ], + 'storage' => [ + 'private' => $privateStorageUrl, + 'public' => $publicStorageUrl, + ], + ], + 'file' => [ + 'max_size' => env('DOCUMENT_STORAGE_MAXIMUM_FILE_SIZE', 5 * 1024 * 1024), ], ]; } + + public function getServerUrl() + { + return $this->get('url.server.public'); + } + + public function getSetting($settingName) + { + return $this->get($settingName); + } + + public function setSetting($settingName, $value, $createSetting = false) {} + + private function get(string $key, mixed $default = null): mixed + { + $keys = explode('.', $key); + $result = $this->config; + + try { + foreach ($keys as $key) { + $result = $result[$key]; + } + } catch (Exception $e) { + $result = $default; + } + + return $result; + } } diff --git a/web/documentserver-example/php-laravel/app/OnlyOffice/Miscellaneous/CommandRequest.php b/web/documentserver-example/php-laravel/app/OnlyOffice/Miscellaneous/CommandRequest.php new file mode 100644 index 00000000..7d77d971 --- /dev/null +++ b/web/documentserver-example/php-laravel/app/OnlyOffice/Miscellaneous/CommandRequest.php @@ -0,0 +1,90 @@ + 'forcesave', + 'key' => $key, + ]; + + $result = $requestService->commandRequest('forcesave', $data); + + return $result; + } + + public static function deleteForgotten(string $key) + { + $requestService = app(RequestService::class); + + $data = [ + 'c' => 'deleteForgotten', + 'key' => $key, + ]; + + $result = $requestService->commandRequest('deleteForgotten', $data); + + return $result; + } + + public static function getForgotten(string $key) + { + $requestService = app(RequestService::class); + + $data = [ + 'c' => 'getForgotten', + 'key' => $key, + ]; + + $result = $requestService->commandRequest('getForgotten', $data); + + return $result; + } + + public static function getForgottenList() + { + $requestService = app(RequestService::class); + + $result = $requestService->commandRequest('getForgottenList'); + + return $result; + } + + public static function updateMeta(string $key, array $meta) + { + $requestService = app(RequestService::class); + + $data = [ + 'c' => 'meta', + 'key' => $key, + 'meta' => $meta, + ]; + + $result = $requestService->commandRequest('meta', $data); + + return $result; + } +} diff --git a/web/documentserver-example/php-laravel/app/OnlyOffice/Miscellaneous/ConvertRequest.php b/web/documentserver-example/php-laravel/app/OnlyOffice/Miscellaneous/ConvertRequest.php new file mode 100644 index 00000000..47115e99 --- /dev/null +++ b/web/documentserver-example/php-laravel/app/OnlyOffice/Miscellaneous/ConvertRequest.php @@ -0,0 +1,53 @@ +sendRequestToConvertService( + $data['url'], + $data['filetype'], + $data['outputtype'], + $data['key'], + false, + $data['lang'], + ); + + if (property_exists($result, 'Error')) { + throw new ConversionError($result->Error); + } + + if (! property_exists($result, 'EndConvert')) { + throw new ConversionNotComplete($result->Percent, $result->Filename, $result->FileUrl); + } + + return [ + 'fileType' => $result->FileType, + 'fileUrl' => $result->FileUrl, + ]; + } +} diff --git a/web/documentserver-example/php-laravel/app/OnlyOffice/Models/Format.php b/web/documentserver-example/php-laravel/app/OnlyOffice/Models/Format.php new file mode 100644 index 00000000..2079bf40 --- /dev/null +++ b/web/documentserver-example/php-laravel/app/OnlyOffice/Models/Format.php @@ -0,0 +1,55 @@ +actions); + } + + public function extension(): string + { + return $this->name; + } + + public function isWord(): bool + { + return $this->type === FormatType::WORD->value; + } + + public function isCell(): bool + { + return $this->type === FormatType::CELL->value; + } + + public function isSlide(): bool + { + return $this->type === FormatType::SLIDE->value; + } + + public function isPDF(): bool + { + return $this->type === FormatType::PDF->value; + } +} diff --git a/web/documentserver-example/php-laravel/app/OnlyOffice/Services/CallbackService.php b/web/documentserver-example/php-laravel/app/OnlyOffice/Services/CallbackService.php new file mode 100644 index 00000000..32e73ce9 --- /dev/null +++ b/web/documentserver-example/php-laravel/app/OnlyOffice/Services/CallbackService.php @@ -0,0 +1,225 @@ +data = $data; + } + + public function processTrackerStatusEditing($callback, string $fileid) + { + return $this->processTrackerStatusEditingAndClosed($callback, $fileid); + } + + public function processTrackerStatusMustsave($callback, string $fileid) + { + return $this->processTrackerStatusMustsaveAndCorrupted($callback, $fileid); + } + + public function processTrackerStatusCorrupted($callback, string $fileid) + { + return $this->processTrackerStatusMustsaveAndCorrupted($callback, $fileid); + } + + public function processTrackerStatusClosed($callback, string $fileid) + { + return $this->processTrackerStatusEditingAndClosed($callback, $fileid); + } + + public function processTrackerStatusForcesave($callback, string $fileid) + { + $isSubmitForm = $callback->getForceSaveType()->getValue() === CallbackForceSaveType::SUBMIT_FORM; + + if ($isSubmitForm && ! $callback->getFormsDataUrl()) { + Log::error('Document editing service did not return formsDataUrl'); + + return ['error' => 1]; + } + + $url = $callback->getUrl(); + $key = $callback->getKey(); + $user = $callback->getUsers()[0]; + $filename = $this->data['filename']; + $address = $this->data['address']; + + $url = $this->settingsManager->replaceDocumentServerUrlToInternal($url); + + $fileExtension = PathInfo::extension($filename); + $downloadExtension = PathInfo::extension($url); + + if ($fileExtension !== $downloadExtension) { + $result = app(ConvertCommand::class) + ->__invoke(new ConvertRequest( + filename: $filename, + fileType: $downloadExtension, + outputType: $fileExtension, + url: $url, + password: null, + user: $user, + userAddress: $address, + )); + + if (array_key_exists('step', $result) || array_key_exists('error', $result)) { + $filename = PathInfo::filename($filename).".$downloadExtension"; + } else { + $url = $result['fileUrl']; + } + } + + $content = app(DownloadFileCommand::class) + ->__invoke(new DownloadFileRequest(url: $url))['content']; + + if ($isSubmitForm) { + $formsDataUrl = $this->settingsManager->replaceDocumentServerUrlToInternal($callback->getFormsDataUrl()); + + $formData = app(DownloadFileCommand::class) + ->__invoke(new DownloadFileRequest(url: $formsDataUrl))['content']; + + app(SaveDocumentFormCommand::class) + ->__invoke(new SaveDocumentFormRequest( + filename: $filename, + userDirectory: $address, + user: $user, + formContent: $content, + formDataContent: $formData, + )); + } else { + app(ForceSaveDocumentCommand::class) + ->__invoke( + new ForceSaveDocumentRequest( + filename: $filename, + userDirectory: $address, + content: $content + ) + ); + } + + $result['error'] = 0; + + return $result; + } + + public function processTrackerStatusMustsaveAndCorrupted($callback, string $fileid) + { + $url = $callback->getUrl(); + $key = $callback->getKey(); + $user = $callback->getUsers()[0]; + $changes = null; + $filename = $this->data['filename']; + $address = $this->data['address']; + + $url = $this->settingsManager->replaceDocumentServerUrlToInternal($url); + + $fileExtension = PathInfo::extension($filename); + $downloadExtension = PathInfo::extension($url); + + if ($fileExtension !== $downloadExtension) { + $result = app(ConvertCommand::class) + ->__invoke(new ConvertRequest( + filename: $filename, + fileType: $downloadExtension, + outputType: $fileExtension, + url: $url, + password: null, + user: $user, + userAddress: $address, + )); + + if (array_key_exists('step', $result) || array_key_exists('error', $result)) { + $filename = PathInfo::filename($filename).".$downloadExtension"; + } else { + $url = $result['fileUrl']; + } + } + + $content = app(DownloadFileCommand::class) + ->__invoke(new DownloadFileRequest(url: $url))['content']; + + $changesUrl = $callback->getChangesurl(); + if ($changesUrl) { + $changesUrl = Str::replace(URL::origin($changesUrl), $this->settingsManager->getSetting('url.server.private'), $changesUrl); + + $changes = app(DownloadFileCommand::class) + ->__invoke(new DownloadFileRequest(url: $changesUrl))['content']; + } + + $historyObject = $callback->getHistory(); + $history = $historyObject ? $historyObject->getChanges() : null; + $serverVersion = $historyObject ? $historyObject->getServerVersion() : null; + + app(SaveDocumentCommand::class)->__invoke( + new SaveDocumentRequest( + Path::join($address, $filename), + $fileExtension, + $key, + $content, + $user, + $serverVersion, + $history, + $changes, + ) + ); + + return [ + 'error' => 0, + ]; + } + + public function processTrackerStatusEditingAndClosed($callback, string $fileid) + { + $actions = $callback->getActions(); + if ($actions && $actions[0]['type'] == 0) { + $user = $actions[0]['userid']; + if (array_search($user, $callback->getUsers()) === false) { + app(ForceSaveCommad::class) + ->__invoke(new ForceSaveRequest(key: $callback->getKey())); + } + } + + $result['error'] = 0; + + return $result; + } +} diff --git a/web/documentserver-example/php-laravel/app/OnlyOffice/Services/HttpClient.php b/web/documentserver-example/php-laravel/app/OnlyOffice/Services/HttpClient.php new file mode 100644 index 00000000..f774be62 --- /dev/null +++ b/web/documentserver-example/php-laravel/app/OnlyOffice/Services/HttpClient.php @@ -0,0 +1,72 @@ +status = null; + $this->body = null; + } + + /** + * Request to Document Server with turn off verification. + * + * @param string $url - request address + * @param string $method - request method + * @param array $opts - request options + */ + public function request($url, $method = 'GET', $opts = []) + { + $httpClient = new Client(['base_uri' => $url]); + try { + $response = $httpClient->request($method, $url, $opts); + $this->body = $response->getBody()->getContents(); + $this->status = $response->getStatusCode(); + } catch (RequestException $requestException) { + throw new Exception($requestException->getMessage()); + } + } + + /** + * Get the status code + */ + public function getStatusCode() + { + return $this->status; + } + + /** + * Get the response body. + */ + public function getBody() + { + return $this->body; + } +} diff --git a/web/documentserver-example/php-laravel/app/Services/Config.php b/web/documentserver-example/php-laravel/app/OnlyOffice/Services/RequestService.php similarity index 54% rename from web/documentserver-example/php-laravel/app/Services/Config.php rename to web/documentserver-example/php-laravel/app/OnlyOffice/Services/RequestService.php index 39707aa3..4d50ff88 100644 --- a/web/documentserver-example/php-laravel/app/Services/Config.php +++ b/web/documentserver-example/php-laravel/app/OnlyOffice/Services/RequestService.php @@ -16,27 +16,21 @@ * limitations under the License. */ -namespace App\Services; +namespace App\OnlyOffice\Services; -use Exception; +use App\OnlyOffice\Managers\JWTManager; +use App\OnlyOffice\Managers\SettingsManager; +use Onlyoffice\DocsIntegrationSdk\Service\Request\RequestService as OnlyOfficeRequestService; -abstract class Config +class RequestService extends OnlyOfficeRequestService { - protected array $config; - - public function get(string $key, mixed $default = null): mixed + public function __construct(SettingsManager $settingsManager, HttpClient $httpClient, JWTManager $jwtManager) { - $keys = explode('.', $key); - $result = $this->config; + parent::__construct($settingsManager, $httpClient, $jwtManager); + } - try { - foreach ($keys as $key) { - $result = $result[$key]; - } - } catch (Exception $e) { - $result = $default; - } - - return $result; + public function getFileUrlForConvert() + { + return ''; } } diff --git a/web/documentserver-example/php-laravel/app/Providers/AppServiceProvider.php b/web/documentserver-example/php-laravel/app/Providers/AppServiceProvider.php index b116dbfb..123f25fa 100644 --- a/web/documentserver-example/php-laravel/app/Providers/AppServiceProvider.php +++ b/web/documentserver-example/php-laravel/app/Providers/AppServiceProvider.php @@ -2,7 +2,7 @@ namespace App\Providers; -use App\Repositories\FormatRepository; +use App\OnlyOffice\Managers\FormatManager; use Illuminate\Support\ServiceProvider; class AppServiceProvider extends ServiceProvider @@ -12,10 +12,8 @@ class AppServiceProvider extends ServiceProvider */ public function register(): void { - $this->app->singleton(FormatRepository::class, function () { - $path = public_path('assets/document-formats/onlyoffice-docs-formats.json'); - - return new FormatRepository($path); + $this->app->singleton(FormatManager::class, function () { + return new FormatManager; }); } diff --git a/web/documentserver-example/php-laravel/app/Services/Docs/Command/CommandRequest.php b/web/documentserver-example/php-laravel/app/Services/Docs/Command/CommandRequest.php deleted file mode 100644 index d0330163..00000000 --- a/web/documentserver-example/php-laravel/app/Services/Docs/Command/CommandRequest.php +++ /dev/null @@ -1,76 +0,0 @@ -jwt->encode(['payload' => $content]); - $this->headers = [$this->config->get('jwt.header') => "Bearer $token"]; - } - - public function send(array $content, ?string $key = null): mixed - { - if ($this->config->get('jwt.enabled')) { - $this->withJWTHeader($content); - $content['token'] = $this->jwt->encode($content); - } - - $client = Http::withHeaders($this->headers) - ->asJson() - ->acceptJson(); - - $url = $this->config->get('url.command'); - - if (Str::of($url)->isUrl(['https']) - && ! $this->config->get('ssl_verify')) { - $client = $client->withoutVerifying(); - } - - if ($key) { - $url = "$url?shardkey=".urlencode($key); - } - - $response = $client->post($url, $content); - - if (! $response->ok()) { - throw new Exception('Could not execute the command.'); - } - - $result = $response->json(); - - if (array_key_exists('error', $result) && $result['error'] !== 0) { - throw new CommandServiceError($result['error']); - } - - return $result; - } -} diff --git a/web/documentserver-example/php-laravel/app/Services/Docs/Command/ForceSaveRequest.php b/web/documentserver-example/php-laravel/app/Services/Docs/Command/ForceSaveRequest.php deleted file mode 100644 index 72b673b3..00000000 --- a/web/documentserver-example/php-laravel/app/Services/Docs/Command/ForceSaveRequest.php +++ /dev/null @@ -1,34 +0,0 @@ - 'forcesave', - 'key' => $key, - ]; - - $result = $this->send($content, $key); - - return $result; - } -} diff --git a/web/documentserver-example/php-laravel/app/Services/Docs/Command/ForgottenDeleteRequest.php b/web/documentserver-example/php-laravel/app/Services/Docs/Command/ForgottenDeleteRequest.php deleted file mode 100644 index 16c9088e..00000000 --- a/web/documentserver-example/php-laravel/app/Services/Docs/Command/ForgottenDeleteRequest.php +++ /dev/null @@ -1,34 +0,0 @@ - 'deleteForgotten', - 'key' => $key, - ]; - - $result = $this->send($content, $key); - - return $result['key']; - } -} diff --git a/web/documentserver-example/php-laravel/app/Services/Docs/Command/ForgottenListRequest.php b/web/documentserver-example/php-laravel/app/Services/Docs/Command/ForgottenListRequest.php deleted file mode 100644 index 6900f354..00000000 --- a/web/documentserver-example/php-laravel/app/Services/Docs/Command/ForgottenListRequest.php +++ /dev/null @@ -1,33 +0,0 @@ - 'getForgottenList', - ]; - - $result = $this->send($content); - - return $result['keys']; - } -} diff --git a/web/documentserver-example/php-laravel/app/Services/Docs/Conversion/ConversionRequest.php b/web/documentserver-example/php-laravel/app/Services/Docs/Conversion/ConversionRequest.php deleted file mode 100644 index feaf960d..00000000 --- a/web/documentserver-example/php-laravel/app/Services/Docs/Conversion/ConversionRequest.php +++ /dev/null @@ -1,84 +0,0 @@ -jwt->encode(['payload' => $content]); - $this->headers = [$this->config->get('jwt.header') => "Bearer $token"]; - } - - public function send(array $content, ?string $key = null): mixed - { - if ($this->config->get('jwt.enabled')) { - $this->withJWTHeader($content); - $content['token'] = $this->jwt->encode($content); - } - - $client = Http::withHeaders($this->headers) - ->timeout($this->config->get('conversion.timeout')) - ->asJson() - ->acceptJson(); - - $url = $this->config->get('conversion.url'); - - if ( - Str::of($url)->isUrl(['https']) - && ! $this->config->get('ssl_verify') - ) { - $client = $client->withoutVerifying(); - } - - if ($key) { - $url = "$url?shardkey=".urlencode($key); - } - - $response = $client->post($url, $content); - - if (! $response->ok()) { - throw new Exception('Could not convert the file'); - } - - $result = $response->json(); - - if (array_key_exists('error', $result)) { - throw new ConversionError($result['error']); - } - - if (! $result['endConvert']) { - throw new ConversionNotComplete($result['percent'], $result['filename'], $result['fileUrl']); - } - - return $result; - } -} diff --git a/web/documentserver-example/php-laravel/app/Services/JWT.php b/web/documentserver-example/php-laravel/app/Services/JWT.php deleted file mode 100644 index 50eec1ce..00000000 --- a/web/documentserver-example/php-laravel/app/Services/JWT.php +++ /dev/null @@ -1,65 +0,0 @@ -secret = $config->get('jwt.secret'); - $this->algorithm = $config->get('jwt.algorithm'); - } - - /** - * Encode a payload object into a token using a secret key - * - * @param array $payload - */ - public function encode(mixed $payload): string - { - return FirebaseJWT::encode($payload, $this->secret, $this->algorithm); - } - - /** - * Decode a token into a payload object using a secret key - * - * - * @return string - */ - public function decode(string $token) - { - try { - $payload = FirebaseJWT::decode( - $token, - new Key($this->secret, $this->algorithm), - ); - } catch (\UnexpectedValueException $e) { - $payload = ''; - } - - return $payload; - } -} diff --git a/web/documentserver-example/php-laravel/app/Services/StorageConfig.php b/web/documentserver-example/php-laravel/app/Services/StorageConfig.php deleted file mode 100644 index d6fa5fa5..00000000 --- a/web/documentserver-example/php-laravel/app/Services/StorageConfig.php +++ /dev/null @@ -1,38 +0,0 @@ -schemeAndHttpHost()), '/'); - $privateStorageUrl = rtrim(env('DOCUMENT_STORAGE_PRIVATE_URL', $publicStorageUrl), '/'); - - $this->config = [ - 'url' => [ - 'private' => $privateStorageUrl, - 'public' => $publicStorageUrl, - ], - 'file' => [ - 'max_size' => env('DOCUMENT_STORAGE_MAXIMUM_FILE_SIZE', 5 * 1024 * 1024), - ], - ]; - } -} diff --git a/web/documentserver-example/php-laravel/app/UseCases/Docs/Command/ForceSaveCommad.php b/web/documentserver-example/php-laravel/app/UseCases/Docs/Command/ForceSaveCommad.php index 127fd03d..34529dbe 100644 --- a/web/documentserver-example/php-laravel/app/UseCases/Docs/Command/ForceSaveCommad.php +++ b/web/documentserver-example/php-laravel/app/UseCases/Docs/Command/ForceSaveCommad.php @@ -18,8 +18,8 @@ namespace App\UseCases\Docs\Command; -use App\Exceptions\CommandServiceError; -use App\Services\Docs\Command\ForceSaveRequest as ForceSave; +use App\OnlyOffice\Miscellaneous\CommandRequest; +use Exception; use Illuminate\Support\Facades\Log; class ForceSaveCommad @@ -27,9 +27,9 @@ class ForceSaveCommad public function __invoke(ForceSaveRequest $request): void { try { - app(ForceSave::class) - ->save($request->key); - } catch (CommandServiceError $e) { + app(CommandRequest::class) + ->forceSave($request->key); + } catch (Exception $e) { Log::debug($e->getMessage()); } } diff --git a/web/documentserver-example/php-laravel/app/UseCases/Docs/Command/UpdateMetaCommand.php b/web/documentserver-example/php-laravel/app/UseCases/Docs/Command/UpdateMetaCommand.php index 1ff68196..f4742cc2 100644 --- a/web/documentserver-example/php-laravel/app/UseCases/Docs/Command/UpdateMetaCommand.php +++ b/web/documentserver-example/php-laravel/app/UseCases/Docs/Command/UpdateMetaCommand.php @@ -2,21 +2,15 @@ namespace App\UseCases\Docs\Command; -use App\Services\Docs\Command\CommandRequest; +use App\OnlyOffice\Miscellaneous\CommandRequest; class UpdateMetaCommand { public function __invoke(UpdateMetaRequest $request): void { - $content = [ - 'c' => 'meta', - 'key' => $request->key, - 'meta' => [ - 'title' => $request->title, - ], - ]; + $meta = ['title' => $request->title]; app(CommandRequest::class) - ->send($content, $request->key); + ->updateMeta($request->key, $meta); } } diff --git a/web/documentserver-example/php-laravel/app/UseCases/Docs/Conversion/ConvertCommand.php b/web/documentserver-example/php-laravel/app/UseCases/Docs/Conversion/ConvertCommand.php index 613cbe8b..c47cf70e 100644 --- a/web/documentserver-example/php-laravel/app/UseCases/Docs/Conversion/ConvertCommand.php +++ b/web/documentserver-example/php-laravel/app/UseCases/Docs/Conversion/ConvertCommand.php @@ -22,26 +22,20 @@ use App\Exceptions\ConversionError; use App\Exceptions\ConversionNotComplete; use App\Helpers\Path\PathInfo; use App\Helpers\URL\FileURL; -use App\Repositories\FormatRepository; -use App\Services\Docs\Conversion\ConversionRequest; -use App\Services\JWT; -use App\Services\ServerConfig; +use App\OnlyOffice\Managers\FormatManager; +use App\OnlyOffice\Miscellaneous\ConvertRequest as ConvertRequestAdapter; use Exception; use Illuminate\Support\Str; class ConvertCommand { - public function __construct( - private ServerConfig $serverConfig, - private FormatRepository $formatRepository, - private JWT $jwt, - ) {} + public function __construct(private FormatManager $formatManager) {} public function __invoke(ConvertRequest $request): mixed { - $format = $this->formatRepository->find($request->fileType); + $format = $this->formatManager->find($request->fileType); - if (! $format->convertible() && $request->outputType == 'ooxml') { + if (! $format->isAutoConvertable() && $request->outputType == 'ooxml') { throw new Exception("The format $request->fileType is not convertible."); } @@ -61,8 +55,7 @@ class ConvertCommand ]; try { - $result = app(ConversionRequest::class) - ->send($content, $key); + $result = app(ConvertRequestAdapter::class)->convert($content); $result['filename'] = PathInfo::filename($request->filename).'.'.$result['fileType']; } catch (ConversionNotComplete $e) { return [ diff --git a/web/documentserver-example/php-laravel/app/UseCases/Document/Create/CreateDocumentCommand.php b/web/documentserver-example/php-laravel/app/UseCases/Document/Create/CreateDocumentCommand.php index b9502196..24914c0b 100644 --- a/web/documentserver-example/php-laravel/app/UseCases/Document/Create/CreateDocumentCommand.php +++ b/web/documentserver-example/php-laravel/app/UseCases/Document/Create/CreateDocumentCommand.php @@ -24,8 +24,8 @@ use App\Helpers\UniqueFilename; use App\Models\File; use App\Models\Version; use App\Models\VersionInfo; +use App\OnlyOffice\Managers\FormatManager; use App\Repositories\FileRepository; -use App\Repositories\FormatRepository; use App\Repositories\UserRepository; use App\Repositories\VersionRepository; use Illuminate\Support\Str; @@ -35,7 +35,7 @@ class CreateDocumentCommand { public function __construct( private FileRepository $fileRepository, - private FormatRepository $formatRepository, + private FormatManager $formatManager, private UserRepository $userRepository, private VersionRepository $versionRepository, ) {} @@ -45,10 +45,10 @@ class CreateDocumentCommand $filePath = Path::join($request->userDirectory, $request->filename); $filePath = UniqueFilename::for($filePath); - $format = $this->formatRepository->find($request->fileType); + $format = $this->formatManager->find($request->fileType); $user = $this->userRepository->find($request->user); - if ($format === null || empty($format->actions)) { + if ($format === null || empty($format->getActions())) { throw new UnexpectedValueException("The $request->fileType format is not supported"); } diff --git a/web/documentserver-example/php-laravel/app/UseCases/Document/Find/FindAllDocumentsQueryHandler.php b/web/documentserver-example/php-laravel/app/UseCases/Document/Find/FindAllDocumentsQueryHandler.php index ccf9348f..d39c95b7 100644 --- a/web/documentserver-example/php-laravel/app/UseCases/Document/Find/FindAllDocumentsQueryHandler.php +++ b/web/documentserver-example/php-laravel/app/UseCases/Document/Find/FindAllDocumentsQueryHandler.php @@ -3,15 +3,15 @@ namespace App\UseCases\Document\Find; use App\Helpers\Path\PathInfo; +use App\OnlyOffice\Managers\FormatManager; use App\Repositories\FileRepository; -use App\Repositories\FormatRepository; use App\Repositories\VersionRepository; class FindAllDocumentsQueryHandler { public function __construct( private FileRepository $fileRepository, - private FormatRepository $formatRepository, + private FormatManager $formatManager, private VersionRepository $versionRepository, ) {} @@ -27,7 +27,7 @@ class FindAllDocumentsQueryHandler $result[] = [ 'filename' => PathInfo::basename($file->filename), 'version' => $currentVersion, - 'format' => $this->formatRepository->find(PathInfo::extension($file->filename)), + 'format' => $this->formatManager->find(PathInfo::extension($file->filename)), 'lastModified' => $file->modified, ]; } diff --git a/web/documentserver-example/php-laravel/app/UseCases/Document/Find/FindDocumentHistoryQueryHandler.php b/web/documentserver-example/php-laravel/app/UseCases/Document/Find/FindDocumentHistoryQueryHandler.php index a3814de2..475c05dc 100644 --- a/web/documentserver-example/php-laravel/app/UseCases/Document/Find/FindDocumentHistoryQueryHandler.php +++ b/web/documentserver-example/php-laravel/app/UseCases/Document/Find/FindDocumentHistoryQueryHandler.php @@ -4,15 +4,18 @@ namespace App\UseCases\Document\Find; use App\Helpers\Path\PathInfo; use App\Helpers\URL\FileURL; +use App\OnlyOffice\Managers\JWTManager; +use App\OnlyOffice\Managers\SettingsManager; use App\Repositories\UserRepository; use App\Repositories\VersionRepository; -use App\Services\JWT; class FindDocumentHistoryQueryHandler { public function __construct( private VersionRepository $versionRepository, private UserRepository $userRepository, + private SettingsManager $settings, + private JWTManager $jwt, ) {} public function __invoke(FindDocumentHistoryQuery $request): array @@ -59,7 +62,7 @@ class FindDocumentHistoryQueryHandler $item['url'] = FileURL::download( PathInfo::basename($request->filename), $request->userAddress ); - $item['token'] = app(JWT::class)->encode($item); + $item['token'] = $this->jwt->encode($item, $this->settings->getSetting('jwt.secret')); $history['history'][] = $item; } diff --git a/web/documentserver-example/php-laravel/app/UseCases/Document/Find/FindDocumentQueryHandler.php b/web/documentserver-example/php-laravel/app/UseCases/Document/Find/FindDocumentQueryHandler.php index 02df1f47..f6fd532f 100644 --- a/web/documentserver-example/php-laravel/app/UseCases/Document/Find/FindDocumentQueryHandler.php +++ b/web/documentserver-example/php-laravel/app/UseCases/Document/Find/FindDocumentQueryHandler.php @@ -4,9 +4,9 @@ namespace App\UseCases\Document\Find; use App\Helpers\Path\Path; use App\Helpers\Path\PathInfo; +use App\OnlyOffice\Managers\FormatManager; use App\Repositories\FileRepository; use App\Repositories\ForceSavedFilesRepository; -use App\Repositories\FormatRepository; use App\Repositories\UserRepository; use App\Repositories\VersionRepository; use DomainException; @@ -18,7 +18,7 @@ class FindDocumentQueryHandler private VersionRepository $versionRepository, private ForceSavedFilesRepository $forceSavedFilesRepository, private UserRepository $userRepository, - private FormatRepository $formatRepository, + private FormatManager $formatManager, ) {} public function __invoke(FindDocumentQuery $request): array @@ -49,7 +49,7 @@ class FindDocumentQueryHandler 'content' => $file->content, 'size' => $file->size, 'mimeType' => $file->mime, - 'format' => $this->formatRepository->find(PathInfo::extension($request->filename)), + 'format' => $this->formatManager->find(PathInfo::extension($request->filename)), ]; return $document; diff --git a/web/documentserver-example/php-laravel/app/UseCases/Editor/Create/CreateConfigCommand.php b/web/documentserver-example/php-laravel/app/UseCases/Editor/Create/CreateConfigCommand.php index e434b3e5..ea611e9f 100644 --- a/web/documentserver-example/php-laravel/app/UseCases/Editor/Create/CreateConfigCommand.php +++ b/web/documentserver-example/php-laravel/app/UseCases/Editor/Create/CreateConfigCommand.php @@ -21,19 +21,19 @@ namespace App\UseCases\Editor\Create; use App\Models\Document; use App\Models\Editor\Editor; use App\Models\Editor\EditorConfig; -use App\Repositories\FormatRepository; +use App\OnlyOffice\Managers\FormatManager; use App\Repositories\UserRepository; class CreateConfigCommand { public function __construct( private UserRepository $userRepository, - private FormatRepository $formatRepository, + private FormatManager $formatManager, ) {} public function __invoke(CreateConfigRequest $request): array { - $format = $this->formatRepository->find($request->fileExtension); + $format = $this->formatManager->find($request->fileExtension); $user = $this->userRepository->find($request->user); if ($user->goback !== null) { diff --git a/web/documentserver-example/php-laravel/app/UseCases/Forgotten/Delete/DeleteForgottenFileCommand.php b/web/documentserver-example/php-laravel/app/UseCases/Forgotten/Delete/DeleteForgottenFileCommand.php index 4203367d..16acc81f 100644 --- a/web/documentserver-example/php-laravel/app/UseCases/Forgotten/Delete/DeleteForgottenFileCommand.php +++ b/web/documentserver-example/php-laravel/app/UseCases/Forgotten/Delete/DeleteForgottenFileCommand.php @@ -18,12 +18,13 @@ namespace App\UseCases\Forgotten\Delete; -use App\Services\Docs\Command\ForgottenDeleteRequest; +use App\OnlyOffice\Miscellaneous\CommandRequest; class DeleteForgottenFileCommand { public function __invoke(DeleteForgottenFileRequest $request): void { - app()->make(ForgottenDeleteRequest::class)->delete($request->key); + app(CommandRequest::class) + ->deleteForgotten($request->key); } } diff --git a/web/documentserver-example/php-laravel/app/UseCases/Forgotten/Find/FindAllForgottenFilesQueryHandler.php b/web/documentserver-example/php-laravel/app/UseCases/Forgotten/Find/FindAllForgottenFilesQueryHandler.php index 1e09926a..8a82e1bb 100644 --- a/web/documentserver-example/php-laravel/app/UseCases/Forgotten/Find/FindAllForgottenFilesQueryHandler.php +++ b/web/documentserver-example/php-laravel/app/UseCases/Forgotten/Find/FindAllForgottenFilesQueryHandler.php @@ -20,40 +20,41 @@ namespace App\UseCases\Forgotten\Find; use App\Helpers\Path\PathInfo; use App\Helpers\URL\URL; -use App\Repositories\FormatRepository; -use App\Services\Docs\Command\ForgottenFileRequest; -use App\Services\Docs\Command\ForgottenListRequest; -use App\Services\ServerConfig; +use App\OnlyOffice\Managers\FormatManager; +use App\OnlyOffice\Managers\SettingsManager; +use App\OnlyOffice\Miscellaneous\CommandRequest; use Illuminate\Support\Str; class FindAllForgottenFilesQueryHandler { public function __construct( - private ServerConfig $serverConfig, - private FormatRepository $formatRepository, + private SettingsManager $settings, + private FormatManager $formatManager, ) {} public function __invoke(FindAllForgottenFilesQuery $query): array { $filesList = []; + $commandRequest = app(CommandRequest::class); - $keys = app()->make(ForgottenListRequest::class)->get(); + $result = $commandRequest->getForgottenList(); + $keys = $result->keys; foreach ($keys as $key) { - $filesList[] = app()->make(ForgottenFileRequest::class)->get($key); + $filesList[] = $commandRequest->getForgotten($key); } $files = []; foreach ($filesList as $fileItem) { - $url = $fileItem['url']; - $url = Str::replace(URL::origin($url), $this->serverConfig->get('url.public'), $url); + $url = $fileItem->url; + $url = Str::replace(URL::origin($url), $this->settings->getSetting('url.server.public'), $url); $files[] = [ - 'key' => $fileItem['key'], + 'key' => $fileItem->key, 'filename' => $url, 'url' => $url, - 'format' => $this->formatRepository->find(PathInfo::extension($fileItem['url'])), + 'format' => $this->formatManager->find(PathInfo::extension($fileItem->url)), ]; } diff --git a/web/documentserver-example/php-laravel/composer.json b/web/documentserver-example/php-laravel/composer.json index c7a73b44..2b5dc048 100644 --- a/web/documentserver-example/php-laravel/composer.json +++ b/web/documentserver-example/php-laravel/composer.json @@ -3,7 +3,8 @@ "php": "^8.2", "firebase/php-jwt": "^6.10", "laravel/framework": "^11.0", - "laravel/tinker": "^2.9" + "laravel/tinker": "^2.9", + "onlyoffice/docs-integration-sdk": "^1.1" }, "require-dev": { "fakerphp/faker": "^1.23", diff --git a/web/documentserver-example/php-laravel/composer.lock b/web/documentserver-example/php-laravel/composer.lock index 45402c59..22d1b79a 100644 --- a/web/documentserver-example/php-laravel/composer.lock +++ b/web/documentserver-example/php-laravel/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "15b06064f4351d124f81a5718daddb7c", + "content-hash": "349f218d77cda1f9ef25791dae86f9d4", "packages": [ { "name": "brick/math", @@ -2380,6 +2380,59 @@ ], "time": "2024-03-06T16:17:14+00:00" }, + { + "name": "onlyoffice/docs-integration-sdk", + "version": "v1.1.0", + "source": { + "type": "git", + "url": "https://github.com/ONLYOFFICE/docs-integration-sdk-php.git", + "reference": "3715cb022c182551f4bad43f5869c0536260e5ed" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ONLYOFFICE/docs-integration-sdk-php/zipball/3715cb022c182551f4bad43f5869c0536260e5ed", + "reference": "3715cb022c182551f4bad43f5869c0536260e5ed", + "shasum": "" + }, + "require": { + "vlucas/phpdotenv": "^5.6" + }, + "type": "library", + "autoload": { + "psr-4": { + "Onlyoffice\\DocsIntegrationSdk\\": "src/", + "Onlyoffice\\DocsIntegrationSdk\\Util\\": "src/util/", + "Onlyoffice\\DocsIntegrationSdk\\Models\\": "src/models/", + "Onlyoffice\\DocsIntegrationSdk\\Manager\\Formats\\": "src/manager/formats/", + "Onlyoffice\\DocsIntegrationSdk\\Service\\Request\\": "src/service/request/", + "Onlyoffice\\DocsIntegrationSdk\\Manager\\Document\\": "src/manager/document/", + "Onlyoffice\\DocsIntegrationSdk\\Manager\\Security\\": "src/manager/security/", + "Onlyoffice\\DocsIntegrationSdk\\Manager\\Settings\\": "src/manager/settings/", + "Onlyoffice\\DocsIntegrationSdk\\Service\\DocEditorConfig\\": "src/service/doceditorconfig/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Ascensio System SIA" + } + ], + "description": "ONLYOFFICE Docs integration SDK", + "homepage": "https://www.onlyoffice.com", + "keywords": [ + "onlyoffice" + ], + "support": { + "email": "support@onlyoffice.com", + "forum": "https://forum.onlyoffice.com/", + "issues": "https://github.com/ONLYOFFICE/docs-integration-sdk-php/issues", + "source": "https://github.com/ONLYOFFICE/docs-integration-sdk-php" + }, + "time": "2025-01-15T13:52:01+00:00" + }, { "name": "phpoption/phpoption", "version": "1.9.2", diff --git a/web/documentserver-example/php-laravel/public/assets/document-formats b/web/documentserver-example/php-laravel/public/assets/document-formats deleted file mode 160000 index aff1285e..00000000 --- a/web/documentserver-example/php-laravel/public/assets/document-formats +++ /dev/null @@ -1 +0,0 @@ -Subproject commit aff1285e92c02b46225a501e94cba3a07bb6e6f3 diff --git a/web/documentserver-example/php-laravel/resources/views/forgotten.blade.php b/web/documentserver-example/php-laravel/resources/views/forgotten.blade.php index 738cbf1c..ae9ee294 100644 --- a/web/documentserver-example/php-laravel/resources/views/forgotten.blade.php +++ b/web/documentserver-example/php-laravel/resources/views/forgotten.blade.php @@ -85,7 +85,7 @@ @foreach ($files as $file)