Compare commits

..

97 Commits

Author SHA1 Message Date
1ac382d3c0 java-spring: https 2023-02-10 10:39:03 +03:00
5933aa83ad Merge remote-tracking branch 'remotes/origin/master' into develop 2023-02-09 12:27:46 +05:00
78bd037486 Merge pull request #340 from ONLYOFFICE/refactor/linter-formatting
Refactor/linter formatting
2023-02-09 09:31:32 +03:00
17beef45f4 php: linter to changelog 2023-02-09 11:30:13 +05:00
b11a1be481 php: PSR1.Files.SideEffects disabled in ruleset.xml 2023-02-09 09:16:46 +03:00
a3e140981d php: correct license type 2023-02-08 22:53:48 +05:00
e0386f7cf9 php: added licenses of new dependency (PHP_CodeSniffer) 2023-02-03 17:25:17 +03:00
0521f20413 php: deleted unused ruleset (uses - ruleset.xml) 2023-02-03 17:23:02 +03:00
61b5746ddf php: deleted dependency: cs-fixer 2023-02-03 17:17:40 +03:00
57d823acb1 Merge branch 'develop' into refactor/linter-formatting 2023-02-03 14:47:29 +03:00
4d99e2e406 php: example namespace for class User (users.php) added 2023-02-03 12:01:22 +03:00
bec48ed834 php: spaces in "mixed"-php files auto-fixed 2023-02-03 11:17:45 +03:00
e856f5bcb1 php: fixed spaces and new lines for multi-line functions 2023-02-03 11:06:05 +03:00
c57a710bca Merge pull request #339 from ONLYOFFICE/fix/phpcs-ruleset
ci: custom ruleset
2023-02-03 09:09:39 +03:00
248e9213a1 ci: custom ruleset 2023-02-03 11:06:55 +05:00
a035adcbd9 php: function names converted to camelCase (exclude mime_content_type) 2023-02-02 17:23:42 +03:00
7fd1b65fec php: fixed doc comments and multi-line assignments 2023-02-02 16:48:58 +03:00
8ee0aa45b9 php: line exceeds maximum limit of 120 characters 2023-02-02 15:28:05 +03:00
dfcf244dc8 php: comments for functions are standardized to PEAR Docblock Comment standards 2023-02-02 14:14:57 +03:00
0563795494 php: spaces and new lines around operators fixed 2023-02-02 11:27:14 +03:00
b6b6e80ffb php: no additional blank lines at end of doc comment 2023-02-02 10:53:15 +03:00
bd3b91d02f php: include/require and file path should be divided with a single space 2023-02-02 10:34:58 +03:00
555f8d43cd php: braces after functions and oop constructs on the next line 2023-02-01 16:46:31 +03:00
3f48a8d492 php: trailing whitespace at the end of blank line removed 2023-02-01 15:57:27 +03:00
bb921e7eff php: method argument spaces normalized 2023-02-01 14:48:48 +03:00
13d5e6fa94 php: binary operators should be surrounded by single space 2023-02-01 14:12:28 +03:00
cbfcf5de96 php: no spaces after function name 2023-02-01 14:06:41 +03:00
4771d96819 php: unary operators should be placed adjacent to their operands 2023-02-01 13:47:04 +03:00
d2aa6f0653 php: used null coalescing operator ?? where possible 2023-02-01 13:44:26 +03:00
cf2a00a374 php: used operator ?: where possible 2023-02-01 13:39:40 +03:00
bdfb75dc84 php: standardized spaces around ternary operator 2023-02-01 13:37:03 +03:00
9e21ca625c Merge pull request #334 from ONLYOFFICE/feature/token-and-address-required-on-download
Feature/token and address required on download
2023-02-01 12:59:22 +03:00
02def07f23 php: require user address on download 2023-02-01 14:30:54 +05:00
fc4dac6c4b java-spring: token and user address required on download 2023-02-01 14:29:52 +05:00
486a09f3b2 java: token and address required on download 2023-02-01 14:28:28 +05:00
9a22fc854b csharp-mvc: user address required on download 2023-02-01 14:27:32 +05:00
ac4d5561a2 c-sharp: user address required on download 2023-02-01 14:26:37 +05:00
98cdda06c4 ruby: user address required on download 2023-02-01 14:25:24 +05:00
744fccf913 python: user address required on download 2023-02-01 14:24:34 +05:00
349ff5d61d php: all classes must be final, except abstract ones and doctrine entities 2023-02-01 11:22:29 +03:00
dbba22df23 php: array_push() converted to short usage 2023-02-01 09:21:35 +03:00
2ddd822b24 php: replace non multibyte-safe functions with corresponding mb function 2023-02-01 09:09:58 +03:00
6b4d6baf4b php: short scalar cast 2023-01-31 17:29:58 +03:00
2c8d151cc7 php: there must be no trailing spaces inside comment or PHPDoc 2023-01-31 17:10:22 +03:00
60c7c025a3 Merge remote-tracking branch 'remotes/origin/hotfix/v7.3.1' into develop 2023-01-31 18:44:33 +05:00
7aaf5243cb Merge pull request #337 from ONLYOFFICE/feature/add-oform-parameter
nodejs: disable oform module
2023-01-31 16:15:43 +03:00
44b0f4d53d php: There must not be a space after the opening parenthesis 2023-01-31 16:05:35 +03:00
70b63636e3 php: there must not be spaces around offset brace 2023-01-31 16:00:00 +03:00
8d4582e379 php: each statement must be indented 2023-01-31 15:54:07 +03:00
a1ec2cf366 php: remove trailing whitespace at the end of non-blank lines 2023-01-31 15:46:55 +03:00
4907e9d3c8 php: header comment needed 2023-01-31 15:43:37 +03:00
88f3d6da59 php: closing ?> tag must be omitted from files containing only PHP 2023-01-31 15:20:22 +03:00
481b111cb2 php: multi-line arrays must have a trailing comma 2023-01-31 15:14:01 +03:00
a1e13f3315 php: visibility must be declared on all methods 2023-01-31 14:58:18 +03:00
d1dd289c77 php: replace control structure alternative syntax to use braces 2023-01-31 14:52:04 +03:00
7b4e40c4e4 php: keyword elseif should be used instead of else if 2023-01-31 12:56:57 +03:00
6d4cad2215 php: curly opening braces after control structures and oop-structures on the same line 2023-01-31 12:31:33 +03:00
f43a4471ef php: whitespace after each comma in array declaration 2023-01-31 11:42:13 +03:00
0cf90e86c7 php: trim array spaces 2023-01-31 11:32:59 +03:00
406de99b01 php: single space or none should be between cast and variable 2023-01-31 10:30:26 +03:00
f4bcb15d33 php: each element of an array must be indented exactly once 2023-01-31 10:17:54 +03:00
d2a0164738 Merge branch 'refactor/linter-formatting' of https://github.com/ONLYOFFICE/document-server-integration into refactor/linter-formatting 2023-01-31 10:02:56 +03:00
a49ef4cc13 php: lower case for constants "true", "false" and "null" 2023-01-31 09:59:37 +03:00
3ca29cd402 Merge branch 'feature/deploy' into develop 2023-01-31 00:48:16 +05:00
c398b30e33 build: exclude packages from csharp examples 2023-01-31 00:45:02 +05:00
8caea9fab0 java: fix dockerfile path 2023-01-31 00:45:02 +05:00
f44c62540c php: lower case for constants "true", "false" and "null" 2023-01-30 17:33:48 +03:00
7644db80e3 php: no multiple statements per line 2023-01-30 17:26:31 +03:00
880497cd01 php: curly opening braces on the same line 2023-01-30 17:18:37 +03:00
34f8174d9d php: no mixed "print" and "echo" 2023-01-30 17:02:09 +03:00
99bc9d3fdf php: useless "else" deleted 2023-01-30 16:36:58 +03:00
165c292ab8 php: extra blank lines deleted 2023-01-30 16:26:04 +03:00
8fe41cd8e6 php: used short syntax for arrays 2023-01-30 15:23:00 +03:00
705ea097e2 php: used PSR-2 standart for linter 2023-01-30 14:56:32 +03:00
f4799bebb4 php: added needed dependencies 2023-01-30 14:42:05 +03:00
4ffa524de0 Merge pull request #336 from ONLYOFFICE/bugfix/java-dockerfile
java: fix dockerfile path
2023-01-30 13:16:21 +03:00
cd055317e0 java: fix dockerfile path 2023-01-30 09:46:27 +00:00
b1941c5980 Merge branch 'develop' of https://github.com/ONLYOFFICE/document-server-integration into develop 2023-01-30 08:58:52 +03:00
83bc0fed5e Merge remote-tracking branch 'remotes/origin/master' into develop 2023-01-27 18:54:25 +05:00
5620f49f8f Merge pull request #321 from ONLYOFFICE/dependabot/bundler/web/documentserver-example/ruby/loofah-2.19.1
build(deps): bump loofah from 2.19.0 to 2.19.1 in /web/documentserver-example/ruby
2023-01-27 11:53:41 +03:00
d9fefef834 Merge branch 'develop' into dependabot/bundler/web/documentserver-example/ruby/loofah-2.19.1 2023-01-27 10:40:40 +03:00
37591d847c Merge pull request #323 from ONLYOFFICE/dependabot/bundler/web/documentserver-example/ruby/rails-html-sanitizer-1.4.4
build(deps): bump rails-html-sanitizer from 1.4.3 to 1.4.4 in /web/documentserver-example/ruby
2023-01-26 17:36:27 +03:00
77290d88f3 build(deps): bump rails-html-sanitizer
Bumps [rails-html-sanitizer](https://github.com/rails/rails-html-sanitizer) from 1.4.3 to 1.4.4.
- [Release notes](https://github.com/rails/rails-html-sanitizer/releases)
- [Changelog](https://github.com/rails/rails-html-sanitizer/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rails/rails-html-sanitizer/compare/v1.4.3...v1.4.4)

---
updated-dependencies:
- dependency-name: rails-html-sanitizer
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-01-26 19:35:36 +05:00
6befd87761 Merge pull request #330 from ONLYOFFICE/dependabot/bundler/web/documentserver-example/ruby/rack-2.2.6.2
build(deps): bump rack from 2.2.4 to 2.2.6.2 in /web/documentserver-example/ruby
2023-01-26 17:13:57 +03:00
f3e270c1ad Merge pull request #332 from ONLYOFFICE/dependabot/bundler/web/documentserver-example/ruby/globalid-1.0.1
build(deps): bump globalid from 1.0.0 to 1.0.1 in /web/documentserver-example/ruby
2023-01-26 17:13:11 +03:00
f5f1e4b391 Merge pull request #333 from ONLYOFFICE/bugfix/saving-file
Bugfix/saving file
2023-01-26 15:20:30 +03:00
8ba389d02f Merge pull request #328 from ONLYOFFICE/bugfix/php-example-warnings
php: empty GET parameters warnings fixed
2023-01-25 22:33:06 +03:00
45910ff1f3 php: empty GET parameters warnings fixed
Empty GET-parameters "user", "directUrl",  "fileUrl", "fileExt" no longer give a warning, the example can work without them.
2023-01-26 00:11:03 +05:00
7ec969f4d9 ruby: check file availability when saving 2023-01-22 12:51:46 +05:00
c7e13ef8a8 python: check file availability when saving 2023-01-22 12:51:46 +05:00
3d488f89b2 java: check file availability when saving 2023-01-22 12:50:30 +05:00
cc00af1510 java-spring: check file availability when saving 2023-01-22 12:23:07 +05:00
f8aa55143c csharp: check file availability when saving 2023-01-22 02:16:20 +05:00
1b44c04893 csharp-mvc: check file availability when saving 2023-01-22 02:16:20 +05:00
1a51759154 build(deps): bump globalid in /web/documentserver-example/ruby
Bumps [globalid](https://github.com/rails/globalid) from 1.0.0 to 1.0.1.
- [Release notes](https://github.com/rails/globalid/releases)
- [Commits](https://github.com/rails/globalid/compare/v1.0.0...v1.0.1)

---
updated-dependencies:
- dependency-name: globalid
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-01-19 23:00:11 +00:00
8807328180 build(deps): bump rack in /web/documentserver-example/ruby
Bumps [rack](https://github.com/rack/rack) from 2.2.4 to 2.2.6.2.
- [Release notes](https://github.com/rack/rack/releases)
- [Changelog](https://github.com/rack/rack/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rack/rack/compare/2.2.4...v2.2.6.2)

---
updated-dependencies:
- dependency-name: rack
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-01-19 01:22:30 +00:00
ca49e5bdda build(deps): bump loofah in /web/documentserver-example/ruby
Bumps [loofah](https://github.com/flavorjones/loofah) from 2.19.0 to 2.19.1.
- [Release notes](https://github.com/flavorjones/loofah/releases)
- [Changelog](https://github.com/flavorjones/loofah/blob/main/CHANGELOG.md)
- [Commits](https://github.com/flavorjones/loofah/compare/v2.19.0...v2.19.1)

---
updated-dependencies:
- dependency-name: loofah
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-13 20:48:42 +00:00
47 changed files with 2432 additions and 1305 deletions

View File

@ -6,7 +6,7 @@ on:
branches: [master, main]
paths: ['web/documentserver-example/java/**']
pull_request:
branches: [master, main, develop]
branches: [master, main]
paths: ['web/documentserver-example/java/**']
jobs:

View File

@ -6,7 +6,7 @@ on:
branches: [master, main]
paths: ['web/documentserver-example/nodejs/**']
pull_request:
branches: [master, main, develop]
branches: [master, main]
paths: ['web/documentserver-example/nodejs/**']
env:

View File

@ -6,7 +6,7 @@ on:
branches: [master, main]
paths: ['web/documentserver-example/php/**']
pull_request:
branches: [master, main, develop]
branches: [master, main]
paths: ['web/documentserver-example/php/**']
jobs:
@ -22,8 +22,10 @@ jobs:
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.1'
php-version: '8.2'
tools: cs2pr, phpcs
- name: Run phpcs
run: phpcs -q --extensions=php,module,inc,install,test,profile,theme,css,info,txt,md,yml --ignore=node_modules,bower_components,vendor ./
run: |
phpcs --version
phpcs -q --extensions=php,module,inc,install,test,profile,theme,info --ignore=node_modules,bower_components,vendor,css,js,lib --standard=./ruleset.xml ./

View File

@ -6,7 +6,7 @@ on:
branches: [master, main]
paths: ['web/documentserver-example/python/**']
pull_request:
branches: [master, main, develop]
branches: [master, main]
paths: ['web/documentserver-example/python/**']
jobs:

View File

@ -6,7 +6,7 @@ on:
branches: [master, main]
paths: ['web/documentserver-example/ruby/**']
pull_request:
branches: [master, main, develop]
branches: [master, main]
paths: ['web/documentserver-example/ruby/**']
jobs:

View File

@ -6,7 +6,7 @@ on:
branches: [master, main]
paths: ['web/documentserver-example/java-spring/**']
pull_request:
branches: [master, main, develop]
branches: [master, main]
paths: ['web/documentserver-example/java-spring/**']
jobs:

View File

@ -250,6 +250,14 @@ jQuery.UI - jQuery UI is an open source library of interface components —
License: MIT
License File: jQuery.UI.license
JWT - JSON Web Token implementation (https://github.com/firebase/php-jwt/blob/master/LICENSE)
License: BSD-3-Clause
License File: jwt.license
PHP_CodeSniffer - PHP_CodeSniffer is a set of two PHP scripts; the main phpcs script that tokenizes PHP, JavaScript and CSS files to detect violations of a defined coding standard, and a second phpcbf script to automatically correct coding standard violations. PHP_CodeSniffer is an essential development tool that ensures your code remains clean and consistent. (https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt)
License: BSD-3-Clause
License File: PHP_CodeSniffer.license
web/documentserver-example/ruby

View File

@ -1,5 +1,7 @@
# Change Log
- php: linter refactoring
## 1.5.0
- nodejs: added wopi putRelativeFile action
- nodejs: wopi editnew action for exisiting file

View File

@ -26,13 +26,13 @@
<RemoveDir Directories="$(To)" ContinueOnError="true" />
<ItemGroup>
<ZipFilesCSharp Include="$(DirCSharp)**" Exclude="$(DirCSharp)obj\**;$(DirCSharp)**\.git" />
<ZipFilesCSharp Include="$(DirCSharp)**" Exclude="$(DirCSharp).vs\**;$(DirCSharp)bin\*.pdb;$(DirCSharp)bin\*.xml;$(DirCSharp)obj\**;$(DirCSharp)packages\**;$(DirCSharp)**\.git" />
</ItemGroup>
<Copy SourceFiles="@(ZipFilesCSharp)" DestinationFiles="@(ZipFilesCSharp->'$(NameCSharp)\%(RecursiveDir)%(Filename)%(Extension)')" />
<Zip Files="$(NameCSharp)" WorkingDirectory="$(To)" ZipFileName="$(NameCSharp).zip" />
<ItemGroup>
<ZipFilesMVC Include="$(DirMvc)**" Exclude="$(DirMvc)obj\**;$(DirMvc)**\.git" />
<ZipFilesMVC Include="$(DirMvc)**" Exclude="$(DirMvc).vs\**;$(DirMvc)bin\*.pdb;$(DirMvc)bin\*.xml;$(DirMvc)obj\**;$(DirMvc)packages\**;$(DirMvc)**\.git" />
</ItemGroup>
<Copy SourceFiles="@(ZipFilesMVC)" DestinationFiles="@(ZipFilesMVC->'$(NameMvc)\%(RecursiveDir)%(Filename)%(Extension)')" />
<Zip Files="$(NameMvc)" WorkingDirectory="$(To)" ZipFileName="$(NameMvc).zip" />

View File

@ -128,37 +128,48 @@ namespace OnlineEditorsExampleMVC.Helpers
DocManagerHelper.VerifySSL();
var storagePath = DocManagerHelper.StoragePath(newFileName, userAddress); // get the file path
var histDir = DocManagerHelper.HistoryDir(storagePath); // get the path to the history directory
if (!Directory.Exists(histDir)) Directory.CreateDirectory(histDir);
var versionDir = DocManagerHelper.VersionDir(histDir, DocManagerHelper.GetFileVersion(histDir)); // get the path to the file version
if (!Directory.Exists(versionDir)) Directory.CreateDirectory(versionDir); // if the path doesn't exist, create it
// get the path to the previous file version and move it to the storage directory
File.Move(DocManagerHelper.StoragePath(fileName, userAddress), Path.Combine(versionDir, "prev" + curExt));
DownloadToFile(downloadUri, storagePath); // save file to the storage directory
DownloadToFile((string)fileData["changesurl"], Path.Combine(versionDir, "diff.zip")); // save file changes to the diff.zip archive
var hist = fileData.ContainsKey("changeshistory") ? (string)fileData["changeshistory"] : null;
if (string.IsNullOrEmpty(hist) && fileData.ContainsKey("history"))
try
{
var jss = new JavaScriptSerializer();
hist = jss.Serialize(fileData["history"]);
}
var bytesFile = DownloadFile(downloadUri); // download document file
var storagePath = DocManagerHelper.StoragePath(newFileName, userAddress); // get the file path
if (!string.IsNullOrEmpty(hist))
var histDir = DocManagerHelper.HistoryDir(storagePath); // get the path to the history directory
if (!Directory.Exists(histDir)) Directory.CreateDirectory(histDir);
var versionDir = DocManagerHelper.VersionDir(histDir, DocManagerHelper.GetFileVersion(histDir)); // get the path to the file version
if (!Directory.Exists(versionDir)) Directory.CreateDirectory(versionDir); // if the path doesn't exist, create it
// get the path to the previous file version and move it to the storage directory
File.Move(DocManagerHelper.StoragePath(fileName, userAddress), Path.Combine(versionDir, "prev" + curExt));
SaveFile(bytesFile, storagePath);// save document file
byte[] bytesChanges = DownloadFile((string)fileData["changesurl"]); // download changes file
SaveFile(bytesChanges, Path.Combine(versionDir, "diff.zip")); // save file changes to the diff.zip archive
var hist = fileData.ContainsKey("changeshistory") ? (string)fileData["changeshistory"] : null;
if (string.IsNullOrEmpty(hist) && fileData.ContainsKey("history"))
{
var jss = new JavaScriptSerializer();
hist = jss.Serialize(fileData["history"]);
}
if (!string.IsNullOrEmpty(hist))
{
File.WriteAllText(Path.Combine(versionDir, "changes.json"), hist); // write the history changes to the changes.json file
}
File.WriteAllText(Path.Combine(versionDir, "key.txt"), (string)fileData["key"]); // write the key value to the key.txt file
string forcesavePath = DocManagerHelper.ForcesavePath(newFileName, userAddress, false); // get the path to the forcesaved file version
if (!forcesavePath.Equals("")) // if the forcesaved file version exists
{
File.Delete(forcesavePath); // remove it
}
} catch (Exception)
{
File.WriteAllText(Path.Combine(versionDir, "changes.json"), hist); // write the history changes to the changes.json file
}
File.WriteAllText(Path.Combine(versionDir, "key.txt"), (string)fileData["key"]); // write the key value to the key.txt file
string forcesavePath = DocManagerHelper.ForcesavePath(newFileName, userAddress, false); // get the path to the forcesaved file version
if (!forcesavePath.Equals("")) // if the forcesaved file version exists
{
File.Delete(forcesavePath); // remove it
return 1;
}
return 0;
@ -202,43 +213,51 @@ namespace OnlineEditorsExampleMVC.Helpers
}
DocManagerHelper.VerifySSL();
string forcesavePath = "";
Boolean isSubmitForm = fileData["forcesavetype"].ToString().Equals("3"); // SubmitForm
if (isSubmitForm) // if the form is submitted
try
{
if (newFileName)
var bytesFile = DownloadFile(downloadUri); // download document file
string forcesavePath = "";
Boolean isSubmitForm = fileData["forcesavetype"].ToString().Equals("3"); // SubmitForm
if (isSubmitForm) // if the form is submitted
{
fileName = DocManagerHelper.GetCorrectName(Path.GetFileNameWithoutExtension(fileName) + "-form" + downloadExt, userAddress); // get the correct file name if it already exists
if (newFileName)
{
fileName = DocManagerHelper.GetCorrectName(Path.GetFileNameWithoutExtension(fileName) + "-form" + downloadExt, userAddress); // get the correct file name if it already exists
} else
{
fileName = DocManagerHelper.GetCorrectName(Path.GetFileNameWithoutExtension(fileName) + "-form" + curExt, userAddress);
{
fileName = DocManagerHelper.GetCorrectName(Path.GetFileNameWithoutExtension(fileName) + "-form" + curExt, userAddress);
}
forcesavePath = DocManagerHelper.StoragePath(fileName, userAddress);
}
forcesavePath = DocManagerHelper.StoragePath(fileName, userAddress);
}
else
{
if (newFileName)
else
{
fileName = DocManagerHelper.GetCorrectName(Path.GetFileNameWithoutExtension(fileName) + downloadExt, userAddress);
}
forcesavePath = DocManagerHelper.ForcesavePath(fileName, userAddress, false);
if (newFileName)
{
fileName = DocManagerHelper.GetCorrectName(Path.GetFileNameWithoutExtension(fileName) + downloadExt, userAddress);
}
forcesavePath = DocManagerHelper.ForcesavePath(fileName, userAddress, false);
if (string.IsNullOrEmpty(forcesavePath)) // create forcesave path if it doesn't exist
{
forcesavePath = DocManagerHelper.ForcesavePath(fileName, userAddress, true);
{
forcesavePath = DocManagerHelper.ForcesavePath(fileName, userAddress, true);
}
}
}
DownloadToFile(downloadUri, forcesavePath);
SaveFile(bytesFile, forcesavePath);// save document file
if (isSubmitForm)
if (isSubmitForm)
{
var jss = new JavaScriptSerializer();
var actions = jss.Deserialize<List<object>>(jss.Serialize(fileData["actions"]));
var action = jss.Deserialize<Dictionary<string, object>>(jss.Serialize(actions[0]));
var user = action["userid"].ToString(); // get the user id
DocManagerHelper.CreateMeta(fileName, user, "Filling Form", userAddress); // create meta data for the forcesaved file
}
} catch (Exception)
{
var jss = new JavaScriptSerializer();
var actions = jss.Deserialize<List<object>>(jss.Serialize(fileData["actions"]));
var action = jss.Deserialize<Dictionary<string, object>>(jss.Serialize(actions[0]));
var user = action["userid"].ToString(); // get the user id
DocManagerHelper.CreateMeta(fileName, user, "Filling Form", userAddress); // create meta data for the forcesaved file
return 1;
}
return 0;
@ -310,27 +329,30 @@ namespace OnlineEditorsExampleMVC.Helpers
}
}
// save file
private static void SaveFile(byte[] data, string path)
{
using (var fs = File.Open(path, FileMode.Create))
{
fs.Write(data, 0, data.Length);
}
}
// save file information from the url to the file specified
private static void DownloadToFile(string url, string path)
private static byte[] DownloadFile(string url)
{
if (string.IsNullOrEmpty(url)) throw new ArgumentException("url"); // url isn't specified
if (string.IsNullOrEmpty(path)) throw new ArgumentException("path"); // file isn't specified
var req = (HttpWebRequest)WebRequest.Create(url);
req.Timeout = 5000;
using (var stream = req.GetResponse().GetResponseStream()) // get input stream of the file information from the url
{
if (stream == null) throw new Exception("stream is null");
const int bufferSize = 4096;
using (var fs = File.Open(path, FileMode.Create))
using (MemoryStream memoryStream = new MemoryStream())
{
var buffer = new byte[bufferSize];
int readed;
while ((readed = stream.Read(buffer, 0, bufferSize)) != 0)
{
fs.Write(buffer, 0, readed); // write bytes to the output stream
}
stream.CopyTo(memoryStream);
return memoryStream.ToArray();
}
}
}

View File

@ -461,20 +461,21 @@ namespace OnlineEditorsExampleMVC
var userAddress = context.Request["userAddress"];
var isEmbedded = context.Request["dmode"];
if (JwtManager.Enabled && isEmbedded == null)
if (JwtManager.Enabled && isEmbedded == null && userAddress != null)
{
string JWTheader = string.IsNullOrEmpty(WebConfigurationManager.AppSettings["files.docservice.header"]) ? "Authorization" : WebConfigurationManager.AppSettings["files.docservice.header"];
string token = "";
if (context.Request.Headers.AllKeys.Contains(JWTheader, StringComparer.InvariantCultureIgnoreCase))
{
var headerToken = context.Request.Headers.Get(JWTheader).Substring("Bearer ".Length);
string token = JwtManager.Decode(headerToken);
if (string.IsNullOrEmpty(token))
{
context.Response.StatusCode = (int)HttpStatusCode.Forbidden;
context.Response.Write("JWT validation failed");
return;
}
token = JwtManager.Decode(headerToken);
}
if (string.IsNullOrEmpty(token))
{
context.Response.StatusCode = (int)HttpStatusCode.Forbidden;
context.Response.Write("JWT validation failed");
return;
}
}

View File

@ -130,37 +130,48 @@ namespace OnlineEditorsExample
_Default.VerifySSL();
var storagePath = _Default.StoragePath(newFileName, userAddress); // get the file path
var histDir = _Default.HistoryDir(storagePath); // get the path to the history directory
if (!Directory.Exists(histDir)) Directory.CreateDirectory(histDir);
var versionDir = _Default.VersionDir(histDir, _Default.GetFileVersion(histDir)); // get the path to the file version
if (!Directory.Exists(versionDir)) Directory.CreateDirectory(versionDir); // if the path doesn't exist, create it
// get the path to the previous file version and rename the storage path with it
File.Copy(_Default.StoragePath(fileName, userAddress), Path.Combine(versionDir, "prev" + curExt));
DownloadToFile(downloadUri, storagePath); // save file to the storage directory
DownloadToFile((string)fileData["changesurl"], Path.Combine(versionDir, "diff.zip")); // save file changes to the diff.zip archive
var hist = fileData.ContainsKey("changeshistory") ? (string)fileData["changeshistory"] : null;
if (string.IsNullOrEmpty(hist) && fileData.ContainsKey("history"))
try
{
var jss = new JavaScriptSerializer();
hist = jss.Serialize(fileData["history"]);
}
var bytesFile = DownloadFile(downloadUri); // download document file
var storagePath = _Default.StoragePath(newFileName, userAddress); // get the file path
if (!string.IsNullOrEmpty(hist))
{
File.WriteAllText(Path.Combine(versionDir, "changes.json"), hist); // write the history changes to the changes.json file
}
var histDir = _Default.HistoryDir(storagePath); // get the path to the history directory
if (!Directory.Exists(histDir)) Directory.CreateDirectory(histDir);
File.WriteAllText(Path.Combine(versionDir, "key.txt"), (string)fileData["key"]); // write the key value to the key.txt file
var versionDir = _Default.VersionDir(histDir, _Default.GetFileVersion(histDir)); // get the path to the file version
if (!Directory.Exists(versionDir)) Directory.CreateDirectory(versionDir); // if the path doesn't exist, create it
string forcesavePath = _Default.ForcesavePath(newFileName, userAddress, false); // get the path to the forcesaved file version
// get the path to the previous file version and rename the storage path with it
File.Copy(_Default.StoragePath(fileName, userAddress), Path.Combine(versionDir, "prev" + curExt));
SaveFile(bytesFile, storagePath);// save document file
var bytesChanges = DownloadFile((string)fileData["changesurl"]); // download changes file
SaveFile(bytesChanges, Path.Combine(versionDir, "diff.zip")); // save file changes to the diff.zip archive
var hist = fileData.ContainsKey("changeshistory") ? (string)fileData["changeshistory"] : null;
if (string.IsNullOrEmpty(hist) && fileData.ContainsKey("history"))
{
var jss = new JavaScriptSerializer();
hist = jss.Serialize(fileData["history"]);
}
if (!string.IsNullOrEmpty(hist))
{
File.WriteAllText(Path.Combine(versionDir, "changes.json"), hist); // write the history changes to the changes.json file
}
File.WriteAllText(Path.Combine(versionDir, "key.txt"), (string)fileData["key"]); // write the key value to the key.txt file
string forcesavePath = _Default.ForcesavePath(newFileName, userAddress, false); // get the path to the forcesaved file version
if (!string.IsNullOrEmpty(forcesavePath)) // if the forcesaved file version exists
{
File.Delete(forcesavePath); // remove it
}
}
catch (Exception)
{
File.Delete(forcesavePath); // remove it
return 1;
}
return 0;
@ -205,43 +216,51 @@ namespace OnlineEditorsExample
_Default.VerifySSL();
string forcesavePath = "";
Boolean isSubmitForm = fileData["forcesavetype"].ToString().Equals("3"); // SubmitForm
if (isSubmitForm) // if the form is submitted
try
{
if (newFileName)
var bytesFile = DownloadFile(downloadUri); // download document file
string forcesavePath = "";
Boolean isSubmitForm = fileData["forcesavetype"].ToString().Equals("3"); // SubmitForm
if (isSubmitForm) // if the form is submitted
{
fileName = _Default.GetCorrectName(Path.GetFileNameWithoutExtension(fileName) + "-form" + downloadExt, userAddress); // get the correct file name if it already exists
if (newFileName)
{
fileName = _Default.GetCorrectName(Path.GetFileNameWithoutExtension(fileName) + "-form" + downloadExt, userAddress); // get the correct file name if it already exists
} else
{
fileName = _Default.GetCorrectName(Path.GetFileNameWithoutExtension(fileName) + "-form" + curExt, userAddress);
{
fileName = _Default.GetCorrectName(Path.GetFileNameWithoutExtension(fileName) + "-form" + curExt, userAddress);
}
forcesavePath = _Default.StoragePath(fileName, userAddress);
}
forcesavePath = _Default.StoragePath(fileName, userAddress);
}
else
{
if (newFileName)
else
{
fileName = _Default.GetCorrectName(Path.GetFileNameWithoutExtension(fileName) + downloadExt, userAddress);
}
if (newFileName)
{
fileName = _Default.GetCorrectName(Path.GetFileNameWithoutExtension(fileName) + downloadExt, userAddress);
}
forcesavePath = _Default.ForcesavePath(fileName, userAddress, false);
forcesavePath = _Default.ForcesavePath(fileName, userAddress, false);
if (string.IsNullOrEmpty(forcesavePath)) // create forcesave path if it doesn't exist
{
forcesavePath = _Default.ForcesavePath(fileName, userAddress, true);
}
}
SaveFile(bytesFile, forcesavePath);// save document file
if (isSubmitForm)
{
forcesavePath = _Default.ForcesavePath(fileName, userAddress, true);
var jss = new JavaScriptSerializer();
var actions = jss.Deserialize<List<object>>(jss.Serialize(fileData["actions"]));
var action = jss.Deserialize<Dictionary<string, object>>(jss.Serialize(actions[0]));
var user = action["userid"].ToString(); // get the user id
DocEditor.CreateMeta(fileName, user, "Filling Form", userAddress); // create meta data for the forcesaved file
}
}
DownloadToFile(downloadUri, forcesavePath);
if (isSubmitForm)
catch (Exception)
{
var jss = new JavaScriptSerializer();
var actions = jss.Deserialize<List<object>>(jss.Serialize(fileData["actions"]));
var action = jss.Deserialize<Dictionary<string, object>>(jss.Serialize(actions[0]));
var user = action["userid"].ToString(); // get the user id
DocEditor.CreateMeta(fileName, user, "Filling Form", userAddress); // create meta data for the forcesaved file
return 1;
}
return 0;
@ -313,27 +332,29 @@ namespace OnlineEditorsExample
}
}
private static void SaveFile(byte[] data, string path)
{
using (var fs = File.Open(path, FileMode.Create))
{
fs.Write(data, 0, data.Length);
}
}
// save file information from the url to the file specified
private static void DownloadToFile(string url, string path)
private static byte[] DownloadFile(string url)
{
if (string.IsNullOrEmpty(url)) throw new ArgumentException("url"); // url isn't specified
if (string.IsNullOrEmpty(path)) throw new ArgumentException("path"); // file isn't specified
var req = (HttpWebRequest)WebRequest.Create(url);
req.Timeout = 5000;
using (var stream = req.GetResponse().GetResponseStream()) // get input stream of the file information from the url
{
if (stream == null) throw new Exception("stream is null");
const int bufferSize = 4096;
using (var fs = File.Open(path, FileMode.Create))
using (MemoryStream memoryStream = new MemoryStream())
{
var buffer = new byte[bufferSize];
int readed;
while ((readed = stream.Read(buffer, 0, bufferSize)) != 0)
{
fs.Write(buffer, 0, readed); // write bytes to the output stream
}
stream.CopyTo(memoryStream);
return memoryStream.ToArray();
}
}
}

View File

@ -281,21 +281,21 @@ namespace OnlineEditorsExample
var userAddress = Path.GetFileName(context.Request["userAddress"]);
var isEmbedded = context.Request["dmode"];
if (JwtManager.Enabled && isEmbedded == null)
if (JwtManager.Enabled && isEmbedded == null && userAddress != null)
{
string JWTheader = string.IsNullOrEmpty(WebConfigurationManager.AppSettings["files.docservice.header"]) ? "Authorization" : WebConfigurationManager.AppSettings["files.docservice.header"];
string token = "";
if (context.Request.Headers.AllKeys.Contains(JWTheader, StringComparer.InvariantCultureIgnoreCase))
{
var headerToken = context.Request.Headers.Get(JWTheader).Substring("Bearer ".Length);
string token = JwtManager.Decode(headerToken);
if (string.IsNullOrEmpty(token))
{
context.Response.StatusCode = (int)HttpStatusCode.Forbidden;
context.Response.Write("JWT validation failed");
return;
}
token = JwtManager.Decode(headerToken);
}
if (string.IsNullOrEmpty(token))
{
context.Response.StatusCode = (int)HttpStatusCode.Forbidden;
context.Response.Write("JWT validation failed");
return;
}
}

View File

@ -35,6 +35,14 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>

View File

@ -0,0 +1,37 @@
/**
*
* (c) Copyright Ascensio System SIA 2023
*
* 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.
*
*/
package com.onlyoffice.integration.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.SecurityFilterChain;
@Configuration
public class SecurityConfig {
@Bean
SecurityFilterChain filterChain(final HttpSecurity http) throws Exception {
return http
.requiresChannel(channel -> channel.anyRequest().requiresSecure())
.authorizeRequests(authorize -> authorize.anyRequest().permitAll())
.build();
}
}

View File

@ -285,16 +285,19 @@ public class FileController {
@GetMapping(path = "${url.download}")
public ResponseEntity<Resource> download(final HttpServletRequest request, // download a file
@RequestParam("fileName") final String fileName) {
@RequestParam("fileName") final String fileName,
@RequestParam(value = "userAddress", required = false) final String userAddress){
try {
// check if a token is enabled or not
if (jwtManager.tokenEnabled()) {
String header = request.getHeader(documentJwtHeader == null // get the document JWT header
if (jwtManager.tokenEnabled() && userAddress != null) {
String header = request.getHeader(documentJwtHeader == null // get the document JWT header
|| documentJwtHeader.isEmpty() ? "Authorization" : documentJwtHeader);
if (header != null && !header.isEmpty()) {
String token = header
.replace("Bearer ", ""); // token is the header without the Bearer prefix
jwtManager.readToken(token); // read the token
} else {
return null;
}
}
return downloadFile(fileName); // download data from the specified file

View File

@ -35,6 +35,7 @@ import org.springframework.context.annotation.Primary;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.InputStream;
import java.io.OutputStream;
@ -75,14 +76,12 @@ public class DefaultCallbackManager implements CallbackManager {
@Autowired
private ServiceConverter serviceConverter;
// save file information from the URL to the file specified
private void downloadToFile(final String url, final Path path) throws Exception {
// download file from url
@SneakyThrows
private byte[] getDownloadFile(final String url) {
if (url == null || url.isEmpty()) {
throw new RuntimeException("Url argument is not specified"); // URL isn't specified
}
if (path == null) {
throw new RuntimeException("Path argument is not specified"); // file isn't specified
}
URL uri = new URL(url);
java.net.HttpURLConnection connection = (java.net.HttpURLConnection) uri.openConnection();
@ -100,7 +99,17 @@ public class DefaultCallbackManager implements CallbackManager {
throw new RuntimeException("Input stream is null");
}
storageMutator.createOrUpdateFile(path, stream); // update a file or create a new one
return stream.readAllBytes();
}
// file saving
@SneakyThrows
private void saveFile(final byte[] byteArray, final Path path) {
if (path == null) {
throw new RuntimeException("Path argument is not specified"); // file isn't specified
}
// update a file or create a new one
storageMutator.createOrUpdateFile(path, new ByteArrayInputStream(byteArray));
}
@SneakyThrows
@ -134,6 +143,8 @@ public class DefaultCallbackManager implements CallbackManager {
}
}
byte[] byteArrayFile = getDownloadFile(downloadUri); // download document file
String storagePath = storagePathBuilder.getFileLocation(newFileName); // get the path to a new file
Path lastVersion = Paths.get(storagePathBuilder
.getFileLocation(fileName)); // get the path to the last file version
@ -152,12 +163,11 @@ public class DefaultCallbackManager implements CallbackManager {
storageMutator.createDirectory(ver); // create the file version directory
// move the last file version to the file version directory with the "prev" postfix
storageMutator.moveFile(lastVersion, Paths.get(versionDir + File.separator + "prev" + curExt));
saveFile(byteArrayFile, toSave); // save document file
downloadToFile(downloadUri, toSave); // save file to the storage path
downloadToFile(changesUri, Path
.of(versionDir + File.separator + "diff.zip")); // save file changes to the diff.zip archive
byte[] byteArrayChanges = getDownloadFile(changesUri); // download file changes
saveFile(byteArrayChanges, Path
.of(versionDir + File.separator + "diff.zip")); // save file changes to the diff.zip archive
JSONObject jsonChanges = new JSONObject(); // create a json object for document changes
jsonChanges.put("changes", body.getHistory().getChanges()); // put the changes to the json object
@ -246,8 +256,8 @@ public class DefaultCallbackManager implements CallbackManager {
break;
default:
throw new RuntimeException(response.toJSONString());
}
}
}
@SneakyThrows
public void processForceSave(final Track body, final String fileNameParam) { // file force saving process
@ -278,6 +288,7 @@ public class DefaultCallbackManager implements CallbackManager {
}
}
byte[] byteArrayFile = getDownloadFile(downloadUri); // download document file
String forcesavePath = "";
// todo: Use ENUMS
@ -313,6 +324,6 @@ public class DefaultCallbackManager implements CallbackManager {
}
}
downloadToFile(downloadUri, Path.of(forcesavePath));
saveFile(byteArrayFile, Path.of(forcesavePath));
}
}

View File

@ -20,6 +20,7 @@ package com.onlyoffice.integration.documentserver.storage;
import org.springframework.core.io.Resource;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.InputStream;
import java.nio.file.Path;
@ -37,5 +38,5 @@ public interface FileStorageMutator {
Resource loadFileAsResourceHistory(String fileName, String version, String file); // load file as a resource
File[] getStoredFiles(); // get a collection of all the stored files
void createMeta(String fileName, String uid, String uname); // create the file meta information
boolean createOrUpdateFile(Path path, InputStream stream); // create or update a file
boolean createOrUpdateFile(Path path, ByteArrayInputStream stream); // create or update a file
}

View File

@ -31,6 +31,7 @@ import org.springframework.stereotype.Component;
import org.springframework.util.FileSystemUtils;
import javax.servlet.http.HttpServletRequest;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
@ -332,7 +333,7 @@ public class LocalFileStorage implements FileStorageMutator, FileStoragePathBuil
}
// create or update a file
public boolean createOrUpdateFile(final Path path, final InputStream stream) {
public boolean createOrUpdateFile(final Path path, final ByteArrayInputStream stream) {
if (!Files.exists(path)) { // if the specified file does not exist
return createFile(path, stream); // create it in the specified directory
} else {
@ -372,7 +373,7 @@ public class LocalFileStorage implements FileStorageMutator, FileStoragePathBuil
path = Paths.get(historyPath); // otherwise, get the path to the history directory
if (!Files.exists(path)) {
return 1; // if the history directory does not exist, then the file version is 1
}
}
}
// run through all the files in the history directory

View File

@ -1,7 +1,11 @@
server.version=1.5.0
server.address=
server.port=4000
server.port=8443
server.ssl.key-store=classpath:springboot.p12
server.ssl.key-store-password=111111
server.ssl.key-alias=springboot
server.ssl.key-password=111111
filesize-max=5242880

View File

@ -1,6 +1,5 @@
FROM maven:3.6.1-jdk-8-alpine AS MVN_BLDR
COPY pom.xml /tmp/
COPY src /tmp/src/
COPY ./ /tmp/
WORKDIR /tmp/
RUN mvn package

View File

@ -517,22 +517,23 @@ public class IndexServlet extends HttpServlet {
String userAddress = request.getParameter("userAddress");
String isEmbedded = request.getParameter("dmode");
if (DocumentManager.tokenEnabled() && isEmbedded == null) {
if (DocumentManager.tokenEnabled() && isEmbedded == null && userAddress != null) {
String documentJwtHeader = ConfigManager.getProperty("files.docservice.header");
String header = (String) request.getHeader(documentJwtHeader == null || documentJwtHeader.isEmpty()
? "Authorization" : documentJwtHeader);
String token = "";
if (header != null && !header.isEmpty()) {
String bearerPrefix = "Bearer ";
String token = header.startsWith(bearerPrefix) ? header.substring(bearerPrefix.length()) : header;
try {
Verifier verifier = HMACVerifier.newVerifier(DocumentManager.getTokenSecret());
JWT jwt = JWT.getDecoder().decode(token, verifier);
} catch (Exception e) {
response.sendError(HttpServletResponse.SC_FORBIDDEN, "JWT validation failed");
return;
}
token = header.startsWith(bearerPrefix) ? header.substring(bearerPrefix.length()) : header;
}
try {
Verifier verifier = HMACVerifier.newVerifier(DocumentManager.getTokenSecret());
JWT jwt = JWT.getDecoder().decode(token, verifier);
} catch (Exception e) {
response.sendError(HttpServletResponse.SC_FORBIDDEN, "JWT validation failed");
return;
}
}

View File

@ -26,19 +26,26 @@ import org.primeframework.jwt.domain.JWT;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.InputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Scanner;
import static utils.Constants.BUFFER_SIZE;
import static utils.Constants.FILE_SAVE_TIMEOUT;
import static utils.Constants.KILOBYTE_SIZE;
@ -167,6 +174,8 @@ public final class TrackManager {
}
}
byte[] byteArrayFile = getDownloadFile(downloadUri); // download document file
String storagePath = DocumentManager.storagePath(newFileName, userAddress); // get the file path
File histDir = new File(DocumentManager.historyDir(storagePath)); // get the path to the history direction
if (!histDir.exists()) {
@ -177,7 +186,7 @@ public final class TrackManager {
.getFileVersion(histDir.getAbsolutePath())); // get the path to the file version
File ver = new File(versionDir);
File lastVersion = new File(DocumentManager.storagePath(fileName, userAddress));
File toSave = new File(storagePath);
Path toSave = Paths.get(storagePath);
if (!ver.exists()) {
ver.mkdirs();
@ -186,10 +195,10 @@ public final class TrackManager {
// get the path to the previous file version and rename the last file version with it
lastVersion.renameTo(new File(versionDir + File.separator + "prev" + curExt));
downloadToFile(downloadUri, toSave); // save file to the storage path
saveFile(byteArrayFile, toSave); // save document file
// save file changes to the diff.zip archive
downloadToFile(changesUri, new File(versionDir + File.separator + "diff.zip"));
byte[] byteArrayChanges = getDownloadFile(changesUri);
saveFile(byteArrayChanges, Paths.get(versionDir + File.separator + "diff.zip"));
String history = (String) body.get("changeshistory");
if (history == null && body.containsKey("history")) {
@ -248,6 +257,7 @@ public final class TrackManager {
}
}
byte[] byteArrayFile = getDownloadFile(downloadUri); // download document file
String forcesavePath = "";
boolean isSubmitForm = body.get("forcesavetype").toString().equals("3"); // SubmitForm
@ -274,8 +284,7 @@ public final class TrackManager {
}
}
File toSave = new File(forcesavePath);
downloadToFile(downloadUri, toSave);
saveFile(byteArrayFile, Paths.get(forcesavePath));
if (isSubmitForm) {
JSONArray actions = (JSONArray) body.get("actions");
@ -287,43 +296,79 @@ public final class TrackManager {
}
}
// save file information from the url to the file specified
private static void downloadToFile(final String url, final File file) throws Exception {
if (url == null || url.isEmpty()) {
throw new Exception("argument url"); // url isn't specified
// create a new file if it does not exist
private static boolean createFile(final byte[] byteArray, final Path path) {
if (Files.exists(path)) {
return true;
}
if (file == null) {
throw new Exception("argument path"); // file isn't specified
try (ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArray)) {
File file = Files.createFile(path).toFile(); // create a new file in the specified path
try (FileOutputStream out = new FileOutputStream(file)) {
int read;
final byte[] bytes = new byte[KILOBYTE_SIZE];
while ((read = byteArrayInputStream.read(bytes)) != -1) {
out.write(bytes, 0, read); // write bytes to the output stream
}
out.flush(); // force write data to the output stream that can be cached in the current thread
}
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
// get byte array from stream
private static byte[] getAllBytes(final InputStream is) throws IOException {
ByteArrayOutputStream os = new ByteArrayOutputStream();
byte[] buffer = new byte[BUFFER_SIZE];
for (int len = is.read(buffer); len != -1; len = is.read(buffer)) {
os.write(buffer, 0, len);
}
return os.toByteArray();
}
// save file
private static boolean saveFile(final byte[] byteArray, final Path path) {
if (path == null) {
throw new RuntimeException("Path argument is not specified"); // file isn't specified
}
if (!Files.exists(path)) { // if the specified file does not exist
return createFile(byteArray, path); // create it in the specified directory
} else {
try {
Files.write(path, byteArray); // otherwise, write new information in the bytes format to the file
return true;
} catch (IOException e) {
e.printStackTrace();
}
}
return false;
}
// download file from url
private static byte[] getDownloadFile(final String url) throws Exception {
if (url == null || url.isEmpty()) {
throw new RuntimeException("Url argument is not specified"); // URL isn't specified
}
URL uri = new URL(url);
java.net.HttpURLConnection connection = (java.net.HttpURLConnection) uri.openConnection();
connection.setConnectTimeout(FILE_SAVE_TIMEOUT);
InputStream stream = connection.getInputStream(); // get input stream of the file information from the URL
int statusCode = connection.getResponseCode();
if (statusCode != HttpServletResponse.SC_OK) { // checking status code
connection.disconnect();
throw new RuntimeException("Document editing service returned status: " + statusCode);
}
InputStream stream = connection.getInputStream(); // get input stream of the file information from the url
if (stream == null) {
throw new Exception("Stream is null");
connection.disconnect();
throw new RuntimeException("Input stream is null");
}
try (FileOutputStream out = new FileOutputStream(file)) {
int read;
final byte[] bytes = new byte[KILOBYTE_SIZE];
while ((read = stream.read(bytes)) != -1) {
out.write(bytes, 0, read); // write bytes to the output stream
}
// force write data to the output stream that can be cached in the current thread
out.flush();
}
connection.disconnect();
return getAllBytes(stream);
}
// create a command request

View File

@ -26,6 +26,7 @@ public final class Constants {
public static final Integer FILE_SAVE_TIMEOUT = 5000;
public static final Integer MAX_KEY_LENGTH = 20;
public static final Integer KILOBYTE_SIZE = 1024;
public static final Integer BUFFER_SIZE = 0xFFFF;
private Constants() { }
}

View File

@ -21,5 +21,9 @@ License: MIT
License File: jQuery.UI.license
JWT - JSON Web Token implementation (https://github.com/firebase/php-jwt/blob/master/LICENSE)
License: BSD
License: BSD-3-Clause
License File: jwt.license
PHP_CodeSniffer - PHP_CodeSniffer is a set of two PHP scripts; the main phpcs script that tokenizes PHP, JavaScript and CSS files to detect violations of a defined coding standard, and a second phpcbf script to automatically correct coding standard violations. PHP_CodeSniffer is an essential development tool that ensures your code remains clean and consistent. (https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt)
License: BSD-3-Clause
License File: PHP_CodeSniffer.license

View File

@ -1,6 +1,5 @@
<?php
/**
*
* (c) Copyright Ascensio System SIA 2023
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -14,52 +13,66 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
require( dirname(__FILE__) . '/config.php' );
// check if the request is an AJAX request
function is_ajax() {
return isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest';
require dirname(__FILE__) . '/config.php';
/**
* Check if the request is an AJAX request
*
* @return bool
*/
function isAjax()
{
return isset($_SERVER['HTTP_X_REQUESTED_WITH'])
&& mb_strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest';
}
// get the http origin
function get_http_origin() {
$origin = '';
if ( ! empty ( $_SERVER[ 'HTTP_ORIGIN' ] ) )
$origin = $_SERVER[ 'HTTP_ORIGIN' ];
return $origin;
/**
* Get the http origin
*
* @return string
*/
function getHttpOrigin()
{
$origin = '';
if (!empty($_SERVER['HTTP_ORIGIN'])) {
$origin = $_SERVER['HTTP_ORIGIN'];
}
return $origin;
}
// set headers that prevent caching in all the browsers
function nocache_headers() {
$headers = array(
'Expires' => 'Wed, 11 Jan 1984 05:00:00 GMT',
'Cache-Control' => 'no-cache, must-revalidate, max-age=0',
'Pragma' => 'no-cache',
);
$headers['Last-Modified'] = false;
/**
* Set headers that prevent caching in all the browsers
*
* @return void
*/
function nocacheHeaders()
{
$headers = [
'Expires' => 'Wed, 11 Jan 1984 05:00:00 GMT',
'Cache-Control' => 'no-cache, must-revalidate, max-age=0',
'Pragma' => 'no-cache',
];
$headers['Last-Modified'] = false;
unset($headers['Last-Modified']);
unset( $headers['Last-Modified'] );
// In PHP 5.3+, make sure we are not sending a Last-Modified header.
if (function_exists('header_remove')) {
@header_remove('Last-Modified');
} else {
// In PHP 5.2, send an empty Last-Modified header, but only as a
// last resort to override a header already sent. #WP23021
foreach (headers_list() as $header) {
if (0 === mb_stripos($header, 'Last-Modified')) {
$headers['Last-Modified'] = '';
break;
}
}
}
// In PHP 5.3+, make sure we are not sending a Last-Modified header.
if ( function_exists( 'header_remove' ) ) {
@header_remove( 'Last-Modified' );
} else {
// In PHP 5.2, send an empty Last-Modified header, but only as a
// last resort to override a header already sent. #WP23021
foreach ( headers_list() as $header ) {
if ( 0 === stripos( $header, 'Last-Modified' ) ) {
$headers['Last-Modified'] = '';
break;
}
}
}
foreach( $headers as $name => $field_value )
@header("{$name}: {$field_value}");
foreach ($headers as $name => $field_value) {
@header("{$name}: {$field_value}");
}
}
?>

View File

@ -1,6 +1,5 @@
<?php
/**
*
* (c) Copyright Ascensio System SIA 2023
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -14,44 +13,62 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
require_once( dirname(__FILE__) . '/config.php' );
require_once( dirname(__FILE__) . '/functions.php' );
require_once dirname(__FILE__) . '/config.php';
require_once dirname(__FILE__) . '/functions.php';
// put log files into the log folder
function sendlog($msg, $logFileName) {
/**
* Put log files into the log folder
*
* @param string $msg
* @param integer $logFileName
*
* @return void
*/
function sendlog($msg, $logFileName)
{
$logsFolder = "logs/";
if (!file_exists($logsFolder)) { // if log folder does't exist, make it
if (!file_exists($logsFolder)) { // if log folder doesn't exist, make it
mkdir($logsFolder);
}
file_put_contents($logsFolder . $logFileName, $msg . PHP_EOL, FILE_APPEND);
}
// create new uuid
function guid() {
/**
* Create new uuid
*
* @return string
*/
function guid()
{
if (function_exists('com_create_guid')) {
return com_create_guid();
} else {
mt_srand((double)microtime()*10000); // optional for php 4.2.0 and up
$charid = strtoupper(md5(uniqid(rand(), true)));
$hyphen = chr(45); // "-"
$uuid = chr(123) // "{"
.substr($charid, 0, 8).$hyphen
.substr($charid, 8, 4).$hyphen
.substr($charid,12, 4).$hyphen
.substr($charid,16, 4).$hyphen
.substr($charid,20,12)
.chr(125); // "}"
return $uuid;
}
mt_srand((float) microtime() * 10000); // optional for php 4.2.0 and up
$charid = mb_strtoupper(md5(uniqid(rand(), true)));
$hyphen = chr(45); // "-"
$uuid = chr(123) // "{"
.mb_substr($charid, 0, 8).$hyphen
.mb_substr($charid, 8, 4).$hyphen
.mb_substr($charid, 12, 4).$hyphen
.mb_substr($charid, 16, 4).$hyphen
.mb_substr($charid, 20, 12)
.chr(125); // "}"
return $uuid;
}
if(!function_exists('mime_content_type')) {
function mime_content_type($filename) {
$mime_types = array(
if (!function_exists('mime_content_type')) {
/**
* Create new uuid
*
* @param string $filename
*
* @return string
*/
function mime_content_type($filename)
{
$mime_types = [
'txt' => 'text/plain',
'htm' => 'text/html',
@ -105,35 +122,36 @@ if(!function_exists('mime_content_type')) {
// open office
'odt' => 'application/vnd.oasis.opendocument.text',
'ods' => 'application/vnd.oasis.opendocument.spreadsheet',
);
];
// check if the file extension is in the mime type array
$ext = strtolower(array_pop(explode('.',$filename)));
$ext = mb_strtolower(array_pop(explode('.', $filename)));
if (array_key_exists($ext, $mime_types)) {
return $mime_types[$ext]; // get the mime type of this extension
}
// or get the mime type from the file information
elseif (function_exists('finfo_open')) {
} elseif (function_exists('finfo_open')) { // or get the mime type from the file information
$finfo = finfo_open(FILEINFO_MIME);
$mimetype = finfo_file($finfo, $filename);
finfo_close($finfo);
return $mimetype;
}
else {
return 'application/octet-stream';
}
return 'application/octet-stream';
}
}
// get ip address
function getClientIp() {
$ipaddress =
getenv('HTTP_CLIENT_IP')?:
getenv('HTTP_X_FORWARDED_FOR')?:
getenv('HTTP_X_FORWARDED')?:
getenv('HTTP_FORWARDED_FOR')?:
getenv('HTTP_FORWARDED')?:
getenv('REMOTE_ADDR')?:
/**
* Get ip address
*
* @return string
*/
function getClientIp()
{
$ipaddress = getenv('HTTP_CLIENT_IP') ?:
getenv('HTTP_X_FORWARDED_FOR') ?:
getenv('HTTP_X_FORWARDED') ?:
getenv('HTTP_FORWARDED_FOR') ?:
getenv('HTTP_FORWARDED') ?:
getenv('REMOTE_ADDR') ?:
'Storage';
$ipaddress = preg_replace("/[^0-9a-zA-Z.=]/", "_", $ipaddress);
@ -141,65 +159,132 @@ function getClientIp() {
return $ipaddress;
}
// get server url
function serverPath($forDocumentServer = NULL) {
/**
* Get server url
*
* @param string $forDocumentServer
*
* @return string
*/
function serverPath($forDocumentServer = null)
{
return $forDocumentServer && isset($GLOBALS['EXAMPLE_URL']) && $GLOBALS['EXAMPLE_URL'] != ""
? $GLOBALS['EXAMPLE_URL']
: (getScheme() . '://' . $_SERVER['HTTP_HOST']);
}
// get current user host address
function getCurUserHostAddress($userAddress = NULL) {
/**
* Get current user host address
*
* @param string $userAddress
*
* @return string
*/
function getCurUserHostAddress($userAddress = null)
{
if ($GLOBALS['ALONE']) {
if (empty($GLOBALS['STORAGE_PATH'])) {
return "Storage";
} else {
return "";
}
return "";
}
if (is_null($userAddress)) {
$userAddress = getClientIp();
}
if (is_null($userAddress)) {$userAddress = getClientIp();}
return preg_replace("[^0-9a-zA-Z.=]", '_', $userAddress);
}
// get an internal file extension
function getInternalExtension($filename) {
$ext = strtolower('.' . pathinfo($filename, PATHINFO_EXTENSION));
/**
* Get an internal file extension
*
* @param string $filename
*
* @return string
*/
function getInternalExtension($filename)
{
$ext = mb_strtolower('.' . pathinfo($filename, PATHINFO_EXTENSION));
if (in_array($ext, $GLOBALS['ExtsDocument'])) return ".docx"; // .docx for text document extensions
if (in_array($ext, $GLOBALS['ExtsSpreadsheet'])) return ".xlsx"; // .xlsx for spreadsheet extensions
if (in_array($ext, $GLOBALS['ExtsPresentation'])) return ".pptx"; // .pptx for presentation extensions
if (in_array($ext, $GLOBALS['ExtsDocument'])) {
return ".docx";
} // .docx for text document extensions
if (in_array($ext, $GLOBALS['ExtsSpreadsheet'])) {
return ".xlsx";
} // .xlsx for spreadsheet extensions
if (in_array($ext, $GLOBALS['ExtsPresentation'])) {
return ".pptx";
} // .pptx for presentation extensions
return "";
}
// get image url for templates
function getTemplateImageUrl($filename) {
$ext = strtolower('.' . pathinfo($filename, PATHINFO_EXTENSION));
/**
* Get image url for templates
*
* @param string $filename
*
* @return string
*/
function getTemplateImageUrl($filename)
{
$ext = mb_strtolower('.' . pathinfo($filename, PATHINFO_EXTENSION));
$path = serverPath(true) . "/css/images/";
if (in_array($ext, $GLOBALS['ExtsDocument'])) return $path . "file_docx.svg"; // for text document extensions
if (in_array($ext, $GLOBALS['ExtsSpreadsheet'])) return $path . "file_xlsx.svg"; // for spreadsheet extensions
if (in_array($ext, $GLOBALS['ExtsPresentation'])) return $path . "file_pptx.svg"; // for presentation extensions
if (in_array($ext, $GLOBALS['ExtsDocument'])) {
return $path . "file_docx.svg";
} // for text document extensions
if (in_array($ext, $GLOBALS['ExtsSpreadsheet'])) {
return $path . "file_xlsx.svg";
} // for spreadsheet extensions
if (in_array($ext, $GLOBALS['ExtsPresentation'])) {
return $path . "file_pptx.svg";
} // for presentation extensions
return $path . "file_docx.svg";
}
// get the document type
function getDocumentType($filename) {
$ext = strtolower('.' . pathinfo($filename, PATHINFO_EXTENSION));
/**
* Get the document type
*
* @param string $filename
*
* @return string
*/
function getDocumentType($filename)
{
$ext = mb_strtolower('.' . pathinfo($filename, PATHINFO_EXTENSION));
if (in_array($ext, $GLOBALS['ExtsDocument'])) return "word"; // word for text document extensions
if (in_array($ext, $GLOBALS['ExtsSpreadsheet'])) return "cell"; // cell for spreadsheet extensions
if (in_array($ext, $GLOBALS['ExtsPresentation'])) return "slide"; // slide for presentation extensions
if (in_array($ext, $GLOBALS['ExtsDocument'])) {
return "word";
} // word for text document extensions
if (in_array($ext, $GLOBALS['ExtsSpreadsheet'])) {
return "cell";
} // cell for spreadsheet extensions
if (in_array($ext, $GLOBALS['ExtsPresentation'])) {
return "slide";
} // slide for presentation extensions
return "word";
}
// get the protocol
function getScheme() {
/**
* Get the protocol
*
* @return string
*/
function getScheme()
{
return (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http';
}
// get the storage path of the given file
function getStoragePath($fileName, $userAddress = NULL) {
$storagePath = trim(str_replace(array('/','\\'), DIRECTORY_SEPARATOR, $GLOBALS['STORAGE_PATH']), DIRECTORY_SEPARATOR);
/**
* Get the storage path of the given file
*
* @param string $fileName
* @param string $userAddress
*
* @return string
*/
function getStoragePath($fileName, $userAddress = null)
{
$storagePath = trim(str_replace(['/', '\\'], DIRECTORY_SEPARATOR, $GLOBALS['STORAGE_PATH']), DIRECTORY_SEPARATOR);
if (!empty($storagePath) && !file_exists($storagePath) && !is_dir($storagePath)) {
mkdir($storagePath);
}
@ -210,9 +295,8 @@ function getStoragePath($fileName, $userAddress = NULL) {
$directory = __DIR__ . DIRECTORY_SEPARATOR . $storagePath;
}
if ($storagePath != "")
{
$directory = $directory . DIRECTORY_SEPARATOR;
if ($storagePath != "") {
$directory = $directory . DIRECTORY_SEPARATOR;
// if the file directory doesn't exist, make it
if (!file_exists($directory) && !is_dir($directory)) {
@ -226,39 +310,62 @@ function getStoragePath($fileName, $userAddress = NULL) {
if (!file_exists($directory) && !is_dir($directory)) {
mkdir($directory);
}
}
sendlog("getStoragePath result: " . $directory . basename($fileName), "common.log");
return realpath($storagePath) === $storagePath ? $directory . $fileName : $directory . basename($fileName);
}
// get the path to the forcesaved file version
function getForcesavePath($fileName, $userAddress, $create) {
$storagePath = trim(str_replace(array('/','\\'), DIRECTORY_SEPARATOR, $GLOBALS['STORAGE_PATH']), DIRECTORY_SEPARATOR);
/**
* Get the path to the forcesaved file version
*
* @param string $fileName
* @param string $userAddress
* @param bool $create
*
* @return string
*/
function getForcesavePath($fileName, $userAddress, $create)
{
$storagePath = trim(str_replace(['/', '\\'], DIRECTORY_SEPARATOR, $GLOBALS['STORAGE_PATH']), DIRECTORY_SEPARATOR);
// create the directory to this file version
if (realpath($storagePath) === $storagePath) {
$directory = $storagePath . DIRECTORY_SEPARATOR;
} else {
$directory = __DIR__ . DIRECTORY_SEPARATOR . $storagePath . getCurUserHostAddress($userAddress) . DIRECTORY_SEPARATOR;
$directory = __DIR__ . DIRECTORY_SEPARATOR . $storagePath . getCurUserHostAddress($userAddress) .
DIRECTORY_SEPARATOR;
}
if (!is_dir($directory)) return "";
if (!is_dir($directory)) {
return "";
}
// create the directory to the history of this file version
$directory = $directory . $fileName . "-hist" . DIRECTORY_SEPARATOR;
if (!$create && !is_dir($directory)) return "";
if (!$create && !is_dir($directory)) {
return "";
}
if (!file_exists($directory) && !is_dir($directory)) {
mkdir($directory);
}
$directory = $directory . $fileName;
if (!$create && !file_exists($directory)) return "";
if (!$create && !file_exists($directory)) {
return "";
}
return $directory;
}
// get the path to the file history
function getHistoryDir($storagePath) {
/**
* Get the path to the file history
*
* @param string $storagePath
*
* @return string
*/
function getHistoryDir($storagePath)
{
$directory = $storagePath . "-hist";
// if the history directory doesn't exist, make it
if (!file_exists($directory) && !is_dir($directory)) {
@ -267,19 +374,36 @@ function getHistoryDir($storagePath) {
return $directory;
}
// get the path to the specified file version
function getVersionDir($histDir, $version) {
/**
* Get the path to the specified file version
*
* @param string $histDir
* @param string $version
*
* @return string
*/
function getVersionDir($histDir, $version)
{
return $histDir . DIRECTORY_SEPARATOR . $version;
}
// get a number of the last file version from the history directory
function getFileVersion($histDir) {
if (!file_exists($histDir) || !is_dir($histDir)) return 1; // check if the history directory exists
/**
* Get a number of the last file version from the history directory
*
* @param string $histDir
*
* @return int
*/
function getFileVersion($histDir)
{
if (!file_exists($histDir) || !is_dir($histDir)) {
return 1;
} // check if the history directory exists
$cdir = scandir($histDir);
$ver = 1;
foreach($cdir as $key => $fileName) {
if (!in_array($fileName,array(".", ".."))) {
foreach ($cdir as $key => $fileName) {
if (!in_array($fileName, [".", ".."])) {
if (is_dir($histDir . DIRECTORY_SEPARATOR . $fileName)) {
$ver++;
}
@ -288,9 +412,14 @@ function getFileVersion($histDir) {
return $ver;
}
// get all the stored files from the folder
function getStoredFiles() {
$storagePath = trim(str_replace(array('/','\\'), DIRECTORY_SEPARATOR, $GLOBALS['STORAGE_PATH']), DIRECTORY_SEPARATOR);
/**
* Get all the stored files from the folder
*
* @return array
*/
function getStoredFiles()
{
$storagePath = trim(str_replace(['/', '\\'], DIRECTORY_SEPARATOR, $GLOBALS['STORAGE_PATH']), DIRECTORY_SEPARATOR);
if (!empty($storagePath) && !file_exists($storagePath) && !is_dir($storagePath)) {
mkdir($storagePath);
}
@ -302,10 +431,9 @@ function getStoredFiles() {
}
// get the storage path and check if it exists
$result = array();
if ($storagePath != "")
{
$directory = $directory . DIRECTORY_SEPARATOR;
$result = [];
if ($storagePath != "") {
$directory = $directory . DIRECTORY_SEPARATOR;
if (!file_exists($directory) && !is_dir($directory)) {
return $result;
@ -321,18 +449,18 @@ function getStoredFiles() {
}
$cdir = scandir($directory); // get all the files and folders from the directory
$result = array();
foreach($cdir as $key => $fileName) { // run through all the file and folder names
if (!in_array($fileName,array(".", ".."))) {
$result = [];
foreach ($cdir as $key => $fileName) { // run through all the file and folder names
if (!in_array($fileName, [".", ".."])) {
if (!is_dir($directory . DIRECTORY_SEPARATOR . $fileName)) { // if an element isn't a directory
$ext = strtolower('.' . pathinfo($fileName, PATHINFO_EXTENSION));
$ext = mb_strtolower('.' . pathinfo($fileName, PATHINFO_EXTENSION));
$dat = filemtime($directory . DIRECTORY_SEPARATOR . $fileName); // get the time of element modification
$result[$dat] = (object) array( // and write the file to the result
"name" => $fileName,
"documentType" => getDocumentType($fileName),
"canEdit" => in_array($ext, $GLOBALS['DOC_SERV_EDITED']),
"isFillFormDoc" => in_array($ext, $GLOBALS['DOC_SERV_FILLFORMS'])
);
$result[$dat] = (object) [ // and write the file to the result
"name" => $fileName,
"documentType" => getDocumentType($fileName),
"canEdit" => in_array($ext, $GLOBALS['DOC_SERV_EDITED']),
"isFillFormDoc" => in_array($ext, $GLOBALS['DOC_SERV_FILLFORMS']),
];
}
}
}
@ -340,12 +468,18 @@ function getStoredFiles() {
return array_reverse($result);
}
// get the virtual path
function getVirtualPath($forDocumentServer) {
$storagePath = trim(str_replace(array('/','\\'), '/', $GLOBALS['STORAGE_PATH']), '/');
/**
* Get the virtual path
*
* @param string $forDocumentServer
*
* @return string
*/
function getVirtualPath($forDocumentServer)
{
$storagePath = trim(str_replace(['/', '\\'], '/', $GLOBALS['STORAGE_PATH']), '/');
$storagePath = $storagePath != "" ? $storagePath . '/' : "";
if (realpath($storagePath) === $storagePath) {
$virtPath = serverPath($forDocumentServer) . '/' . $storagePath . '/';
} else {
@ -355,8 +489,18 @@ function getVirtualPath($forDocumentServer) {
return $virtPath;
}
// get a file with meta information
function createMeta($fileName, $uid, $uname, $userAddress = NULL) {
/**
* Get a file with meta information
*
* @param string $fileName
* @param string $uid
* @param string $uname
* @param string $userAddress
*
* @return void
*/
function createMeta($fileName, $uid, $uname, $userAddress = null)
{
$histDir = getHistoryDir(getStoragePath($fileName, $userAddress)); // get the history directory
// turn the file information into the json format
@ -370,72 +514,113 @@ function createMeta($fileName, $uid, $uname, $userAddress = NULL) {
file_put_contents($histDir . DIRECTORY_SEPARATOR . "createdInfo.json", json_encode($json, JSON_PRETTY_PRINT));
}
// get the file url
function FileUri($file_name, $forDocumentServer = NULL) {
/**
* Get the file url
*
* @param string $file_name
* @param string $forDocumentServer
*
* @return string
*/
function fileUri($file_name, $forDocumentServer = null)
{
$uri = getVirtualPath($forDocumentServer) . rawurlencode($file_name); // add encoded file name to the virtual path
return $uri;
}
// get file information
function getFileInfo($fileId){
/**
* Get file information
*
* @param string $fileId
*
* @return array|string
*/
function getFileInfo($fileId)
{
$storedFiles = getStoredFiles();
$result = array();
$resultID = array();
$result = [];
$resultID = [];
// run through all the stored files
foreach ($storedFiles as $key => $value){
$result[$key] = (object) array( // write all the parameters to the map
foreach ($storedFiles as $key => $value) {
$result[$key] = (object) [ // write all the parameters to the map
"version" => getFileVersion(getHistoryDir(getStoragePath($value->name))),
"id" => getDocEditorKey($value->name),
"contentLength" => number_format( filesize(getStoragePath($value->name)) / 1024, 2 )." KB",
"contentLength" => number_format(filesize(getStoragePath($value->name)) / 1024, 2)." KB",
"pureContentLength" => filesize(getStoragePath($value->name)),
"title" => $value->name,
"updated" => date( DATE_ATOM, filemtime(getStoragePath($value->name))),
);
"updated" => date(DATE_ATOM, filemtime(getStoragePath($value->name))),
];
// get file information by its id
if ($fileId != null){
if ($fileId == getDocEditorKey($value->name)){
if ($fileId != null) {
if ($fileId == getDocEditorKey($value->name)) {
$resultID[count($resultID)] = $result[$key];
}
}
}
if ($fileId != null){
if (count($resultID) != 0) return $resultID;
else return "File not found";
}
else {
return $result;
if ($fileId != null) {
if (count($resultID) != 0) {
return $resultID;
}
return "File not found";
}
return $result;
}
// get all the supported file extensions
function getFileExts() {
return array_merge($GLOBALS['DOC_SERV_VIEWD'], $GLOBALS['DOC_SERV_EDITED'], $GLOBALS['DOC_SERV_CONVERT'], $GLOBALS['DOC_SERV_FILLFORMS']);
/**
* Get all the supported file extensions
*
* @return array
*/
function getFileExts()
{
return array_merge(
$GLOBALS['DOC_SERV_VIEWD'],
$GLOBALS['DOC_SERV_EDITED'],
$GLOBALS['DOC_SERV_CONVERT'],
$GLOBALS['DOC_SERV_FILLFORMS']
);
}
// get the correct file name if such a name already exists
function GetCorrectName($fileName, $userAddress = NULL) {
/**
* Get the correct file name if such a name already exists
*
* @param string $fileName
* @param string $userAddress
*
* @return string
*/
function GetCorrectName($fileName, $userAddress = null)
{
$path_parts = pathinfo($fileName);
$ext = strtolower($path_parts['extension']);
$ext = mb_strtolower($path_parts['extension']);
$name = $path_parts['basename'];
$baseNameWithoutExt = substr($name, 0, strlen($name) - strlen($ext) - 1); // get file name from the basename without extension
// get file name from the basename without extension
$baseNameWithoutExt = mb_substr($name, 0, mb_strlen($name) - mb_strlen($ext) - 1);
$name = $baseNameWithoutExt . "." . $ext;
for ($i = 1; file_exists(getStoragePath($name, $userAddress)); $i++) // if a file with such a name already exists in this directory
{
// if a file with such a name already exists in this directory
for ($i = 1; file_exists(getStoragePath($name, $userAddress)); $i++) {
$name = $baseNameWithoutExt . " (" . $i . ")." . $ext; // add an index after its base name
}
return $name;
}
// get document key
function getDocEditorKey($fileName) {
$key = getCurUserHostAddress() . FileUri($fileName); // get document key by adding local file url to the current user host address
/**
* Get document key
*
* @param string $fileName
*
* @return string
*/
function getDocEditorKey($fileName)
{
// get document key by adding local file url to the current user host address
$key = getCurUserHostAddress() . fileUri($fileName);
$stat = filemtime(getStoragePath($fileName)); // get creation time
$key = $key . $stat; // and add it to the document key
return GenerateRevisionId($key); // generate the document key value
return generateRevisionId($key); // generate the document key value
}
?>

View File

@ -0,0 +1,17 @@
{
"require-dev": {
"squizlabs/php_codesniffer": "*"
},
"scripts": {
"code-sniffer": [
"./vendor/bin/phpcs --config-set default_standard ruleset.xml",
"./vendor/bin/phpcs --config-set colors 1"
],
"post-install-cmd": [
"@code-sniffer"
],
"post-update-cmd": [
"@code-sniffer"
]
}
}

View File

@ -0,0 +1,75 @@
{
"_readme": [
"This file locks the dependencies of your project to a known state",
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "0ae1576e556ebadd2933ecd2483a4b26",
"packages": [],
"packages-dev": [
{
"name": "squizlabs/php_codesniffer",
"version": "3.7.1",
"source": {
"type": "git",
"url": "https://github.com/squizlabs/PHP_CodeSniffer.git",
"reference": "1359e176e9307e906dc3d890bcc9603ff6d90619"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/1359e176e9307e906dc3d890bcc9603ff6d90619",
"reference": "1359e176e9307e906dc3d890bcc9603ff6d90619",
"shasum": ""
},
"require": {
"ext-simplexml": "*",
"ext-tokenizer": "*",
"ext-xmlwriter": "*",
"php": ">=5.4.0"
},
"require-dev": {
"phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0"
},
"bin": [
"bin/phpcs",
"bin/phpcbf"
],
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "3.x-dev"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Greg Sherwood",
"role": "lead"
}
],
"description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.",
"homepage": "https://github.com/squizlabs/PHP_CodeSniffer",
"keywords": [
"phpcs",
"standards"
],
"support": {
"issues": "https://github.com/squizlabs/PHP_CodeSniffer/issues",
"source": "https://github.com/squizlabs/PHP_CodeSniffer",
"wiki": "https://github.com/squizlabs/PHP_CodeSniffer/wiki"
},
"time": "2022-06-18T07:21:10+00:00"
}
],
"aliases": [],
"minimum-stability": "stable",
"stability-flags": [],
"prefer-stable": false,
"prefer-lowest": false,
"platform": [],
"platform-dev": [],
"plugin-api-version": "2.2.0"
}

View File

@ -1,19 +1,36 @@
<?php
/**
* (c) Copyright Ascensio System SIA 2023
*
* 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.
*/
$GLOBALS['version'] = "1.5.0";
$GLOBALS['FILE_SIZE_MAX'] = 5242880;
$GLOBALS['STORAGE_PATH'] = "";
$GLOBALS['ALONE'] = FALSE;
$GLOBALS['ALONE'] = false;
$GLOBALS['DOC_SERV_FILLFORMS'] = array(".oform", ".docx");
$GLOBALS['DOC_SERV_VIEWD'] = array(".pdf", ".djvu", ".xps", ".oxps");
$GLOBALS['DOC_SERV_EDITED'] = array(".docx", ".xlsx", ".csv", ".pptx", ".txt", ".docxf");
$GLOBALS['DOC_SERV_CONVERT'] = array(".docm", ".doc", ".dotx", ".dotm", ".dot", ".odt", ".fodt", ".ott", ".xlsm", ".xlsb", ".xls", ".xltx", ".xltm", ".xlt", ".ods", ".fods", ".ots", ".pptm", ".ppt", ".ppsx", ".ppsm", ".pps", ".potx", ".potm", ".pot", ".odp", ".fodp", ".otp", ".rtf", ".mht", ".html", ".htm", ".xml", ".epub", ".fb2");
$GLOBALS['DOC_SERV_FILLFORMS'] = [".oform", ".docx"];
$GLOBALS['DOC_SERV_VIEWD'] = [".pdf", ".djvu", ".xps", ".oxps"];
$GLOBALS['DOC_SERV_EDITED'] = [".docx", ".xlsx", ".csv", ".pptx", ".txt", ".docxf"];
$GLOBALS['DOC_SERV_CONVERT'] = [".docm", ".doc", ".dotx", ".dotm", ".dot",
".odt", ".fodt", ".ott", ".xlsm", ".xlsb", ".xls", ".xltx", ".xltm",
".xlt", ".ods", ".fods", ".ots", ".pptm", ".ppt", ".ppsx", ".ppsm", ".pps",
".potx", ".potm", ".pot", ".odp", ".fodp", ".otp", ".rtf", ".mht", ".html", ".htm", ".xml", ".epub", ".fb2"];
$GLOBALS['DOC_SERV_TIMEOUT'] = "120000";
$GLOBALS['DOC_SERV_SITE_URL'] = "http://documentserver/";
$GLOBALS['DOC_SERV_CONVERTER_URL'] = "ConvertService.ashx";
@ -24,29 +41,31 @@ $GLOBALS['DOC_SERV_COMMAND_URL'] = "coauthoring/CommandService.ashx";
$GLOBALS['DOC_SERV_JWT_SECRET'] = "";
$GLOBALS['DOC_SERV_JWT_HEADER'] = "Authorization";
$GLOBALS['DOC_SERV_VERIFY_PEER_OFF'] = TRUE;
$GLOBALS['DOC_SERV_VERIFY_PEER_OFF'] = true;
$GLOBALS['EXAMPLE_URL'] = "";
$GLOBALS['MOBILE_REGEX'] = "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";
$GLOBALS['MOBILE_REGEX'] = "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";
$GLOBALS['ExtsSpreadsheet'] = [".xls", ".xlsx", ".xlsm", ".xlsb",
".xlt", ".xltx", ".xltm",
".ods", ".fods", ".ots", ".csv"];
$GLOBALS['ExtsSpreadsheet'] = array(".xls", ".xlsx", ".xlsm", ".xlsb",
".xlt", ".xltx", ".xltm",
".ods", ".fods", ".ots", ".csv");
$GLOBALS['ExtsPresentation'] = [".pps", ".ppsx", ".ppsm",
".ppt", ".pptx", ".pptm",
".pot", ".potx", ".potm",
".odp", ".fodp", ".otp"];
$GLOBALS['ExtsPresentation'] = array(".pps", ".ppsx", ".ppsm",
".ppt", ".pptx", ".pptm",
".pot", ".potx", ".potm",
".odp", ".fodp", ".otp");
$GLOBALS['ExtsDocument'] = [".doc", ".docx", ".docm",
".dot", ".dotx", ".dotm",
".odt", ".fodt", ".ott", ".rtf", ".txt",
".html", ".htm", ".mht", ".xml",
".pdf", ".djvu", ".fb2", ".epub", ".xps", ".oxps", ".oform"];
$GLOBALS['ExtsDocument'] = array(".doc", ".docx", ".docm",
".dot", ".dotx", ".dotm",
".odt", ".fodt", ".ott", ".rtf", ".txt",
".html", ".htm", ".mht", ".xml",
".pdf", ".djvu", ".fb2", ".epub", ".xps", ".oxps", ".oform");
$GLOBALS['LANGUAGES'] = array(
$GLOBALS['LANGUAGES'] = [
'en' => 'English',
'hy' => 'Armenian',
'az' => 'Azerbaijani',
@ -85,6 +104,5 @@ $GLOBALS['LANGUAGES'] = array(
'tr' => 'Turkish',
'uk' => 'Ukrainian',
'vi' => 'Vietnamese',
'aa-AA' => 'Test Language'
);
?>
'aa-AA' => 'Test Language',
];

View File

@ -1,360 +1,434 @@
<?php
/**
*
* (c) Copyright Ascensio System SIA 2023
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
require_once( dirname(__FILE__) . '/config.php' );
require_once( dirname(__FILE__) . '/common.php' );
require_once( dirname(__FILE__) . '/functions.php' );
require_once( dirname(__FILE__) . '/jwtmanager.php' );
require_once( dirname(__FILE__) . '/users.php' );
namespace PhpExample;
$filename;
/**
* (c) Copyright Ascensio System SIA 2023
*
* 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.
*/
$user = getUser($_GET["user"]);
$isEnableDirectUrl = $_GET["directUrl"] != null ? filter_var($_GET["directUrl"], FILTER_VALIDATE_BOOLEAN) : false;
require_once dirname(__FILE__) . '/config.php';
require_once dirname(__FILE__) . '/common.php';
require_once dirname(__FILE__) . '/functions.php';
require_once dirname(__FILE__) . '/jwtmanager.php';
require_once dirname(__FILE__) . '/users.php';
// get the file url and upload it
$externalUrl = $_GET["fileUrl"];
if (!empty($externalUrl))
{
$filename = DoUpload($externalUrl);
}
// if the file url doesn't exist, get file name and file extension
else
{
$filename = basename($_GET["fileID"]);
}
$createExt = $_GET["fileExt"];
$user = getUser($_GET["user"]);
$isEnableDirectUrl = isset($_GET["directUrl"]) ? filter_var($_GET["directUrl"], FILTER_VALIDATE_BOOLEAN) : false;
if (!empty($createExt))
{
// and get demo file name by the extension
$filename = tryGetDefaultByType($createExt, $user);
// get the file url and upload it
$externalUrl = $_GET["fileUrl"] ?? "";
if (!empty($externalUrl)) {
$filename = doUpload($externalUrl);
} else { // if the file url doesn't exist, get file name and file extension
$filename = basename($_GET["fileID"]);
}
$createExt = $_GET["fileExt"] ?? "";
// create the demo file url
$new_url = "doceditor.php?fileID=" . $filename . "&user=" . $_GET["user"];
header('Location: ' . $new_url, true);
exit;
}
if (!empty($createExt)) {
// and get demo file name by the extension
$filename = tryGetDefaultByType($createExt, $user);
$fileuri = FileUri($filename, true);
$fileuriUser = realpath($GLOBALS['STORAGE_PATH']) === $GLOBALS['STORAGE_PATH'] ? getDownloadUrl($filename) . "&dmode=emb" : FileUri($filename);
$directUrl = getDownloadUrl($filename, FALSE);
$docKey = getDocEditorKey($filename);
$filetype = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
// create the demo file url
$new_url = "doceditor.php?fileID=" . $filename . "&user=" . $_GET["user"];
header('Location: ' . $new_url, true);
exit;
}
$ext = strtolower('.' . pathinfo($filename, PATHINFO_EXTENSION));
$editorsMode = empty($_GET["action"]) ? "edit" : $_GET["action"]; // get the editors mode
$canEdit = in_array($ext, $GLOBALS['DOC_SERV_EDITED']); // check if the file can be edited
if ((!$canEdit && $editorsMode == "edit" || $editorsMode == "fillForms") && in_array($ext, $GLOBALS['DOC_SERV_FILLFORMS'])) {
$editorsMode = "fillForms";
$canEdit = true;
}
$submitForm = $editorsMode == "fillForms" && $user->id == "uid-1" && !1; // check if the Submit form button is displayed or not
$mode = $canEdit && $editorsMode != "view" ? "edit" : "view"; // define if the editing mode is edit or view
$type = empty($_GET["type"]) ? "desktop" : $_GET["type"];
$fileuri = fileUri($filename, true);
$fileuriUser = realpath($GLOBALS['STORAGE_PATH']) === $GLOBALS['STORAGE_PATH'] ?
getDownloadUrl($filename) . "&dmode=emb" : fileUri($filename);
$directUrl = getDownloadUrl($filename, false);
$docKey = getDocEditorKey($filename);
$filetype = mb_strtolower(pathinfo($filename, PATHINFO_EXTENSION));
$templatesImageUrl = getTemplateImageUrl($filename); // templates image url in the "From Template" section
$createUrl = getCreateUrl($filename, $user->id, $type);
$templates = array(
array (
"image" => "",
"title" => "Blank",
"url" => $createUrl
),
array (
"image" => $templatesImageUrl,
"title" => "With sample content",
"url" => $createUrl . "&sample=true"
)
);
$ext = mb_strtolower('.' . pathinfo($filename, PATHINFO_EXTENSION));
$editorsMode = empty($_GET["action"]) ? "edit" : $_GET["action"]; // get the editors mode
$canEdit = in_array($ext, $GLOBALS['DOC_SERV_EDITED']); // check if the file can be edited
if ((!$canEdit && $editorsMode == "edit"
|| $editorsMode == "fillForms")
&& in_array($ext, $GLOBALS['DOC_SERV_FILLFORMS'])
) {
$editorsMode = "fillForms";
$canEdit = true;
}
// specify the document config
$config = [
"type" => $type,
"documentType" => getDocumentType($filename),
"document" => [
"title" => $filename,
"url" => getDownloadUrl($filename),
"directUrl" => $isEnableDirectUrl ? $directUrl : "",
"fileType" => $filetype,
"key" => $docKey,
"info" => [
"owner" => "Me",
"uploaded" => date('d.m.y'),
"favorite" => $user->favorite
],
"permissions" => [ // the permission for the document to be edited and downloaded or not
"comment" => $editorsMode != "view" && $editorsMode != "fillForms" && $editorsMode != "embedded" && $editorsMode != "blockcontent",
"copy" => !in_array("copy", $user->deniedPermissions),
"download" => !in_array("download", $user->deniedPermissions),
"edit" => $canEdit && ($editorsMode == "edit" || $editorsMode == "view" || $editorsMode == "filter" || $editorsMode == "blockcontent"),
"print" => !in_array("print", $user->deniedPermissions),
"fillForms" => $editorsMode != "view" && $editorsMode != "comment" && $editorsMode != "embedded" && $editorsMode != "blockcontent",
"modifyFilter" => $editorsMode != "filter",
"modifyContentControl" => $editorsMode != "blockcontent",
"review" => $canEdit && ($editorsMode == "edit" || $editorsMode == "review"),
"chat" => $user->id != "uid-0",
"reviewGroups" => $user->reviewGroups,
"commentGroups" => $user->commentGroups,
"userInfoGroups" => $user->userInfoGroups
]
// check if the Submit form button is displayed or not
$submitForm = $editorsMode == "fillForms" && $user->id == "uid-1" && !1;
$mode = $canEdit && $editorsMode != "view" ? "edit" : "view"; // define if the editing mode is edit or view
$type = empty($_GET["type"]) ? "desktop" : $_GET["type"];
$templatesImageUrl = getTemplateImageUrl($filename); // templates image url in the "From Template" section
$createUrl = getCreateUrl($filename, $user->id, $type);
$templates = [
[
"image" => "",
"title" => "Blank",
"url" => $createUrl,
],
[
"image" => $templatesImageUrl,
"title" => "With sample content",
"url" => $createUrl . "&sample=true",
],
];
// specify the document config
$config = [
"type" => $type,
"documentType" => getDocumentType($filename),
"document" => [
"title" => $filename,
"url" => getDownloadUrl($filename),
"directUrl" => $isEnableDirectUrl ? $directUrl : "",
"fileType" => $filetype,
"key" => $docKey,
"info" => [
"owner" => "Me",
"uploaded" => date('d.m.y'),
"favorite" => $user->favorite,
],
"editorConfig" => [
"actionLink" => empty($_GET["actionLink"]) ? null : json_decode($_GET["actionLink"]),
"mode" => $mode,
"lang" => empty($_COOKIE["ulang"]) ? "en" : $_COOKIE["ulang"],
"callbackUrl" => getCallbackUrl($filename), // absolute URL to the document storage service
"coEditing" => $editorsMode == "view" && $user->id == "uid-0" ? [
"mode" => "strict",
"change" => false
] : null,
"createUrl" => $user->id != "uid-0" ? $createUrl : null,
"templates" => $user->templates ? $templates : null,
"user" => [ // the user currently viewing or editing the document
"id" => $user->id != "uid-0" ? $user->id : null,
"name" => $user->name,
"group" => $user->group
"permissions" => [ // the permission for the document to be edited and downloaded or not
"comment" => $editorsMode != "view" && $editorsMode
!= "fillForms" && $editorsMode != "embedded" && $editorsMode != "blockcontent",
"copy" => !in_array("copy", $user->deniedPermissions),
"download" => !in_array("download", $user->deniedPermissions),
"edit" => $canEdit && ($editorsMode == "edit" ||
$editorsMode == "view" || $editorsMode == "filter" || $editorsMode == "blockcontent"),
"print" => !in_array("print", $user->deniedPermissions),
"fillForms" => $editorsMode != "view" && $editorsMode != "comment"
&& $editorsMode != "embedded" && $editorsMode != "blockcontent",
"modifyFilter" => $editorsMode != "filter",
"modifyContentControl" => $editorsMode != "blockcontent",
"review" => $canEdit && ($editorsMode == "edit" || $editorsMode == "review"),
"chat" => $user->id != "uid-0",
"reviewGroups" => $user->reviewGroups,
"commentGroups" => $user->commentGroups,
"userInfoGroups" => $user->userInfoGroups,
],
],
"editorConfig" => [
"actionLink" => empty($_GET["actionLink"]) ? null : json_decode($_GET["actionLink"]),
"mode" => $mode,
"lang" => empty($_COOKIE["ulang"]) ? "en" : $_COOKIE["ulang"],
"callbackUrl" => getCallbackUrl($filename), // absolute URL to the document storage service
"coEditing" => $editorsMode == "view" && $user->id == "uid-0" ? [
"mode" => "strict",
"change" => false,
] : null,
"createUrl" => $user->id != "uid-0" ? $createUrl : null,
"templates" => $user->templates ? $templates : null,
"user" => [ // the user currently viewing or editing the document
"id" => $user->id != "uid-0" ? $user->id : null,
"name" => $user->name,
"group" => $user->group,
],
"embedded" => [ // the parameters for the embedded document type
// the absolute URL that will allow the document to be saved onto the user personal computer
"saveUrl" => $directUrl,
// the absolute URL to the document serving as a source file for the document embedded into the web page
"embedUrl" => $directUrl,
// the absolute URL that will allow other users to share this document
"shareUrl" => $directUrl,
"toolbarDocked" => "top", // the place for the embedded viewer toolbar (top or bottom)
],
"customization" => [ // the parameters for the editor interface
"about" => true, // the About section display
"comments" => true,
"feedback" => true, // the Feedback & Support menu button display
// adds the request for the forced file saving to the callback handler when saving the document
"forcesave" => false,
"submitForm" => $submitForm, // if the Submit form button is displayed or not
"goback" => [ // settings for the Open file location menu button and upper right corner button
// the absolute URL to the website address which will be opened
// when clicking the Open file location menu button
"url" => serverPath(),
],
"embedded" => [ // the parameters for the embedded document type
"saveUrl" => $directUrl, // the absolute URL that will allow the document to be saved onto the user personal computer
"embedUrl" => $directUrl, // the absolute URL to the document serving as a source file for the document embedded into the web page
"shareUrl" => $directUrl, // the absolute URL that will allow other users to share this document
"toolbarDocked" => "top", // the place for the embedded viewer toolbar (top or bottom)
],
"customization" => [ // the parameters for the editor interface
"about" => true, // the About section display
"comments" => true,
"feedback" => true, // the Feedback & Support menu button display
"forcesave" => false, // adds the request for the forced file saving to the callback handler when saving the document
"submitForm" => $submitForm, // if the Submit form button is displayed or not
"goback" => [ // settings for the Open file location menu button and upper right corner button
"url" => serverPath(), // the absolute URL to the website address which will be opened when clicking the Open file location menu button
]
]
]
];
],
],
];
// an image for inserting
$dataInsertImage = $isEnableDirectUrl ? [
"fileType" => "png",
"url" => serverPath(true) . "/css/images/logo.png",
"directUrl" => serverPath(false) . "/css/images/logo.png"
] : [
"fileType" => "png",
"url" => serverPath(true) . "/css/images/logo.png"
];
// an image for inserting
$dataInsertImage = $isEnableDirectUrl ? [
"fileType" => "png",
"url" => serverPath(true) . "/css/images/logo.png",
"directUrl" => serverPath(false) . "/css/images/logo.png",
] : [
"fileType" => "png",
"url" => serverPath(true) . "/css/images/logo.png",
];
// a document for comparing
$dataCompareFile = $isEnableDirectUrl ? [
"fileType" => "docx",
"url" => serverPath(true) . "/webeditor-ajax.php?type=assets&name=sample.docx",
"directUrl" => serverPath(false) . "/webeditor-ajax.php?type=assets&name=sample.docx"
] : [
"fileType" => "docx",
"url" => serverPath(true) . "/webeditor-ajax.php?type=assets&name=sample.docx"
];
// a document for comparing
$dataCompareFile = $isEnableDirectUrl ? [
"fileType" => "docx",
"url" => serverPath(true) . "/webeditor-ajax.php?type=assets&name=sample.docx",
"directUrl" => serverPath(false) . "/webeditor-ajax.php?type=assets&name=sample.docx",
] : [
"fileType" => "docx",
"url" => serverPath(true) . "/webeditor-ajax.php?type=assets&name=sample.docx",
];
// recipients data for mail merging
$dataMailMergeRecipients = $isEnableDirectUrl ? [
"fileType" =>"csv",
"url" => serverPath(true) . "/webeditor-ajax.php?type=csv",
"directUrl" => serverPath(false) . "/webeditor-ajax.php?type=csv"
] : [
"fileType" =>"csv",
"url" => serverPath(true) . "/webeditor-ajax.php?type=csv"
];
// users data for mentions
$usersForMentions = $user->id != "uid-0" ? getUsersForMentions($user->id) : null;
// recipients data for mail merging
$dataMailMergeRecipients = $isEnableDirectUrl ? [
"fileType" => "csv",
"url" => serverPath(true) . "/webeditor-ajax.php?type=csv",
"directUrl" => serverPath(false) . "/webeditor-ajax.php?type=csv",
] : [
"fileType" => "csv",
"url" => serverPath(true) . "/webeditor-ajax.php?type=csv",
];
// check if the secret key to generate token exists
if (isJwtEnabled()) {
$config["token"] = jwtEncode($config); // encode config into the token
$dataInsertImage["token"] = jwtEncode($dataInsertImage); // encode the dataInsertImage object into the token
$dataCompareFile["token"] = jwtEncode($dataCompareFile); // encode the dataCompareFile object into the token
$dataMailMergeRecipients["token"] = jwtEncode($dataMailMergeRecipients); // encode the dataMailMergeRecipients object into the token
// users data for mentions
$usersForMentions = $user->id != "uid-0" ? getUsersForMentions($user->id) : null;
// check if the secret key to generate token exists
if (isJwtEnabled()) {
$config["token"] = jwtEncode($config); // encode config into the token
$dataInsertImage["token"] = jwtEncode($dataInsertImage); // encode the dataInsertImage object into the token
$dataCompareFile["token"] = jwtEncode($dataCompareFile); // encode the dataCompareFile object into the token
// encode the dataMailMergeRecipients object into the token
$dataMailMergeRecipients["token"] = jwtEncode($dataMailMergeRecipients);
}
/**
* Get demo file name by the extension
*
* @param string $createExt
* @param string $user
*
* @return string
*/
function tryGetDefaultByType($createExt, $user)
{
$demoName = ($_GET["sample"] ? "sample." : "new.") . $createExt;
$demoPath = "assets" . DIRECTORY_SEPARATOR . ($_GET["sample"] ? "sample" : "new") . DIRECTORY_SEPARATOR;
$demoFilename = GetCorrectName($demoName);
if (!@copy(dirname(__FILE__) . DIRECTORY_SEPARATOR . $demoPath . $demoName, getStoragePath($demoFilename))) {
sendlog("Copy file error to ". getStoragePath($demoFilename), "common.log");
// Copy error!!!
}
// get demo file name by the extension
function tryGetDefaultByType($createExt, $user) {
$demoName = ($_GET["sample"] ? "sample." : "new.") . $createExt;
$demoPath = "assets" . DIRECTORY_SEPARATOR . ($_GET["sample"] ? "sample" : "new") . DIRECTORY_SEPARATOR;
$demoFilename = GetCorrectName($demoName);
// create demo file meta information
createMeta($demoFilename, $user->id, $user->name);
if(!@copy(dirname(__FILE__) . DIRECTORY_SEPARATOR . $demoPath . $demoName, getStoragePath($demoFilename)))
{
sendlog("Copy file error to ". getStoragePath($demoFilename), "common.log");
// Copy error!!!
}
return $demoFilename;
}
// create demo file meta information
createMeta($demoFilename, $user->id, $user->name);
/**
* Get the callback url
*
* @param string $fileName
*
* @return string
*/
function getCallbackUrl($fileName)
{
return serverPath(true) . '/'
. "webeditor-ajax.php"
. "?type=track"
. "&fileName=" . urlencode($fileName)
. "&userAddress=" . getClientIp();
}
return $demoFilename;
}
/**
* Get url to the created file
*
* @param string $fileName
* @param string $uid
* @param string $type
*
* @return string
*/
function getCreateUrl($fileName, $uid, $type)
{
$ext = trim(getInternalExtension($fileName), '.');
return serverPath(false) . '/'
. "doceditor.php"
. "?fileExt=" . $ext
. "&user=" . $uid
. "&type=" . $type;
}
// get the callback url
function getCallbackUrl($fileName) {
return serverPath(TRUE) . '/'
. "webeditor-ajax.php"
. "?type=track"
. "&fileName=" . urlencode($fileName)
. "&userAddress=" . getClientIp();
}
/**
* Get url for history download
*
* @param string $fileName
* @param string $version
* @param string $file
* @param bool $isServer
*
* @return string
*/
function getHistoryDownloadUrl($fileName, $version, $file, $isServer = true)
{
$userAddress = $isServer ? "&userAddress=" . getClientIp() : "";
return serverPath($isServer) . '/'
. "webeditor-ajax.php"
. "?type=history"
. "&fileName=" . urlencode($fileName)
. "&ver=" . $version
. "&file=" . urlencode($file)
. $userAddress;
}
// get url to the created file
function getCreateUrl($fileName, $uid, $type) {
$ext = trim(getInternalExtension($fileName),'.');
return serverPath(false) . '/'
. "doceditor.php"
. "?fileExt=" . $ext
. "&user=" . $uid
. "&type=" . $type;
}
/**
* Get url to download a file
*
* @param string $fileName
* @param bool $isServer
*
* @return string
*/
function getDownloadUrl($fileName, $isServer = true)
{
$userAddress = $isServer ? "&userAddress=" . getClientIp() : "";
return serverPath($isServer) . '/'
. "webeditor-ajax.php"
. "?type=download"
. "&fileName=" . urlencode($fileName)
. $userAddress;
}
function getHistoryDownloadUrl($fileName, $version, $file, $isServer = TRUE) {
$userAddress = $isServer ? "&userAddress=" . getClientIp() : "";
return serverPath($isServer) . '/'
. "webeditor-ajax.php"
. "?type=history"
. "&fileName=" . urlencode($fileName)
. "&ver=" . $version
. "&file=" . urlencode($file)
. $userAddress;
}
/**
* Get document history
*
* @param string $filename
* @param string $filetype
* @param string $docKey
* @param string $fileuri
* @param bool $isEnableDirectUrl
*
* @return array
*/
function getHistory($filename, $filetype, $docKey, $fileuri, $isEnableDirectUrl)
{
$storagePath = $GLOBALS['STORAGE_PATH'];
$histDir = getHistoryDir(getStoragePath($filename)); // get the path to the file history
// get url to download a file
function getDownloadUrl($fileName, $isServer = TRUE) {
$userAddress = $isServer ? "&userAddress=" . getClientIp() : "";
return serverPath($isServer) . '/'
. "webeditor-ajax.php"
. "?type=download"
. "&fileName=" . urlencode($fileName)
. $userAddress;
}
if (getFileVersion($histDir) > 0) { // check if the file was modified (the file version is greater than 0)
$curVer = getFileVersion($histDir);
// get document history
function getHistory($filename, $filetype, $docKey, $fileuri, $isEnableDirectUrl) {
$storagePath = $GLOBALS['STORAGE_PATH'];
$histDir = getHistoryDir(getStoragePath($filename)); // get the path to the file history
$hist = [];
$histData = [];
if (getFileVersion($histDir) > 0) { // check if the file was modified (the file version is greater than 0)
$curVer = getFileVersion($histDir);
for ($i = 1; $i <= $curVer; $i++) { // run through all the file versions
$obj = [];
$dataObj = [];
$verDir = getVersionDir($histDir, $i); // get the path to the file version
$hist = [];
$histData = [];
// get document key
$key = $i == $curVer ? $docKey : file_get_contents($verDir . DIRECTORY_SEPARATOR . "key.txt");
$obj["key"] = $key;
$obj["version"] = $i;
for ($i = 1; $i <= $curVer; $i++) { // run through all the file versions
$obj = [];
$dataObj = [];
$verDir = getVersionDir($histDir, $i); // get the path to the file version
if ($i == 1) { // check if the version number is equal to 1
// get meta data of this file
$createdInfo = file_get_contents($histDir . DIRECTORY_SEPARATOR . "createdInfo.json");
$json = json_decode($createdInfo, true); // decode the meta data from the createdInfo.json file
$key = $i == $curVer ? $docKey : file_get_contents($verDir . DIRECTORY_SEPARATOR . "key.txt"); // get document key
$obj["key"] = $key;
$obj["version"] = $i;
if ($i == 1) { // check if the version number is equal to 1
$createdInfo = file_get_contents($histDir . DIRECTORY_SEPARATOR . "createdInfo.json"); // get meta data of this file
$json = json_decode($createdInfo, true); // decode the meta data from the createdInfo.json file
$obj["created"] = $json["created"];
$obj["user"] = [
"id" => $json["uid"],
"name" => $json["name"]
];
}
$fileExe = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
$prevFileName = $verDir . DIRECTORY_SEPARATOR . "prev." . $filetype;
$prevFileName = substr($prevFileName, strlen(getStoragePath("")));
$dataObj["fileType"] = $fileExe;
$dataObj["key"] = $key;
$directUrl = $i == $curVer ? FileUri($filename, FALSE) : getHistoryDownloadUrl($filename, $i, "prev.".$fileExe, FALSE);
$prevFileUrl = $i == $curVer ? $fileuri : getHistoryDownloadUrl($filename, $i, "prev.".$fileExe);
if (realpath($storagePath) === $storagePath) {
$prevFileUrl = $i == $curVer ? getDownloadUrl($filename) : getHistoryDownloadUrl($filename, $i, "prev.".$fileExe);
if ($isEnableDirectUrl) {
$directUrl = $i == $curVer ? getDownloadUrl($filename, FALSE) : getHistoryDownloadUrl($filename, $i, "prev.".$fileExe, FALSE);
}
}
$dataObj["url"] = $prevFileUrl; // write file url to the data object
if ($isEnableDirectUrl) {
$dataObj["directUrl"] = $directUrl; // write direct url to the data object
}
$dataObj["version"] = $i;
if ($i > 1) { // check if the version number is greater than 1 (the document was modified)
$changes = json_decode(file_get_contents(getVersionDir($histDir, $i - 1) . DIRECTORY_SEPARATOR . "changes.json"), true); // get the path to the changes.json file
$change = $changes["changes"][0];
$obj["changes"] = $changes ? $changes["changes"] : null; // write information about changes to the object
$obj["serverVersion"] = $changes["serverVersion"];
$obj["created"] = $change ? $change["created"] : null;
$obj["user"] = $change ? $change["user"] : null;
$prev = $histData[$i - 2]; // get the history data from the previous file version
$dataObj["previous"] = $isEnableDirectUrl ? [ // write information about previous file version to the data object
"fileType" => $prev["fileType"],
"key" => $prev["key"],
"url" => $prev["url"],
"directUrl" => $prev["directUrl"]
] : [
"fileType" => $prev["fileType"],
"key" => $prev["key"],
"url" => $prev["url"]
];
// write the path to the diff.zip archive with differences in this file version
$dataObj["changesUrl"] = getHistoryDownloadUrl($filename, $i - 1, "diff.zip");
}
if (isJwtEnabled()) {
$dataObj["token"] = jwtEncode($dataObj);
}
array_push($hist, $obj); // add object dictionary to the hist list
$histData[$i - 1] = $dataObj; // write data object information to the history data
$obj["created"] = $json["created"];
$obj["user"] = [
"id" => $json["uid"],
"name" => $json["name"],
];
}
// write history information about the current file version
$out = [];
array_push($out, [
"currentVersion" => $curVer,
"history" => $hist
],
$histData);
return $out;
$fileExe = mb_strtolower(pathinfo($filename, PATHINFO_EXTENSION));
$prevFileName = $verDir . DIRECTORY_SEPARATOR . "prev." . $filetype;
$prevFileName = mb_substr($prevFileName, mb_strlen(getStoragePath("")));
$dataObj["fileType"] = $fileExe;
$dataObj["key"] = $key;
$directUrl = $i == $curVer ? fileUri($filename, false) :
getHistoryDownloadUrl($filename, $i, "prev.".$fileExe, false);
$prevFileUrl = $i == $curVer ? $fileuri : getHistoryDownloadUrl($filename, $i, "prev.".$fileExe);
if (realpath($storagePath) === $storagePath) {
$prevFileUrl = $i == $curVer ? getDownloadUrl($filename) :
getHistoryDownloadUrl($filename, $i, "prev.".$fileExe);
if ($isEnableDirectUrl) {
$directUrl = $i == $curVer ? getDownloadUrl($filename, false) :
getHistoryDownloadUrl($filename, $i, "prev.".$fileExe, false);
}
}
$dataObj["url"] = $prevFileUrl; // write file url to the data object
if ($isEnableDirectUrl) {
$dataObj["directUrl"] = $directUrl; // write direct url to the data object
}
$dataObj["version"] = $i;
if ($i > 1) { // check if the version number is greater than 1 (the document was modified)
$changes = json_decode(file_get_contents(getVersionDir($histDir, $i - 1) .
DIRECTORY_SEPARATOR . "changes.json"), true); // get the path to the changes.json file
$change = $changes["changes"][0];
// write information about changes to the object
$obj["changes"] = $changes ? $changes["changes"] : null;
$obj["serverVersion"] = $changes["serverVersion"];
$obj["created"] = $change ? $change["created"] : null;
$obj["user"] = $change ? $change["user"] : null;
$prev = $histData[$i - 2]; // get the history data from the previous file version
// write information about previous file version to the data object
$dataObj["previous"] = $isEnableDirectUrl ? [
"fileType" => $prev["fileType"],
"key" => $prev["key"],
"url" => $prev["url"],
"directUrl" => $prev["directUrl"],
] : [
"fileType" => $prev["fileType"],
"key" => $prev["key"],
"url" => $prev["url"],
];
// write the path to the diff.zip archive with differences in this file version
$dataObj["changesUrl"] = getHistoryDownloadUrl($filename, $i - 1, "diff.zip");
}
if (isJwtEnabled()) {
$dataObj["token"] = jwtEncode($dataObj);
}
$hist[] = $obj; // add object dictionary to the hist list
$histData[$i - 1] = $dataObj; // write data object information to the history data
}
// write history information about the current file version
$out = [];
array_push(
$out,
[
"currentVersion" => $curVer,
"history" => $hist,
],
$histData
);
return $out;
}
}
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no, minimal-ui" />
<meta name="viewport" content="width=device-width, initial-scale=1,
maximum-scale=1, minimum-scale=1, user-scalable=no, minimal-ui" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="mobile-web-app-capable" content="yes" />
<link rel="icon" href="css/images/<?php echo getDocumentType($filename) ?>.ico" type="image/x-icon" />
@ -389,7 +463,9 @@
}
</style>
<script type="text/javascript" src="<?php echo $GLOBALS["DOC_SERV_SITE_URL"].$GLOBALS["DOC_SERV_API_URL"] ?>"></script>
<script type="text/javascript" src="
<?php echo $GLOBALS["DOC_SERV_SITE_URL"].$GLOBALS["DOC_SERV_API_URL"] ?>">
</script>
<script type="text/javascript">
@ -437,7 +513,8 @@
if (actionIndex != -1) {
var endIndex = href.indexOf("&", actionIndex + "&actionLink=".length);
if (endIndex != -1) {
link = href.substring(0, actionIndex) + href.substring(endIndex) + "&actionLink=" + encodeURIComponent(linkParam);
link = href.substring(0, actionIndex) + href.substring(endIndex) +
"&actionLink=" + encodeURIComponent(linkParam);
} else {
link = href.substring(0, actionIndex) + "&actionLink=" + encodeURIComponent(linkParam);
}
@ -447,11 +524,13 @@
return link;
}
// the user is trying to get link for opening the document which contains a bookmark, scrolling to the bookmark position
// the user is trying to get link for opening the document which contains a bookmark,
// scrolling to the bookmark position
var onMakeActionLink = function (event) {
var actionData = event.data;
var linkParam = JSON.stringify(actionData);
docEditor.setActionLink(replaceActionLink(location.href, linkParam)); // set the link to the document which contains a bookmark
// set the link to the document which contains a bookmark
docEditor.setActionLink(replaceActionLink(location.href, linkParam));
};
// the meta information of the document is changed via the meta command
@ -470,7 +549,11 @@
var onRequestInsertImage = function(event) {
docEditor.insertImage({ // insert an image into the file
"c": event.data.c,
<?php echo mb_strimwidth(json_encode($dataInsertImage), 1, strlen(json_encode($dataInsertImage)) - 2)?>
<?php echo mb_strimwidth(
json_encode($dataInsertImage),
1,
mb_strlen(json_encode($dataInsertImage)) - 2
)?>
})
};
@ -481,7 +564,8 @@
// the user is trying to select recipients data by clicking the Mail merge button
var onRequestMailMergeRecipients = function (event) {
docEditor.setMailMergeRecipients(<?php echo json_encode($dataMailMergeRecipients) ?>); // insert recipient data for mail merge into the file
// insert recipient data for mail merge into the file
docEditor.setMailMergeRecipients(<?php echo json_encode($dataMailMergeRecipients) ?>);
};
var onRequestSaveAs = function (event) { // the user is trying to save file by clicking Save Copy as... button
@ -522,11 +606,11 @@
var сonnectEditor = function () {
<?php
if (!file_exists(getStoragePath($filename))) {
echo "alert('File not found'); return;";
}
?>
<?php
if (!file_exists(getStoragePath($filename))) {
echo "alert('File not found'); return;";
}
?>
config = <?php echo json_encode($config) ?>;
@ -547,28 +631,30 @@
};
<?php
$out = getHistory($filename, $filetype, $docKey, $fileuri, $isEnableDirectUrl);
$history = $out[0];
$historyData = $out[1];
$out = getHistory($filename, $filetype, $docKey, $fileuri, $isEnableDirectUrl);
$history = $out[0];
$historyData = $out[1];
?>
<?php if ($user->id != "uid-0"): ?>
<?php if ($history != null && $historyData != null): ?>
<?php if ($user->id != "uid-0") { ?>
<?php if ($history != null && $historyData != null) { ?>
// the user is trying to show the document version history
config.events['onRequestHistory'] = function () {
docEditor.refreshHistory(<?php echo json_encode($history) ?>); // show the document version history
// show the document version history
docEditor.refreshHistory(<?php echo json_encode($history) ?>);
};
// the user is trying to click the specific document version in the document version history
config.events['onRequestHistoryData'] = function (event) {
var ver = event.data;
var histData = <?php echo json_encode($historyData) ?>;
docEditor.setHistoryData(histData[ver - 1]); // send the link to the document for viewing the version history
// send the link to the document for viewing the version history
docEditor.setHistoryData(histData[ver - 1]);
};
// the user is trying to go back to the document from viewing the document version history
config.events['onRequestHistoryClose'] = function () {
document.location.reload();
};
<?php endif; ?>
<?php } ?>
// add mentions for not anonymous users
config.events['onRequestUsers'] = function () {
docEditor.setUsers({ // set a list of users to mention in the comments
@ -583,7 +669,7 @@
};
// prevent file renaming for anonymous users
config.events['onRequestRename'] = onRequestRename;
<?php endif; ?>
<?php } ?>
if (config.editorConfig.createUrl) {
config.events.onRequestSaveAs = onRequestSaveAs;

View File

@ -1,6 +1,5 @@
<?php
/**
*
* (c) Copyright Ascensio System SIA 2023
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -14,28 +13,33 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
require_once( dirname(__FILE__) . '/config.php' );
require_once( dirname(__FILE__) . '/jwtmanager.php' );
require_once dirname(__FILE__) . '/config.php';
require_once dirname(__FILE__) . '/jwtmanager.php';
// file uploading
function DoUpload($fileUri) {
/**
* File uploading
*
* @param string $fileUri
*
* @throws Exception If file type is not supported or copy operation is unsuccessful
*
* @return null
*/
function doUpload($fileUri)
{
$_fileName = GetCorrectName($fileUri);
// check if file extension is supported by the editor
$ext = strtolower('.' . pathinfo($_fileName, PATHINFO_EXTENSION));
if (!in_array($ext, getFileExts()))
{
$ext = mb_strtolower('.' . pathinfo($_fileName, PATHINFO_EXTENSION));
if (!in_array($ext, getFileExts())) {
throw new Exception("File type is not supported");
}
// check if the file copy operation is successful
if(!@copy($fileUri, getStoragePath($_fileName)))
{
$errors= error_get_last();
if (!@copy($fileUri, getStoragePath($_fileName))) {
$errors = error_get_last();
$err = "Copy file error: " . $errors['type'] . "<br />\n" . $errors['message'];
throw new Exception($err);
}
@ -43,21 +47,22 @@ function DoUpload($fileUri) {
return $_fileName;
}
/**
* Generate an error code table
*
* @param string $errorCode Error code
*
* @return null
*/
function ProcessConvServResponceError($errorCode) {
* Generate an error code table
*
* @param string $errorCode Error code
*
* @throws Exception If error code is unknown
*
* @return null
*/
function processConvServResponceError($errorCode)
{
$errorMessageTemplate = "Error occurred in the document service: ";
$errorMessage = '';
// add the error message to the error message template depending on the error code
switch ($errorCode)
{
switch ($errorCode) {
case -8:
$errorMessage = $errorMessageTemplate . "Error document VKey";
break;
@ -92,38 +97,48 @@ function ProcessConvServResponceError($errorCode) {
throw new Exception($errorMessage);
}
/**
* Translation key to a supported form.
*
* @param string $expected_key Expected key
*
* @return Supported key
*/
function GenerateRevisionId($expected_key) {
if (strlen($expected_key) > 20) $expected_key = crc32( $expected_key); // if the expected key length is greater than 20, calculate the crc32 for it
* Translation key to a supported form.
*
* @param string $expected_key Expected key
*
* @return string key
*/
function generateRevisionId($expected_key)
{
if (mb_strlen($expected_key) > 20) {
$expected_key = crc32($expected_key);
} // if the expected key length is greater than 20, calculate the crc32 for it
$key = preg_replace("[^0-9-.a-zA-Z_=]", "_", $expected_key);
$key = substr($key, 0, min(array(strlen($key), 20))); // the resulting key length is 20 or less
$key = mb_substr($key, 0, min([mb_strlen($key), 20])); // the resulting key length is 20 or less
return $key;
}
/**
* Request for conversion to a service.
*
* @param string $document_uri Uri for the document to convert
* @param string $from_extension Document extension
* @param string $to_extension Extension to which to convert
* @param string $document_revision_id Key for caching on service
* @param bool $is_async Perform conversions asynchronously
*
* @return Document request result of conversion
*/
function SendRequestToConvertService($document_uri, $from_extension, $to_extension, $document_revision_id, $is_async, $filePass, $lang) {
if (empty($from_extension))
{
* Request for conversion to a service.
*
* @param string $document_uri Uri for the document to convert
* @param string $from_extension Document extension
* @param string $to_extension Extension to which to convert
* @param string $document_revision_id Key for caching on service
* @param bool $is_async Perform conversions asynchronously
* @param string $filePass
* @param string $lang
*
* @return string request result of conversion
*/
function sendRequestToConvertService(
$document_uri,
$from_extension,
$to_extension,
$document_revision_id,
$is_async,
$filePass,
$lang
) {
if (empty($from_extension)) {
$path_parts = pathinfo($document_uri);
$from_extension = strtolower($path_parts['extension']);
$from_extension = mb_strtolower($path_parts['extension']);
}
// if title is undefined, then replace it with a random guid
@ -137,19 +152,19 @@ function SendRequestToConvertService($document_uri, $from_extension, $to_extensi
}
// generate document token
$document_revision_id = GenerateRevisionId($document_revision_id);
$document_revision_id = generateRevisionId($document_revision_id);
$urlToConverter = $GLOBALS['DOC_SERV_SITE_URL'].$GLOBALS['DOC_SERV_CONVERTER_URL'];
$arr = [
"async" => $is_async,
"url" => $document_uri,
"outputtype" => trim($to_extension,'.'),
"outputtype" => trim($to_extension, '.'),
"filetype" => trim($from_extension, '.'),
"title" => $title,
"key" => $document_revision_id,
"password" => $filePass,
"region" => $lang
"region" => $lang,
];
// add header token
@ -157,88 +172,111 @@ function SendRequestToConvertService($document_uri, $from_extension, $to_extensi
$jwtHeader = $GLOBALS['DOC_SERV_JWT_HEADER'] == "" ? "Authorization" : $GLOBALS['DOC_SERV_JWT_HEADER'];
if (isJwtEnabled()) {
$headerToken = jwtEncode([ "payload" => $arr ]);
$headerToken = jwtEncode(["payload" => $arr]);
$arr["token"] = jwtEncode($arr);
}
$data = json_encode($arr);
// request parameters
$opts = array('http' => array(
'method' => 'POST',
'timeout' => $GLOBALS['DOC_SERV_TIMEOUT'],
'header'=> "Content-type: application/json\r\n" .
"Accept: application/json\r\n" .
(empty($headerToken) ? "" : $jwtHeader.": Bearer $headerToken\r\n"),
'content' => $data
)
);
$opts = ['http' => [
'method' => 'POST',
'timeout' => $GLOBALS['DOC_SERV_TIMEOUT'],
'header' => "Content-type: application/json\r\n" .
"Accept: application/json\r\n" .
(empty($headerToken) ? "" : $jwtHeader.": Bearer $headerToken\r\n"),
'content' => $data,
],
];
if (substr($urlToConverter, 0, strlen("https")) === "https") {
if($GLOBALS['DOC_SERV_VERIFY_PEER_OFF'] === TRUE) {
$opts['ssl'] = array( 'verify_peer' => FALSE, 'verify_peer_name' => FALSE );
if (mb_substr($urlToConverter, 0, mb_strlen("https")) === "https") {
if ($GLOBALS['DOC_SERV_VERIFY_PEER_OFF'] === true) {
$opts['ssl'] = ['verify_peer' => false, 'verify_peer_name' => false];
}
}
$context = stream_context_create($opts);
$response_data = file_get_contents($urlToConverter, FALSE, $context);
$response_data = file_get_contents($urlToConverter, false, $context);
return $response_data;
}
/**
* The method is to convert the file to the required format.
*
* Example:
* string convertedDocumentUri;
* GetConvertedUri("http://helpcenter.onlyoffice.com/content/GettingStarted.pdf", ".pdf", ".docx", "http://helpcenter.onlyoffice.com/content/GettingStarted.pdf", false, out convertedDocumentUri);
*
* @param string $document_uri Uri for the document to convert
* @param string $from_extension Document extension
* @param string $to_extension Extension to which to convert
* @param string $document_revision_id Key for caching on service
* @param bool $is_async Perform conversions asynchronously
* @param string $converted_document_uri Uri to the converted document
*
* @return The percentage of completion of conversion
*/
function GetConvertedUri($document_uri, $from_extension, $to_extension, $document_revision_id, $is_async, &$converted_document_uri, $filePass, $lang) {
* The method is to convert the file to the required format.
*
* Example:
* string convertedDocumentUri;
* getConvertedUri("http://helpcenter.onlyoffice.com/content/GettingStarted.pdf",
* ".pdf", ".docx", "http://helpcenter.onlyoffice.com/content/GettingStarted.pdf", false, out convertedDocumentUri);
*
* @param string $document_uri Uri for the document to convert
* @param string $from_extension Document extension
* @param string $to_extension Extension to which to convert
* @param string $document_revision_id Key for caching on service
* @param bool $is_async Perform conversions asynchronously
* @param string $converted_document_uri Uri to the converted document
* @param string $filePass File pass
* @param string $lang Language
*
* @throws Exception if an error occurs
*
* @return int percentage of completion of conversion
*/
function getConvertedUri(
$document_uri,
$from_extension,
$to_extension,
$document_revision_id,
$is_async,
&$converted_document_uri,
$filePass,
$lang
) {
$converted_document_uri = "";
$responceFromConvertService = SendRequestToConvertService($document_uri, $from_extension, $to_extension, $document_revision_id, $is_async, $filePass, $lang);
$responceFromConvertService = sendRequestToConvertService(
$document_uri,
$from_extension,
$to_extension,
$document_revision_id,
$is_async,
$filePass,
$lang
);
$json = json_decode($responceFromConvertService, true);
// if an error occurs, then display an error message
$errorElement = $json["error"];
if ($errorElement != NULL && $errorElement != "") ProcessConvServResponceError($errorElement);
if ($errorElement != null && $errorElement != "") {
processConvServResponceError($errorElement);
}
$isEndConvert = $json["endConvert"];
$percent = $json["percent"];
// if the conversion is completed successfully
if ($isEndConvert != NULL && $isEndConvert == true)
{
if ($isEndConvert != null && $isEndConvert == true) {
// then get the file url
$converted_document_uri = $json["fileUrl"];
$percent = 100;
}
// otherwise, get the percentage of conversion completion
else if ($percent >= 100)
} elseif ($percent >= 100) { // otherwise, get the percentage of conversion completion
$percent = 99;
}
return $percent;
}
/**
* Processing document received from the editing service.
*
* @param string $document_response The result from editing service
* @param string $response_uri Uri to the converted document
*
* @return The percentage of completion of conversion
*/
function GetResponseUri($document_response, &$response_uri) {
* Processing document received from the editing service.
*
* @param Response $document_response The result from editing service
* @param string $response_uri Uri to the converted document
*
* @throws Exception if an error occurs
*
* @return int percentage of completion of conversion
*/
function getResponseUri($document_response, &$response_uri)
{
$response_uri = "";
$resultPercent = 0;
@ -248,33 +286,35 @@ function GetResponseUri($document_response, &$response_uri) {
// if an error occurs, then display an error message
$errorElement = $document_response->Error;
if ($errorElement != NULL && $errorElement != "") ProcessConvServResponceError($document_response->Error);
if ($errorElement != null && $errorElement != "") {
processConvServResponceError($document_response->Error);
}
$endConvert = $document_response->EndConvert;
if ($endConvert != NULL && $endConvert == "") throw new Exception("Invalid answer format");
if ($endConvert != null && $endConvert == "") {
throw new Exception("Invalid answer format");
}
// if the conversion is completed successfully
if ($endConvert != NULL && strtolower($endConvert) == true)
{
if ($endConvert != null && mb_strtolower($endConvert) == true) {
$fileUrl = $document_response->FileUrl;
if ($fileUrl == NULL || $fileUrl == "") throw new Exception("Invalid answer format");
if ($fileUrl == null || $fileUrl == "") {
throw new Exception("Invalid answer format");
}
// get the response file url
$response_uri = $fileUrl;
$resultPercent = 100;
}
// otherwise, get the percentage of conversion completion
else
{
} else { // otherwise, get the percentage of conversion completion
$percent = $document_response->Percent;
if ($percent != NULL && $percent != "")
if ($percent != null && $percent != "") {
$resultPercent = $percent;
if ($resultPercent >= 100)
}
if ($resultPercent >= 100) {
$resultPercent = 99;
}
}
return $resultPercent;
}
?>

View File

@ -1,32 +1,34 @@
<?php
/**
*
* (c) Copyright Ascensio System SIA 2023
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
require_once( dirname(__FILE__) . '/config.php' );
require_once( dirname(__FILE__) . '/common.php' );
require_once( dirname(__FILE__) . '/functions.php' );
require_once( dirname(__FILE__) . '/users.php' );
namespace PhpExample;
$user = $_GET["user"];
$directUrlArg = $_GET["directUrl"] != null ? "&directUrl=" . $_GET["directUrl"] : "";
/**
* (c) Copyright Ascensio System SIA 2023
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
require_once dirname(__FILE__) . '/config.php';
require_once dirname(__FILE__) . '/common.php';
require_once dirname(__FILE__) . '/functions.php';
require_once dirname(__FILE__) . '/users.php';
$user = $_GET["user"] ?? "";
$directUrlArg = isset($_GET["directUrl"]) ? "&directUrl=" . $_GET["directUrl"] : "";
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html lang="en">
<head>
@ -36,7 +38,8 @@
<link rel="icon" href="./favicon.ico" type="image/x-icon" />
<link rel="stylesheet" type="text/css" href="https://fonts.googleapis.com/css?family=Open+Sans:900,800,700,600,500,400,300&subset=latin,cyrillic-ext,cyrillic,latin-ext" />
<link rel="stylesheet" type="text/css" href="https://fonts.googleapis.com/css?family=Open+Sans:900,
800,700,600,500,400,300&subset=latin,cyrillic-ext,cyrillic,latin-ext" />
<link rel="stylesheet" type="text/css" href="css/stylesheet.css" />
<link rel="stylesheet" type="text/css" href="css/media.css">
@ -62,25 +65,36 @@
<div class="create-panel clearFix">
<ul class="try-editor-list clearFix">
<li>
<a class="try-editor word reload-page" target="_blank" href="doceditor.php?fileExt=docx&user=<?php echo htmlentities($user); ?>">Document</a>
<a class="try-editor word reload-page" target="_blank"
href="doceditor.php?fileExt=docx&user=
<?php echo htmlentities($user); ?>">Document</a>
</li>
<li>
<a class="try-editor cell reload-page" target="_blank" href="doceditor.php?fileExt=xlsx&user=<?php echo htmlentities($user); ?>">Spreadsheet</a>
<a class="try-editor cell reload-page" target="_blank"
href="doceditor.php?fileExt=xlsx&user=
<?php echo htmlentities($user); ?>">Spreadsheet</a>
</li>
<li>
<a class="try-editor slide reload-page" target="_blank" href="doceditor.php?fileExt=pptx&user=<?php echo htmlentities($user); ?>">Presentation</a>
<a class="try-editor slide reload-page" target="_blank"
href="doceditor.php?fileExt=pptx&user=
<?php echo htmlentities($user); ?>">Presentation</a>
</li>
<li>
<a class="try-editor form reload-page" target="_blank" href="doceditor.php?fileExt=docxf&user=<?php echo htmlentities($user); ?>">Form template</a>
<a class="try-editor form reload-page" target="_blank"
href="doceditor.php?fileExt=docxf&user=
<?php echo htmlentities($user); ?>">Form template</a>
</li>
</ul>
<label class="side-option">
<input type="checkbox" id="createSample" class="checkbox" />With sample content
<input type="checkbox" id="createSample" class="checkbox" />
With sample content
</label>
</div>
<div class="upload-panel clearFix">
<a class="file-upload">Upload file
<input type="file" id="fileupload" name="files" data-url="webeditor-ajax.php?type=upload&user=<?php echo htmlentities($user); ?>" />
<input type="file" id="fileupload" name="files"
data-url="webeditor-ajax.php?type=upload&user=
<?php echo htmlentities($user); ?>" />
</a>
</div>
@ -90,8 +104,8 @@
<span class="select-user">Username</span>
<img id="info" class="info" src="css/images/info.svg" />
<select class="select-user" id="user">
<?php foreach(getAllUsers() as $user_l) {
$name = $user_l->name ? $user_l->name : "Anonymous";
<?php foreach (getAllUsers() as $user_l) {
$name = $user_l->name ?: "Anonymous";
echo '<option value="'.$user_l->id.'">'.$name.'</option>';
} ?>
</select>
@ -113,8 +127,13 @@
<tr>
<td valign="middle">
<label class="side-option">
<input id="directUrl" type="checkbox" class="checkbox" />Try opening on client
<img id="directUrlInfo" class="info info-tooltip" data-id="directUrlInfo" data-tooltip="Some files can be opened in the user's browser without connecting to the document server." src="css/images/info.svg" />
<input id="directUrl" type="checkbox" class="checkbox" />
Try opening on client
<img id="directUrlInfo" class="info info-tooltip"
data-id="directUrlInfo" data-tooltip=
"Some files can be opened in the user's
browser without connecting to the document server."
src="css/images/info.svg" />
</label>
</td>
</tr>
@ -126,20 +145,32 @@
<div class="main-panel">
<?php
$storedFiles = getStoredFiles();
if (!empty($storedFiles)): ?>
if (!empty($storedFiles)) { ?>
<div id="portal-info" style="display: none">
<?php else: ?>
<?php } else { ?>
<div id="portal-info" style="display: table-cell">
<?php endif; ?>
<?php } ?>
<span class="portal-name">ONLYOFFICE Document Editors Welcome!</span>
<span class="portal-descr">
Get started with a demo-sample of ONLYOFFICE Document Editors, the first html5-based editors.
<br /> You may upload your own documents for testing using the "<b>Upload file</b>" button and <b>selecting</b> the necessary files on your PC.
Get started with a demo-sample of ONLYOFFICE Document Editors,
the first html5-based editors.
<br /> You may upload your own documents for testing using the
"<b>Upload file</b>" button and <b>selecting</b>
the necessary files on your PC.
</span>
<span class="portal-descr">Please do NOT use this integration example on your own server without proper code modifications, it is intended for testing purposes only. In case you enabled this test example, disable it before going for production.</span>
<span class="portal-descr">You can open the same document using different users in different Web browser sessions, so you can check out multi-user editing functions.</span>
<?php foreach(getAllUsers() as $user_l) {
$name = $user_l->name ? $user_l->name : "Anonymous";
<span class="portal-descr">
Please do NOT use this integration example on your own server without
proper code modifications, it is intended for testing purposes only.
In case you enabled this test example, disable it before going for
production.
</span>
<span class="portal-descr">
You can open the same document using different
users in different Web browser sessions, so you can check out multi-user
editing functions.
</span>
<?php foreach (getAllUsers() as $user_l) {
$name = $user_l->name ?: "Anonymous";
echo '<div class="user-descr">';
echo '<b>'.$name.'</b>';
echo '<ul>';
@ -151,17 +182,28 @@
} ?>
</div>
<?php
if (!empty($storedFiles)) { ?>
if (!empty($storedFiles)) { ?>
<div class="stored-list">
<span class="header-list">Your documents</span>
<table class="tableHeader" cellspacing="0" cellpadding="0" width="100%">
<thead>
<tr>
<td class="tableHeaderCell tableHeaderCellFileName">Filename</td>
<td class="tableHeaderCell tableHeaderCellEditors contentCells-shift">Editors</td>
<td class="tableHeaderCell tableHeaderCellViewers">Viewers</td>
<td class="tableHeaderCell tableHeaderCellDownload">Download</td>
<td class="tableHeaderCell tableHeaderCellRemove">Remove</td>
<td class="tableHeaderCell tableHeaderCellFileName">
Filename
</td>
<td class="tableHeaderCell tableHeaderCellEditors
contentCells-shift">
Editors
</td>
<td class="tableHeaderCell tableHeaderCellViewers">
Viewers
</td>
<td class="tableHeaderCell tableHeaderCellDownload">
Download
</td>
<td class="tableHeaderCell tableHeaderCellRemove">
Remove
</td>
</tr>
</thead>
</table>
@ -169,90 +211,234 @@
<table cellspacing="0" cellpadding="0" width="100%">
<tbody>
<?php foreach ($storedFiles as &$storeFile) {
echo '<tr class="tableRow" title="'.$storeFile->name.' ['.getFileVersion(getHistoryDir(getStoragePath($storeFile->name))).']">';
echo '<tr class="tableRow" title="'.
$storeFile->name.' ['.
getFileVersion(
getHistoryDir(
getStoragePath($storeFile->name)
)
).
']">';
echo ' <td class="contentCells">';
echo ' <a class="stored-edit '.$storeFile->documentType.'" href="doceditor.php?fileID='.urlencode($storeFile->name).'&user='.htmlentities($user) . $directUrlArg .'" target="_blank">';
echo ' <a class="stored-edit '.
$storeFile->documentType.
'" href="doceditor.php?fileID='.
urlencode($storeFile->name) .
'&user='.htmlentities($user) .
$directUrlArg .'" target="_blank">';
echo ' <span>'.$storeFile->name.'</span>';
echo ' </a>';
echo ' </td>';
if ($storeFile->canEdit) {
echo ' <td class="contentCells contentCells-icon">';
echo ' <a href="doceditor.php?fileID=' . urlencode($storeFile->name) . '&user=' . htmlentities($user) . $directUrlArg . '&action=edit&type=desktop" target="_blank">';
echo ' <img src="css/images/desktop.svg" alt="Open in editor for full size screens" title="Open in editor for full size screens" /></a>';
echo ' <a href="doceditor.php?fileID=' .
urlencode($storeFile->name) .
'&user=' . htmlentities($user) .
$directUrlArg .
'&action=edit&type=desktop" target="_blank">';
echo ' <img src="css/images/desktop.svg"
alt="Open in editor for full size screens"
title="Open in editor for full size screens"
/></a>';
echo ' </td>';
echo ' <td class="contentCells contentCells-icon">';
echo ' <a href="doceditor.php?fileID=' . urlencode($storeFile->name) . '&user=' . htmlentities($user) . $directUrlArg . '&action=edit&type=mobile" target="_blank">';
echo ' <img src="css/images/mobile.svg" alt="Open in editor for mobile devices" title="Open in editor for mobile devices" /></a>';
echo ' <a href="doceditor.php?fileID=' .
urlencode($storeFile->name) .
'&user=' . htmlentities($user) .
$directUrlArg .
'&action=edit&type=mobile" target="_blank">';
echo ' <img src="css/images/mobile.svg"
alt="Open in editor for mobile devices"
title="Open in editor for mobile devices"
/></a>';
echo ' </td>';
echo ' <td class="contentCells contentCells-icon">';
echo ' <a href="doceditor.php?fileID=' . urlencode($storeFile->name) . '&user=' . htmlentities($user) . $directUrlArg . '&action=comment&type=desktop" target="_blank">';
echo ' <img src="css/images/comment.svg" alt="Open in editor for comment" title="Open in editor for comment" /></a>';
echo ' <a href="doceditor.php?fileID=' .
urlencode($storeFile->name) .
'&user=' .
htmlentities($user) .
$directUrlArg .
'&action=comment&type=desktop" target="_blank">'
;
echo ' <img src="css/images/comment.svg"
alt="Open in editor for comment"
title="Open in editor for comment" />
</a>';
echo ' </td>';
if ($storeFile->documentType == "word") {
echo ' <td class="contentCells contentCells-icon">';
echo ' <a href="doceditor.php?fileID=' . urlencode($storeFile->name) . '&user=' . htmlentities($user) . $directUrlArg . '&action=review&type=desktop" target="_blank">';
echo ' <img src="css/images/review.svg" alt="Open in editor for review" title="Open in editor for review" /></a>';
echo ' <td
class="contentCells contentCells-icon">';
echo ' <a href="doceditor.php?fileID=' .
urlencode($storeFile->name) .
'&user=' .
htmlentities($user) .
$directUrlArg .
'&action=review&type=desktop"
target="_blank">';
echo ' <img src="css/images/review.svg"
alt="Open in editor for review"
title="Open in editor for review" />
</a>';
echo ' </td>';
} else if ($storeFile->documentType == "cell") {
echo ' <td class="contentCells contentCells-icon">';
echo ' <a href="doceditor.php?fileID=' . urlencode($storeFile->name) . '&user=' . htmlentities($user) . $directUrlArg . '&action=filter&type=desktop" target="_blank">';
echo ' <img src="css/images/filter.svg" alt="Open in editor without access to change the filter" title="Open in editor without access to change the filter" /></a>';
} elseif ($storeFile->documentType == "cell") {
echo ' <td class="contentCells
contentCells-icon">';
echo ' <a href="doceditor.php?fileID=' .
urlencode($storeFile->name) .
'&user=' .
htmlentities($user) .
$directUrlArg .
'&action=filter&type=desktop"
target="_blank">';
echo ' <img src="css/images/filter.svg"
alt="Open in editor without
access to change the filter"
title="Open in editor without
access to change the filter" /></a>';
echo ' </td>';
}
if ($storeFile->documentType == "word") {
echo ' <td class="contentCells contentCells-icon ">';
echo ' <a href="doceditor.php?fileID=' . urlencode($storeFile->name) . '&user=' . htmlentities($user) . $directUrlArg . '&action=blockcontent&type=desktop" target="_blank">';
echo ' <img src="css/images/block-content.svg" alt="Open in editor without content control modification" title="Open in editor without content control modification" /></a>';
echo ' </td>';
} else{
echo ' <td class="contentCells contentCells-icon"></td> ';
}
if($storeFile->documentType!="word" && $storeFile->documentType!="cell"){
echo ' <td class="contentCells contentCells-icon"></td>';
}
if ($storeFile->isFillFormDoc) {
echo ' <td class="contentCells contentCells-shift contentCells-icon firstContentCellShift">';
echo ' <a href="doceditor.php?fileID=' . urlencode($storeFile->name) . '&user=' . htmlentities($user) . $directUrlArg . '&action=fillForms&type=desktop" target="_blank">';
echo ' <img src="css/images/fill-forms.svg" alt="Open in editor for filling in forms" title="Open in editor for filling in forms" /></a>';
echo ' <td class="contentCells
contentCells-icon ">';
echo ' <a href="doceditor.php?fileID=' .
urlencode($storeFile->name) .
'&user=' .
htmlentities($user) .
$directUrlArg .
'&action=blockcontent&type=desktop"
target="_blank">';
echo ' <img src="css/images/block-content.svg"
alt="Open in editor without
content control modification"
title="Open in editor without
content control modification" /></a>';
echo ' </td>';
} else {
echo ' <td class="contentCells contentCells-shift contentCells-icon firstContentCellShift"></td> ';
echo ' <td class="contentCells
contentCells-icon"></td> ';
}
} else if ($storeFile->isFillFormDoc) {
echo ' <td class="contentCells contentCells-icon"></td>';
echo ' <td class="contentCells contentCells-icon">';
echo ' <a href="doceditor.php?fileID=' . urlencode($storeFile->name) . '&user=' . htmlentities($user) . $directUrlArg . '&action=fillForms&type=desktop" target="_blank">';
echo ' <img src="css/images/mobile-fill-forms.svg" alt="Open in editor for filling in forms for mobile devices" title="Open in editor for filling in forms for mobile devices" /></a>';
if ($storeFile->documentType != "word"
&& $storeFile->documentType != "cell"
) {
echo ' <td class="contentCells
contentCells-icon"></td>';
}
if ($storeFile->isFillFormDoc) {
echo ' <td class="contentCells
contentCells-shift contentCells-icon
firstContentCellShift">';
echo ' <a href="doceditor.php?fileID=' .
urlencode($storeFile->name) .
'&user=' .
htmlentities($user) .
$directUrlArg .
'&action=fillForms&type=desktop"
target="_blank">';
echo ' <img src="css/images/fill-forms.svg"
alt="Open in editor for filling in forms"
title="Open in editor for filling in forms"
/></a>';
echo ' </td>';
} else {
echo ' <td class="contentCells
contentCells-shift contentCells-icon
firstContentCellShift"></td> ';
}
} elseif ($storeFile->isFillFormDoc) {
echo ' <td class="contentCells
contentCells-icon"></td>';
echo ' <td class="contentCells
contentCells-icon">';
echo ' <a href="doceditor.php?fileID=' .
urlencode($storeFile->name) .
'&user=' .
htmlentities($user) .
$directUrlArg .
'&action=fillForms&type=desktop"
target="_blank">';
echo ' <img src="css/images/mobile-fill-forms.svg"
alt="Open in editor for filling in forms
for mobile devices"
title="Open in editor for filling in forms
for mobile devices" /></a>';
echo ' </td>';
echo ' <td class="contentCells contentCells-icon"></td>';
echo ' <td class="contentCells contentCells-icon"></td>';
echo ' <td class="contentCells contentCells-icon"></td>';
echo ' <td class="contentCells contentCells-shift contentCells-icon firstContentCellShift">';
echo ' <a href="doceditor.php?fileID=' . urlencode($storeFile->name) . '&user=' . htmlentities($user) . $directUrlArg . '&action=fillForms&type=desktop" target="_blank">';
echo ' <img src="css/images/fill-forms.svg" alt="Open in editor for filling in forms" title="Open in editor for filling in forms" /></a>';
echo ' <td class="contentCells
contentCells-icon"></td>';
echo ' <td class="contentCells
contentCells-icon"></td>';
echo ' <td class="contentCells
contentCells-icon"></td>';
echo ' <td class="contentCells
contentCells-shift contentCells-icon
firstContentCellShift">';
echo ' <a href="doceditor.php?fileID=' .
urlencode($storeFile->name) .
'&user=' .
htmlentities($user) .
$directUrlArg .
'&action=fillForms&type=desktop"
target="_blank">';
echo ' <img src="css/images/fill-forms.svg"
alt="Open in editor for filling in forms"
title="Open in editor for filling in forms"
/></a>';
echo ' </td>';
} else {
echo '<td class="contentCells contentCells-shift contentCells-icon contentCellsEmpty" colspan="6"></td>';
echo '<td class="contentCells
contentCells-shift contentCells-icon
contentCellsEmpty" colspan="6"></td>';
}
echo ' <td class="contentCells contentCells-icon firstContentCellViewers">';
echo ' <a href="doceditor.php?fileID='.urlencode($storeFile->name).'&user='.htmlentities($user) . $directUrlArg . '&action=view&type=desktop" target="_blank">';
echo ' <img src="css/images/desktop.svg" alt="Open in viewer for full size screens" title="Open in viewer for full size screens" /></a>';
echo ' <td class="contentCells
contentCells-icon firstContentCellViewers">';
echo ' <a href="doceditor.php?fileID='.
urlencode($storeFile->name).
'&user='.htmlentities($user).
$directUrlArg.
'&action=view&type=desktop" target="_blank">';
echo ' <img src="css/images/desktop.svg"
alt="Open in viewer for full size screens"
title="Open in viewer for full size screens"
/></a>';
echo ' </td>';
echo ' <td class="contentCells contentCells-icon">';
echo ' <a href="doceditor.php?fileID='.urlencode($storeFile->name).'&user='.htmlentities($user) . $directUrlArg . '&action=view&type=mobile" target="_blank">';
echo ' <img src="css/images/mobile.svg" alt="Open in viewer for mobile devices" title="Open in viewer for mobile devices" /></a>';
echo ' <a href="doceditor.php?fileID='.
urlencode($storeFile->name).
'&user='.htmlentities($user).
$directUrlArg.
'&action=view&type=mobile" target="_blank">';
echo ' <img src="css/images/mobile.svg"
alt="Open in viewer for mobile devices"
title="Open in viewer for mobile devices" /></a>';
echo ' </td>';
echo ' <td class="contentCells contentCells-icon contentCells-shift">';
echo ' <a href="doceditor.php?fileID='.urlencode($storeFile->name).'&user='.htmlentities($user) . $directUrlArg . '&action=embedded&type=embedded" target="_blank">';
echo ' <img src="css/images/embeded.svg" alt="Open in embedded mode" title="Open in embedded mode" /></a>';
echo ' <td class="contentCells
contentCells-icon contentCells-shift">';
echo ' <a href="doceditor.php?fileID='.
urlencode($storeFile->name).
'&user='.
htmlentities($user).
$directUrlArg.
'&action=embedded&type=embedded" target="_blank">';
echo ' <img src="css/images/embeded.svg"
alt="Open in embedded mode"
title="Open in embedded mode" /></a>';
echo ' </td>';
echo ' <td class="contentCells contentCells-icon contentCells-shift downloadContentCellShift">';
echo ' <a href="webeditor-ajax.php?type=download&fileName='.urlencode($storeFile->name).'">';
echo ' <img class="icon-download" src="css/images/download.svg" alt="Download" title="Download" /></a>';
echo ' <td class="contentCells
contentCells-icon contentCells-shift
downloadContentCellShift">';
echo ' <a href="
webeditor-ajax.php?type=download&fileName='.
urlencode($storeFile->name).'">';
echo ' <img class="icon-download"
src="css/images/download.svg"
alt="Download" title="Download" /></a>';
echo ' </td>';
echo ' <td class="contentCells contentCells-icon contentCells-shift">';
echo ' <a class="delete-file" data="'.$storeFile->name.'">';
echo ' <img class="icon-delete" src="css/images/delete.svg" alt="Delete" title="Delete" /></a>';
echo ' <td class="contentCells
contentCells-icon contentCells-shift">';
echo ' <a class="delete-file" data="'.
$storeFile->name.'">';
echo ' <img class="icon-delete"
src="css/images/delete.svg"
alt="Delete" title="Delete" /></a>';
echo ' </td>';
echo '</tr>';
} ?>
@ -260,8 +446,8 @@
</table>
</div>
</div>
<?php
} ?>
<?php
} ?>
</div>
</td>
</tr>
@ -274,7 +460,8 @@
<span id="uploadFileName" class="uploadFileName"></span>
<div class="describeUpload">After these steps are completed, you can work with your document.</div>
<span id="step1" class="step">1. Loading the file.</span>
<span class="step-descr">The loading speed depends on file size and additional elements it contains.</span>
<span class="step-descr">The loading speed depends on file size
and additional elements it contains.</span>
<br />
<span id="step2" class="step">2. Conversion.</span>
<span class="step-descr">The file is converted to OOXML so that you can edit it.</span>
@ -294,7 +481,8 @@
<span class="step-descr">They are loaded only once, they will be cached on your computer.</span>
<input type="hidden" name="hiddenFileName" id="hiddenFileName" />
<br />
<span class="progress-descr">Note the speed of all operations depends on your connection quality and server location.</span>
<span class="progress-descr">Note the speed of all operations depends
on your connection quality and server location.</span>
<br />
<div class="error-message">
<b>Upload error: </b><span></span>
@ -302,7 +490,8 @@
Please select another file and try again.
</div>
</div>
<iframe id="embeddedView" src="" height="345px" width="432px" frameborder="0" scrolling="no" allowtransparency></iframe>
<iframe id="embeddedView" src="" height="345px" width="432px"
frameborder="0" scrolling="no" allowtransparency></iframe>
<br />
<div class="buttonsMobile">
<?php if (($GLOBALS['MODE']) != "view") { ?>
@ -314,7 +503,9 @@
</div>
</div>
<span id="loadScripts" data-docs="<?php echo $GLOBALS['DOC_SERV_SITE_URL'].$GLOBALS['DOC_SERV_PRELOADER_URL'] ?>"></span>
<span id="loadScripts" data-docs="
<?php echo $GLOBALS['DOC_SERV_SITE_URL'].$GLOBALS['DOC_SERV_PRELOADER_URL'] ?>
"></span>
<footer>
<div class="center">
@ -322,7 +513,9 @@
<tbody>
<tr>
<td>
<a href="http://api.onlyoffice.com/editors/howitworks" target="_blank">API Documentation</a>
<a href="http://api.onlyoffice.com/editors/howitworks" target="_blank">
API Documentation
</a>
</td>
<td>
<a href="mailto:sales@onlyoffice.com">Submit your request</a>

View File

@ -1,6 +1,5 @@
<?php
/**
*
* (c) Copyright Ascensio System SIA 2023
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -14,33 +13,50 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
require_once( dirname(__FILE__) . '/lib/jwt/BeforeValidException.php' );
require_once( dirname(__FILE__) . '/lib/jwt/ExpiredException.php' );
require_once( dirname(__FILE__) . '/lib/jwt/SignatureInvalidException.php' );
require_once( dirname(__FILE__) . '/lib/jwt/JWT.php' );
require_once( dirname(__FILE__) . '/config.php' );
require_once dirname(__FILE__) . '/lib/jwt/BeforeValidException.php';
require_once dirname(__FILE__) . '/lib/jwt/ExpiredException.php';
require_once dirname(__FILE__) . '/lib/jwt/SignatureInvalidException.php';
require_once dirname(__FILE__) . '/lib/jwt/JWT.php';
require_once dirname(__FILE__) . '/config.php';
// check if a secret key to generate token exists or not
function isJwtEnabled() {
/**
* Check if a secret key to generate token exists or not.
*
* @return bool
*/
function isJwtEnabled()
{
return !empty($GLOBALS['DOC_SERV_JWT_SECRET']);
}
// encode a payload object into a token using a secret key
function jwtEncode($payload) {
/**
* Encode a payload object into a token using a secret key
*
* @param array $payload
*
* @return string
*/
function jwtEncode($payload)
{
return \Firebase\JWT\JWT::encode($payload, $GLOBALS["DOC_SERV_JWT_SECRET"]);
}
// decode a token into a payload object using a secret key
function jwtDecode($token) {
/**
* Decode a token into a payload object using a secret key
*
* @param string $token
*
* @return string
*/
function jwtDecode($token)
{
try {
$payload = \Firebase\JWT\JWT::decode($token, $GLOBALS["DOC_SERV_JWT_SECRET"], array("HS256"));
$payload = \Firebase\JWT\JWT::decode($token, $GLOBALS["DOC_SERV_JWT_SECRET"], ["HS256"]);
} catch (\UnexpectedValueException $e) {
$payload = "";
}
return $payload;
}
?>

View File

@ -21,5 +21,9 @@ License: MIT
License File: jQuery.UI.license
JWT - JSON Web Token implementation (https://github.com/firebase/php-jwt/blob/master/LICENSE)
License: BSD
License: BSD-3-Clause
License File: jwt.license
PHP_CodeSniffer - PHP_CodeSniffer is a set of two PHP scripts; the main phpcs script that tokenizes PHP, JavaScript and CSS files to detect violations of a defined coding standard, and a second phpcbf script to automatically correct coding standard violations. PHP_CodeSniffer is an essential development tool that ensures your code remains clean and consistent. (https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt)
License: BSD-3-Clause
License File: PHP_CodeSniffer.license

View File

@ -0,0 +1,24 @@
Copyright (c) 2012, Squiz Pty Ltd (ABN 77 084 670 600)
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@ -0,0 +1,18 @@
<?xml version="1.0"?>
<ruleset name="CustomRuleset">
<description>This standard changes the line length</description>
<rule ref="PSR1">
<exclude name="PSR1.Files.SideEffects" />
</rule>
<!-- Insert all sniff from PSR2 standard -->
<rule ref="PSR2"/>
<rule ref="Generic.Files.LineLength">
<properties>
<property name="lineLimit" value="120"/>
<property name="absoluteLineLimit" value="0"/>
</properties>
</rule>
</ruleset>

View File

@ -1,6 +1,5 @@
<?php
/**
*
* (c) Copyright Ascensio System SIA 2023
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -14,20 +13,23 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
require_once( dirname(__FILE__) . '/jwtmanager.php' );
require_once( dirname(__FILE__) . '/common.php' );
require_once( dirname(__FILE__) . '/config.php' );
require_once dirname(__FILE__) . '/jwtmanager.php';
require_once dirname(__FILE__) . '/common.php';
require_once dirname(__FILE__) . '/config.php';
// read request body
function readBody() {
/**
* Read request body
*
* @return int|array
*/
function readBody()
{
$result["error"] = 0;
// get the body of the post request and check if it is correct
if (($body_stream = file_get_contents('php://input')) === FALSE) {
if (($body_stream = file_get_contents('php://input')) === false) {
$result["error"] = "Bad Request";
return $result;
}
@ -35,7 +37,7 @@ function readBody() {
$data = json_decode($body_stream, false);
// check if the response is correct
if ($data === NULL) {
if ($data === null) {
$result["error"] = "Bad Response";
return $result;
}
@ -54,7 +56,12 @@ function readBody() {
$data = jwtDecode($data["token"]); // decode it
sendlog(" jwt in body", "webedior-ajax.log");
} elseif (!empty(apache_request_headers()[$jwtHeader])) { // if the Authorization header exists
$data = jwtDecode(substr(apache_request_headers()[$jwtHeader], strlen("Bearer "))); // decode its part after Authorization prefix
$data = jwtDecode(
mb_substr(
apache_request_headers()[$jwtHeader],
mb_strlen("Bearer ")
)
); // decode its part after Authorization prefix
$inHeader = true;
sendlog(" jwt in header", "webedior-ajax.log");
} else { // otherwise, an error occurs
@ -69,63 +76,88 @@ function readBody() {
return $result;
}
if ($inHeader) $data = $data->payload;
if ($inHeader) {
$data = $data->payload;
}
}
return $data;
}
// file saving process
function processSave($data, $fileName, $userAddress) {
/**
* File saving process
*
* @param string $data
* @param string $fileName
* @param string $userAddress
*
* @return array
*/
function processSave($data, $fileName, $userAddress)
{
$downloadUri = $data->url;
if ($downloadUri === null) {
$result["error"] = 1;
return $result;
}
$curExt = strtolower('.' . pathinfo($fileName, PATHINFO_EXTENSION)); // get current file extension
$downloadExt = strtolower('.' . $data->filetype); // get the extension of the downloaded file
$curExt = mb_strtolower('.' . pathinfo($fileName, PATHINFO_EXTENSION)); // get current file extension
$downloadExt = mb_strtolower('.' . $data->filetype); // get the extension of the downloaded file
$newFileName = $fileName;
// convert downloaded file to the file with the current extension if these extensions aren't equal
if ($downloadExt != $curExt) {
$key = GenerateRevisionId($downloadUri);
$key = generateRevisionId($downloadUri);
try {
sendlog(" Convert " . $downloadUri . " from " . $downloadExt . " to " . $curExt, "webedior-ajax.log");
$convertedUri; // convert file and give url to a new file
$percent = GetConvertedUri($downloadUri, $downloadExt, $curExt, $key, FALSE, $convertedUri);
$percent = getConvertedUri($downloadUri, $downloadExt, $curExt, $key, false, $convertedUri);
if (!empty($convertedUri)) {
$downloadUri = $convertedUri;
} else {
sendlog(" Convert after save convertedUri is empty", "webedior-ajax.log");
$baseNameWithoutExt = substr($fileName, 0, strlen($fileName) - strlen($curExt));
$newFileName = GetCorrectName($baseNameWithoutExt . $downloadExt, $userAddress); // get the correct file name if it already exists
$baseNameWithoutExt = mb_substr($fileName, 0, mb_strlen($fileName) - mb_strlen($curExt));
// get the correct file name if it already exists
$newFileName = GetCorrectName($baseNameWithoutExt . $downloadExt, $userAddress);
}
} catch (Exception $e) {
sendlog(" Convert after save ".$e->getMessage(), "webedior-ajax.log");
$baseNameWithoutExt = substr($fileName, 0, strlen($fileName) - strlen($curExt));
$baseNameWithoutExt = mb_substr($fileName, 0, mb_strlen($fileName) - mb_strlen($curExt));
$newFileName = GetCorrectName($baseNameWithoutExt . $downloadExt, $userAddress);
}
}
$saved = 1;
if (!(($new_data = file_get_contents($downloadUri, false,
stream_context_create(["http"=>["timeout"=>5]]))) === FALSE)) {
if (!(($new_data = file_get_contents(
$downloadUri,
false,
stream_context_create(["http" => ["timeout" => 5]])
)) === false)
) {
$storagePath = getStoragePath($newFileName, $userAddress); // get the file path
$histDir = getHistoryDir($storagePath); // get the path to the history direction
$verDir = getVersionDir($histDir, getFileVersion($histDir)); // get the path to the file version
mkdir($verDir); // if the path doesn't exist, create it
rename(getStoragePath($fileName, $userAddress), $verDir . DIRECTORY_SEPARATOR . "prev" . $curExt); // get the path to the previous file version and rename the storage path with it
// get the path to the previous file version and rename the storage path with it
rename(getStoragePath($fileName, $userAddress), $verDir .
DIRECTORY_SEPARATOR . "prev" . $curExt);
file_put_contents($storagePath, $new_data, LOCK_EX); // save file to the storage directory
if ($changesData = file_get_contents($data->changesurl, false,
stream_context_create(["http"=>["timeout"=>5]]))) {
file_put_contents($verDir . DIRECTORY_SEPARATOR . "diff.zip", $changesData, LOCK_EX); // save file changes to the diff.zip archive
if ($changesData = file_get_contents(
$data->changesurl,
false,
stream_context_create(["http" => ["timeout" => 5]])
)
) {
// save file changes to the diff.zip archive
file_put_contents($verDir . DIRECTORY_SEPARATOR .
"diff.zip", $changesData, LOCK_EX);
}
$histData = empty($data->changeshistory) ? null : $data->changeshistory;
@ -133,11 +165,16 @@ function processSave($data, $fileName, $userAddress) {
$histData = json_encode($data->history, JSON_PRETTY_PRINT);
}
if (!empty($histData)) {
file_put_contents($verDir . DIRECTORY_SEPARATOR . "changes.json", $histData, LOCK_EX); // write the history changes to the changes.json file
// write the history changes to the changes.json file
file_put_contents($verDir .
DIRECTORY_SEPARATOR . "changes.json", $histData, LOCK_EX);
}
file_put_contents($verDir . DIRECTORY_SEPARATOR . "key.txt", $data->key, LOCK_EX); // write the key value to the key.txt file
// write the key value to the key.txt file
file_put_contents($verDir .
DIRECTORY_SEPARATOR . "key.txt", $data->key, LOCK_EX);
$forcesavePath = getForcesavePath($newFileName, $userAddress, false); // get the path to the forcesaved file version
// get the path to the forcesaved file version
$forcesavePath = getForcesavePath($newFileName, $userAddress, false);
if ($forcesavePath != "") { // if the forcesaved file version exists
unlink($forcesavePath); // remove it
}
@ -150,32 +187,41 @@ function processSave($data, $fileName, $userAddress) {
return $result;
}
// file force saving process
function processForceSave($data, $fileName, $userAddress) {
/**
* File force saving process
*
* @param string $data
* @param string $fileName
* @param string $userAddress
*
* @return array
*/
function processForceSave($data, $fileName, $userAddress)
{
$downloadUri = $data->url;
if ($downloadUri === null) {
$result["error"] = 1;
return $result;
}
$curExt = strtolower('.' . pathinfo($fileName, PATHINFO_EXTENSION)); // get current file extension
$downloadExt = strtolower('.' . $data->filetype); // get the extension of the downloaded file
$curExt = mb_strtolower('.' . pathinfo($fileName, PATHINFO_EXTENSION)); // get current file extension
$downloadExt = mb_strtolower('.' . $data->filetype); // get the extension of the downloaded file
$newFileName = false;
// convert downloaded file to the file with the current extension if these extensions aren't equal
if ($downloadExt != $curExt) {
$key = GenerateRevisionId($downloadUri);
$key = generateRevisionId($downloadUri);
try {
sendlog(" Convert " . $downloadUri . " from " . $downloadExt . " to " . $curExt, "webedior-ajax.log");
$convertedUri; // convert file and give url to a new file
$percent = GetConvertedUri($downloadUri, $downloadExt, $curExt, $key, FALSE, $convertedUri);
$percent = getConvertedUri($downloadUri, $downloadExt, $curExt, $key, false, $convertedUri);
if (!empty($convertedUri)) {
$downloadUri = $convertedUri;
} else {
sendlog(" Convert after save convertedUri is empty", "webedior-ajax.log");
$baseNameWithoutExt = substr($fileName, 0, strlen($fileName) - strlen($curExt));
$baseNameWithoutExt = mb_substr($fileName, 0, mb_strlen($fileName) - mb_strlen($curExt));
$newFileName = true;
}
} catch (Exception $e) {
@ -186,20 +232,25 @@ function processForceSave($data, $fileName, $userAddress) {
$saved = 1;
if (!(($new_data = file_get_contents($downloadUri, false,
stream_context_create(["http"=>["timeout"=>5]]))) === FALSE)) {
$baseNameWithoutExt = substr($fileName, 0, strlen($fileName) - strlen($curExt));
if (!(($new_data = file_get_contents(
$downloadUri,
false,
stream_context_create(["http" => ["timeout" => 5]])
)) === false)
) {
$baseNameWithoutExt = mb_substr($fileName, 0, mb_strlen($fileName) - mb_strlen($curExt));
$isSubmitForm = $data->forcesavetype == 3; // SubmitForm
if ($isSubmitForm) {
if ($newFileName){
$fileName = GetCorrectName($baseNameWithoutExt . "-form" . $downloadExt, $userAddress); // get the correct file name if it already exists
if ($newFileName) {
$fileName = GetCorrectName($baseNameWithoutExt .
"-form" . $downloadExt, $userAddress); // get the correct file name if it already exists
} else {
$fileName = GetCorrectName($baseNameWithoutExt . "-form" . $curExt, $userAddress);
}
$forcesavePath = getStoragePath($fileName, $userAddress);
} else {
if ($newFileName){
if ($newFileName) {
$fileName = GetCorrectName($baseNameWithoutExt . $downloadExt, $userAddress);
}
// create forcesave path if it doesn't exist
@ -224,45 +275,55 @@ function processForceSave($data, $fileName, $userAddress) {
return $result;
}
// create a command request
function commandRequest($method, $key, $meta = null){
/**
* Create a command request
*
* @param string $method
* @param string $key
* @param string $meta
*
* @return false|string
*/
function commandRequest($method, $key, $meta = null)
{
$documentCommandUrl = $GLOBALS['DOC_SERV_SITE_URL'].$GLOBALS['DOC_SERV_COMMAND_URL'];
$arr = [
"c" => $method,
"key" => $key
"key" => $key,
];
if($meta)
if ($meta) {
$arr["meta"] = $meta;
}
$headerToken = "";
$jwtHeader = $GLOBALS['DOC_SERV_JWT_HEADER'] == "" ? "Authorization" : $GLOBALS['DOC_SERV_JWT_HEADER'];
if (isJwtEnabled()) { // check if a secret key to generate token exists or not
$headerToken = jwtEncode([ "payload" => $arr ]); // encode a payload object into a header token
$headerToken = jwtEncode(["payload" => $arr]); // encode a payload object into a header token
$arr["token"] = jwtEncode($arr); // encode a payload object into a body token
}
$data = json_encode($arr);
$opts = array('http' => array(
'method' => 'POST',
'header'=> "Content-type: application/json\r\n" .
(empty($headerToken) ? "" : $jwtHeader.": Bearer $headerToken\r\n"), // add a header Authorization with a header token and Authorization prefix in it
'content' => $data
));
$opts = ['http' => [
'method' => 'POST',
'header' => "Content-type: application/json\r\n" .
// add a header Authorization with a header token and Authorization prefix in it
(empty($headerToken) ? "" : $jwtHeader.
": Bearer $headerToken\r\n"),
'content' => $data,
]];
if (substr($documentCommandUrl, 0, strlen("https")) === "https") {
if($GLOBALS['DOC_SERV_VERIFY_PEER_OFF'] === TRUE) {
$opts['ssl'] = array( 'verify_peer' => FALSE, 'verify_peer_name' => FALSE );
if (mb_substr($documentCommandUrl, 0, mb_strlen("https")) === "https") {
if ($GLOBALS['DOC_SERV_VERIFY_PEER_OFF'] === true) {
$opts['ssl'] = ['verify_peer' => false, 'verify_peer_name' => false];
}
}
$context = stream_context_create($opts);
$response_data = file_get_contents($documentCommandUrl, FALSE, $context);
$response_data = file_get_contents($documentCommandUrl, false, $context);
return $response_data;
}
?>

View File

@ -1,6 +1,8 @@
<?php
namespace PhpExample;
/**
*
* (c) Copyright Ascensio System SIA 2023
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -14,12 +16,40 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
class User {
function __construct($id, $name, $email, $group, $reviewGroups, $commentGroups, $userInfoGroups, $favorite, $deniedPermissions, $descriptions, $templates)
{
final class User
{
/**
* Constructor
*
* @param string $id
* @param string $name
* @param string $email
* @param string $group
* @param array|null $reviewGroups
* @param array $commentGroups
* @param array|null $userInfoGroups
* @param bool|null $favorite
* @param array $deniedPermissions
* @param array $descriptions
* @param bool $templates
*
* @return void
*/
public function __construct(
$id,
$name,
$email,
$group,
$reviewGroups,
$commentGroups,
$userInfoGroups,
$favorite,
$deniedPermissions,
$descriptions,
$templates
) {
$this->id = $id;
$this->name = $name;
$this->email = $email;
@ -41,16 +71,17 @@ $descr_user_1 = [
"Can perform all actions with comments",
"The file favorite state is undefined",
"Can create files from templates using data from the editor",
"Can see the information about all users"
"Can see the information about all users",
];
$descr_user_2 = [
"Belongs to Group2",
"Can review only his own changes or changes made by users with no group",
"Can view comments, edit his own comments and comments left by users with no group. Can remove his own comments only",
"Can view comments, edit his own comments and comments left by users with no group.
Can remove his own comments only",
"This file is marked as favorite",
"Can create new files from the editor",
"Can see the information about users from Group2 and users who dont belong to any group"
"Can see the information about users from Group2 and users who dont belong to any group",
];
$descr_user_3 = [
@ -62,7 +93,7 @@ $descr_user_3 = [
"Cant download the file",
"Cant print the file",
"Can create new files from the editor",
"Can see the information about Group2 users"
"Can see the information about Group2 users",
];
$descr_user_0 = [
@ -80,40 +111,90 @@ $descr_user_0 = [
];
$users = [
new User("uid-1", "John Smith", "smith@example.com",
"", null, [], null,
null, [], $descr_user_1, true),
new User("uid-2", "Mark Pottato", "pottato@example.com",
"group-2", ["group-2", ""], [
"view" => "",
"edit" => ["group-2", ""],
"remove" => ["group-2"]
],
["group-2", ""],
true, [], $descr_user_2, false),
new User("uid-3", "Hamish Mitchell", "mitchell@example.com",
"group-3", ["group-2"], [
"view" => ["group-3", "group-2"],
"edit" => ["group-2"],
"remove" => []
],
["group-2"],
false, ["copy", "download", "print"], $descr_user_3, false),
new User("uid-0", null, null,
"", null, [], [],
null, [], $descr_user_0, false)
new User(
"uid-1",
"John Smith",
"smith@example.com",
"",
null,
[],
null,
null,
[],
$descr_user_1,
true
),
new User(
"uid-2",
"Mark Pottato",
"pottato@example.com",
"group-2",
["group-2", ""],
[
"view" => "",
"edit" => ["group-2", ""],
"remove" => ["group-2"],
],
["group-2", ""],
true,
[],
$descr_user_2,
false
),
new User(
"uid-3",
"Hamish Mitchell",
"mitchell@example.com",
"group-3",
["group-2"],
[
"view" => ["group-3", "group-2"],
"edit" => ["group-2"],
"remove" => [],
],
["group-2"],
false,
["copy", "download", "print"],
$descr_user_3,
false
),
new User(
"uid-0",
null,
null,
"",
null,
[],
[],
null,
[],
$descr_user_0,
false
),
];
// get a list of all the users
function getAllUsers() {
/**
* Get a list of all the users
*
* @return array
*/
function getAllUsers()
{
global $users;
return $users;
}
// get a user by id specified
function getUser($id) {
/**
* Get a user by id specified
*
* @param string $id
*
* @return array
*/
function getUser($id)
{
global $users;
foreach ($users as $user){
foreach ($users as $user) {
if ($user->id == $id) {
sendlog("User ". $user->id, "common.log");
return $user;
@ -122,18 +203,24 @@ function getUser($id) {
return $users[0];
}
// get a list of users with their names and emails for mentions
function getUsersForMentions($id) {
/**
* Get a list of users with their names and emails for mentions
*
* @param string $id
*
* @return array
*/
function getUsersForMentions($id)
{
global $users;
$usersData = [];
foreach ($users as $user) {
if ($user->id != $id && $user->name != null && $user->email != null) {
array_push($usersData,[
$usersData[] = [
"name" => $user->name,
"email" => $user->email
]);
"email" => $user->email,
];
}
}
return $usersData;
}
?>

350
web/documentserver-example/php/webeditor-ajax.php Executable file → Normal file
View File

@ -1,6 +1,8 @@
<?php
namespace PhpExample;
/**
*
* (c) Copyright Ascensio System SIA 2023
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -14,34 +16,33 @@
* 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.
*
*/
/**
* WebEditor AJAX Process Execution.
*/
require_once( dirname(__FILE__) . '/config.php' );
require_once( dirname(__FILE__) . '/ajax.php' );
require_once( dirname(__FILE__) . '/common.php' );
require_once( dirname(__FILE__) . '/functions.php' );
require_once( dirname(__FILE__) . '/jwtmanager.php' );
require_once( dirname(__FILE__) . '/trackmanager.php' );
require_once( dirname(__FILE__) . '/users.php' );
require_once dirname(__FILE__) . '/config.php';
require_once dirname(__FILE__) . '/ajax.php';
require_once dirname(__FILE__) . '/common.php';
require_once dirname(__FILE__) . '/functions.php';
require_once dirname(__FILE__) . '/jwtmanager.php';
require_once dirname(__FILE__) . '/trackmanager.php';
require_once dirname(__FILE__) . '/users.php';
// define tracker status
$_trackerStatus = array(
$_trackerStatus = [
0 => 'NotFound',
1 => 'Editing',
2 => 'MustSave',
3 => 'Corrupted',
4 => 'Closed',
6 => 'MustForceSave',
7 => 'CorruptedForceSave'
);
7 => 'CorruptedForceSave',
];
// ignore self-signed certificate
if($GLOBALS['DOC_SERV_VERIFY_PEER_OFF'] === TRUE) {
stream_context_set_default( [
if ($GLOBALS['DOC_SERV_VERIFY_PEER_OFF'] === true) {
stream_context_set_default([
'ssl' => [
'verify_peer' => false,
'verify_peer_name' => false,
@ -52,12 +53,12 @@ if($GLOBALS['DOC_SERV_VERIFY_PEER_OFF'] === TRUE) {
// check if type value exists
if (isset($_GET["type"]) && !empty($_GET["type"])) {
$response_array;
@header( 'Content-Type: application/json; charset==utf-8');
@header( 'X-Robots-Tag: noindex' );
@header( 'X-Content-Type-Options: nosniff' );
@header('Content-Type: application/json; charset==utf-8');
@header('X-Robots-Tag: noindex');
@header('X-Content-Type-Options: nosniff');
// set headers that prevent caching in all the browsers
nocache_headers();
nocacheHeaders();
// write the request result to the log file
sendlog(serialize($_GET), "webedior-ajax.log");
@ -65,49 +66,49 @@ if (isset($_GET["type"]) && !empty($_GET["type"])) {
$type = $_GET["type"];
// switch case for type value
switch($type) {
switch ($type) {
case "upload":
$response_array = upload();
$response_array['status'] = isset($response_array['error']) ? 'error' : 'success';
die (json_encode($response_array));
die(json_encode($response_array));
case "download":
$response_array = download();
$response_array['status'] = 'success';
die (json_encode($response_array));
die(json_encode($response_array));
case "history":
$response_array = historyDownload();
$response_array['status'] = 'success';
die (json_encode($response_array));
die(json_encode($response_array));
case "convert":
$response_array = convert();
$response_array['status'] = 'success';
die (json_encode($response_array));
die(json_encode($response_array));
case "track":
$response_array = track();
$response_array['status'] = 'success';
die (json_encode($response_array));
die(json_encode($response_array));
case "delete":
$response_array = delete();
$response_array['status'] = 'success';
die (json_encode($response_array));
die(json_encode($response_array));
case "assets":
$response_array = assets();
$response_array['status'] = 'success';
die (json_encode($response_array));
die(json_encode($response_array));
case "csv":
$response_array = csv();
$response_array['status'] = 'success';
die (json_encode($response_array));
die(json_encode($response_array));
case "files":
$response_array = files();
die (json_encode($response_array));
die(json_encode($response_array));
case "saveas":
$response_array = saveas();
$response_array['status'] = 'success';
die (json_encode($response_array));
die(json_encode($response_array));
case "rename":
$response_array = renamefile();
die (json_encode($response_array));
die(json_encode($response_array));
default:
$response_array['status'] = 'error';
$response_array['error'] = '404 Method not found';
@ -115,46 +116,62 @@ if (isset($_GET["type"]) && !empty($_GET["type"])) {
}
}
// save copy as...
function saveas() {
try {
$result;
$post = json_decode(file_get_contents('php://input'), true);
$fileurl = $post["url"];
$title = $post["title"];
$extension = strtolower(pathinfo($title, PATHINFO_EXTENSION));
$allexts = array_merge($GLOBALS['DOC_SERV_CONVERT'], $GLOBALS['DOC_SERV_EDITED'], $GLOBALS['DOC_SERV_VIEWD'], $GLOBALS['DOC_SERV_FILLFORMS']);
$filename = GetCorrectName($title);
/**
* Save copy as...
*
* @return array
*/
function saveas()
{
try {
$result;
$post = json_decode(file_get_contents('php://input'), true);
$fileurl = $post["url"];
$title = $post["title"];
$extension = mb_strtolower(pathinfo($title, PATHINFO_EXTENSION));
$allexts = array_merge(
$GLOBALS['DOC_SERV_CONVERT'],
$GLOBALS['DOC_SERV_EDITED'],
$GLOBALS['DOC_SERV_VIEWD'],
$GLOBALS['DOC_SERV_FILLFORMS']
);
$filename = GetCorrectName($title);
if (!in_array("." . $extension, $allexts)) {
$result["error"] = "File type is not supported";
return $result;
}
$headers = get_headers($fileurl, 1);
$content_length = $headers["Content-Length"];
$data = file_get_contents(str_replace(" ","%20",$fileurl));
if (!in_array("." . $extension, $allexts)) {
$result["error"] = "File type is not supported";
return $result;
}
$headers = get_headers($fileurl, 1);
$content_length = $headers["Content-Length"];
$data = file_get_contents(str_replace(" ", "%20", $fileurl));
if ($data === false || $content_length <= 0 || $content_length > $GLOBALS['FILE_SIZE_MAX']) {
$result["error"] = "File size is incorrect";
return $result;
}
if ($data === false || $content_length <= 0 || $content_length > $GLOBALS['FILE_SIZE_MAX']) {
$result["error"] = "File size is incorrect";
return $result;
}
file_put_contents(getStoragePath($filename), $data, LOCK_EX); // write data to the new file
$user = getUser($_GET["user"]);
createMeta($filename, $user->id, $user->name); // and create meta data for this file
file_put_contents(getStoragePath($filename), $data, LOCK_EX); // write data to the new file
$user = getUser($_GET["user"]);
createMeta($filename, $user->id, $user->name); // and create meta data for this file
$result["file"] = $filename;
return $result;
} catch (Exception $e) {
sendlog("SaveAs: ".$e->getMessage(), "webedior-ajax.log");
$result["error"] = "error: " . 1 . "message:" . $e->getMessage();
return $result;
}
$result["file"] = $filename;
return $result;
} catch (Exception $e) {
sendlog("SaveAs: ".$e->getMessage(), "webedior-ajax.log");
$result["error"] = "error: " . 1 . "message:" . $e->getMessage();
return $result;
}
}
// uploading a file
function upload() {
$result; $filename;
/**
* Uploading a file
*
* @return array
*/
function upload()
{
$result;
$filename;
if ($_FILES['files']['error'] > 0) {
$result["error"] = 'Error ' . json_encode($_FILES['files']['error']);
@ -171,10 +188,9 @@ function upload() {
}
// check if the file was uploaded using HTTP POST
if (is_uploaded_file($tmp))
{
if (is_uploaded_file($tmp)) {
$filesize = $_FILES['files']['size']; // get the file size
$ext = strtolower('.' . pathinfo($_FILES['files']['name'], PATHINFO_EXTENSION)); // get file extension
$ext = mb_strtolower('.' . pathinfo($_FILES['files']['name'], PATHINFO_EXTENSION)); // get file extension
// check if the file size is correct (it should be less than the max file size, but greater than 0)
if ($filesize <= 0 || $filesize > $GLOBALS['FILE_SIZE_MAX']) {
@ -188,14 +204,14 @@ function upload() {
return $result;
}
$filename = GetCorrectName($_FILES['files']['name']); // get the correct file name with an index if the file with such a name already exists
if (!move_uploaded_file($tmp, getStoragePath($filename)) ) {
// get the correct file name with an index if the file with such a name already exists
$filename = GetCorrectName($_FILES['files']['name']);
if (!move_uploaded_file($tmp, getStoragePath($filename))) {
$result["error"] = 'Upload failed'; // file upload error
return $result;
}
$user = getUser($_GET["user"]);
createMeta($filename, $user->id, $user->name); // create file meta data
} else {
$result["error"] = 'Upload failed';
return $result;
@ -206,17 +222,22 @@ function upload() {
return $result;
}
// tracking file changes
function track() {
/**
* Tracking file changes
*
* @return array|int
*/
function track()
{
sendlog("Track START", "webedior-ajax.log");
sendlog(" _GET params: " . serialize( $_GET ), "webedior-ajax.log");
sendlog(" _GET params: " . serialize($_GET), "webedior-ajax.log");
$result["error"] = 0;
// get the body of the post request and check if it is correct
$data = readBody();
if (!empty($data->error)){
if (!empty($data->error)) {
return $data;
}
@ -231,8 +252,9 @@ function track() {
case "Editing": // status == 1
if ($data->actions && $data->actions[0]->type == 0) { // finished edit
$user = $data->actions[0]->userid; // the user who finished editing
if (array_search($user, $data->users) === FALSE) {
$commandRequest = commandRequest("forcesave", $data->key); // create a command request with the forcasave method
if (array_search($user, $data->users) === false) {
// create a command request with the forcasave method
$commandRequest = commandRequest("forcesave", $data->key);
sendlog(" CommandRequest forcesave: " . serialize($commandRequest), "webedior-ajax.log");
}
}
@ -251,21 +273,25 @@ function track() {
return $result;
}
// converting a file
function convert() {
/**
* Converting a file
*
* @return array
*/
function convert()
{
$post = json_decode(file_get_contents('php://input'), true);
$fileName = basename($post["filename"]);
$filePass = $post["filePass"];
$lang = $_COOKIE["ulang"];
$extension = strtolower(pathinfo($fileName, PATHINFO_EXTENSION));
$internalExtension = trim(getInternalExtension($fileName),'.');
$extension = mb_strtolower(pathinfo($fileName, PATHINFO_EXTENSION));
$internalExtension = trim(getInternalExtension($fileName), '.');
// check if the file with such an extension can be converted
if (in_array("." . $extension, $GLOBALS['DOC_SERV_CONVERT']) && $internalExtension != "") {
$fileUri = $post["fileUri"];
if ($fileUri == NULL || $fileUri == "") {
$fileUri = $fileUri=serverPath(TRUE) . '/'
if ($fileUri == null || $fileUri == "") {
$fileUri = $fileUri = serverPath(true) . '/'
. "webeditor-ajax.php"
. "?type=download"
. "&fileName=" . urlencode($fileName)
@ -279,15 +305,22 @@ function convert() {
try {
// convert file and get the percentage of the conversion completion
$percent = GetConvertedUri($fileUri, $extension, $internalExtension, $key, TRUE, $newFileUri, $filePass, $lang);
}
catch (Exception $e) {
$percent = getConvertedUri(
$fileUri,
$extension,
$internalExtension,
$key,
true,
$newFileUri,
$filePass,
$lang
);
} catch (Exception $e) {
$result["error"] = "error: " . $e->getMessage();
return $result;
}
if ($percent != 100)
{
if ($percent != 100) {
$result["step"] = $percent;
$result["filename"] = $fileName;
$result["fileUri"] = $fileUri;
@ -295,19 +328,18 @@ function convert() {
}
// get file name without extension
$baseNameWithoutExt = substr($fileName, 0, strlen($fileName) - strlen($extension) - 1);
$baseNameWithoutExt = mb_substr($fileName, 0, mb_strlen($fileName) - mb_strlen($extension) - 1);
// get the correct file name with an index if the file with such a name already exists
$newFileName = GetCorrectName($baseNameWithoutExt . "." . $internalExtension);
if (($data = file_get_contents(str_replace(" ","%20",$newFileUri))) === FALSE) {
if (($data = file_get_contents(str_replace(" ", "%20", $newFileUri))) === false) {
$result["error"] = 'Bad Request';
return $result;
} else {
file_put_contents(getStoragePath($newFileName), $data, LOCK_EX); // write data to the new file
$user = getUser($_GET["user"]);
createMeta($newFileName, $user->id, $user->name); // and create meta data for this file
}
file_put_contents(getStoragePath($newFileName), $data, LOCK_EX); // write data to the new file
$user = getUser($_GET["user"]);
createMeta($newFileName, $user->id, $user->name); // and create meta data for this file
// delete the original file and its history
$stPath = getStoragePath($fileName);
@ -321,8 +353,13 @@ function convert() {
return $result;
}
// removing a file
function delete() {
/**
* Removing a file
*
* @return array|void
*/
function delete()
{
try {
$fileName = basename($_GET["fileName"]);
@ -330,47 +367,67 @@ function delete() {
unlink($filePath); // delete a file
delTree(getHistoryDir($filePath)); // delete all the elements from the history directory
}
catch (Exception $e) {
} catch (Exception $e) {
sendlog("Deletion ".$e->getMessage(), "webedior-ajax.log");
$result["error"] = "error: " . $e->getMessage();
return $result;
}
}
// get file information
function files() {
/**
* Get file information
*
* @return array
*/
function files()
{
try {
@header( "Content-Type", "application/json" );
@header("Content-Type", "application/json");
$fileId = $_GET["fileId"];
$result = getFileInfo($fileId);
return $result;
}
catch (Exception $e) {
} catch (Exception $e) {
sendlog("Files ".$e->getMessage(), "webedior-ajax.log");
$result["error"] = "error: " . $e->getMessage();
return $result;
}
}
// download assets
function assets() {
/**
* Download assets
*
* @return void
*/
function assets()
{
$fileName = basename($_GET["name"]);
$filePath = dirname(__FILE__) . DIRECTORY_SEPARATOR . "assets" . DIRECTORY_SEPARATOR . "sample" . DIRECTORY_SEPARATOR . $fileName;
$filePath = dirname(__FILE__) .
DIRECTORY_SEPARATOR . "assets" . DIRECTORY_SEPARATOR . "sample" . DIRECTORY_SEPARATOR . $fileName;
downloadFile($filePath);
}
// download a csv file
function csv() {
$fileName = "csv.csv";
$filePath = dirname(__FILE__) . DIRECTORY_SEPARATOR . "assets" . DIRECTORY_SEPARATOR . "sample" . DIRECTORY_SEPARATOR . $fileName;
/**
* Download a csv file
*
* @return void
*/
function csv()
{
$fileName = "csv.csv";
$filePath = dirname(__FILE__) .
DIRECTORY_SEPARATOR . "assets" . DIRECTORY_SEPARATOR . "sample" . DIRECTORY_SEPARATOR . $fileName;
downloadFile($filePath);
}
// download a file from history
function historyDownload() {
/**
* Download a file from history
*
* @return array|void
*/
function historyDownload()
{
try {
$fileName = basename($_GET["fileName"]); // get the file name
$userAddress = $_GET["userAddress"];
@ -381,7 +438,7 @@ function historyDownload() {
if (isJwtEnabled()) {
$jwtHeader = $GLOBALS['DOC_SERV_JWT_HEADER'] == "" ? "Authorization" : $GLOBALS['DOC_SERV_JWT_HEADER'];
if (!empty(apache_request_headers()[$jwtHeader])) {
$token = jwtDecode(substr(apache_request_headers()[$jwtHeader], strlen("Bearer ")));
$token = jwtDecode(mb_substr(apache_request_headers()[$jwtHeader], mb_strlen("Bearer ")));
if (empty($token)) {
http_response_code(403);
die("Invalid JWT signature");
@ -394,7 +451,8 @@ function historyDownload() {
$histDir = getHistoryDir(getStoragePath($fileName, $userAddress));
$filePath = getVersionDir($histDir, $ver) . DIRECTORY_SEPARATOR . $file;;
$filePath = getVersionDir($histDir, $ver) . DIRECTORY_SEPARATOR . $file;
;
downloadFile($filePath); // download this file
} catch (Exception $e) {
@ -404,24 +462,29 @@ function historyDownload() {
}
}
// download a file
function download() {
/**
* Download a file
*
* @return array|void
*/
function download()
{
try {
$fileName = realpath($GLOBALS['STORAGE_PATH']) === $GLOBALS['STORAGE_PATH'] ? $_GET["fileName"] : basename($_GET["fileName"]); // get the file name
$fileName = realpath($GLOBALS['STORAGE_PATH'])
=== $GLOBALS['STORAGE_PATH'] ? $_GET["fileName"] : basename($_GET["fileName"]); // get the file name
$userAddress = $_GET["userAddress"];
$isEmbedded = $_GET["&dmode"];
if (isJwtEnabled() && $isEmbedded == null) {
if (isJwtEnabled() && $isEmbedded == null && $userAddress) {
$jwtHeader = $GLOBALS['DOC_SERV_JWT_HEADER'] == "" ? "Authorization" : $GLOBALS['DOC_SERV_JWT_HEADER'];
if (!empty(apache_request_headers()[$jwtHeader])) {
$token = jwtDecode(substr(apache_request_headers()[$jwtHeader], strlen("Bearer ")));
$token = jwtDecode(mb_substr(apache_request_headers()[$jwtHeader], mb_strlen("Bearer ")));
if (empty($token)) {
http_response_code(403);
die("Invalid JWT signature");
}
}
}
$filePath = getForcesavePath($fileName, $userAddress, false); // get the path to the forcesaved file version
if ($filePath == "") {
$filePath = getStoragePath($fileName, $userAddress); // get file from the storage directory
@ -434,8 +497,15 @@ function download() {
}
}
// download the specified file
function downloadFile($filePath) {
/**
* Download the specified file
*
* @param string $filePath
*
* @return void
*/
function downloadFile($filePath)
{
if (file_exists($filePath)) {
if (ob_get_level()) {
ob_end_clean();
@ -448,7 +518,7 @@ function downloadFile($filePath) {
if ($fd = fopen($filePath, 'rb')) {
while (!feof($fd)) {
print fread($fd, 1024);
echo fread($fd, 1024);
}
fclose($fd);
}
@ -456,25 +526,39 @@ function downloadFile($filePath) {
}
}
// delete all the elements from the directory
function delTree($dir) {
if (!file_exists($dir) || !is_dir($dir)) return;
/**
* Delete all the elements from the directory
*
* @param string $dir
*
* @return void|bool
*/
function delTree($dir)
{
if (!file_exists($dir) || !is_dir($dir)) {
return;
}
$files = array_diff(scandir($dir), array('.','..'));
$files = array_diff(scandir($dir), ['.', '..']);
foreach ($files as $file) {
(is_dir("$dir/$file")) ? delTree("$dir/$file") : unlink("$dir/$file");
}
return rmdir($dir);
}
// rename...
function renamefile() {
/**
* Rename file
*
* @return array
*/
function renamefile()
{
$post = json_decode(file_get_contents('php://input'), true);
$newfilename = $post["newfilename"];
$curExt = strtolower(array_pop(explode('.', $newfilename)));
$curExt = mb_strtolower(array_pop(explode('.', $newfilename)));
$origExt = $post["ext"];
if($origExt !== $curExt){
if ($origExt !== $curExt) {
$newfilename .= '.' . $origExt;
}
@ -484,7 +568,5 @@ function renamefile() {
$commandRequest = commandRequest("meta", $dockey, $meta); // create a command request with the forcasave method
sendlog(" CommandRequest rename: " . serialize($commandRequest), "webedior-ajax.log");
return array("result" => $commandRequest);
return ["result" => $commandRequest];
}
?>

View File

@ -201,21 +201,24 @@ def createFile(stream, path, req = None, meta = False):
historyManager.createMeta(path, req) # create meta data for the file if needed
return
# create file response
def createFileResponse(response, path, req, meta):
status_code = response.status_code
if status_code != 200: # checking status code
raise RuntimeError('Document editing service returned status: %s' % status_code)
# save file
def saveFile(response, path):
with open(path, 'wb') as file:
for chunk in response.iter_content(chunk_size=8192):
file.write(chunk)
return
# save file from the given url
def saveFileFromUri(uri, path, req = None, meta = False):
# download file from the given url
def downloadFileFromUri(uri, path = None, withSave = False):
resp = requests.get(uri, stream=True, verify = config.DOC_SERV_VERIFY_PEER, timeout=5)
createFileResponse(resp, path, req, meta)
return
status_code = resp.status_code
if status_code != 200: # checking status code
raise RuntimeError('Document editing service returned status: %s' % status_code)
if withSave:
if path is None:
raise RuntimeError('Path for saving file is null')
saveFile(resp, path)
return resp
# create sample file
def createSample(fileType, sample, req):

View File

@ -68,6 +68,10 @@ def processSave(body, filename, usAddr):
path = docManager.getStoragePath(newFilename, usAddr) # get the file path
data = docManager.downloadFileFromUri(download) # download document file
if (data is None):
raise Exception("Downloaded document is null")
histDir = historyManager.getHistoryDir(path) # get the path to the history direction
if not os.path.exists(histDir): # if the path doesn't exist
os.makedirs(histDir) # create it
@ -75,8 +79,13 @@ def processSave(body, filename, usAddr):
versionDir = historyManager.getNextVersionDir(histDir) # get the path to the next file version
os.rename(docManager.getStoragePath(filename, usAddr), historyManager.getPrevFilePath(versionDir, curExt)) # get the path to the previous file version and rename the storage path with it
docManager.saveFileFromUri(download, path) # save file to the storage path
docManager.saveFileFromUri(changesUri, historyManager.getChangesZipPath(versionDir)) # save file changes to the diff.zip archive
docManager.saveFile(data, path) # save document file
dataChanges = docManager.downloadFileFromUri(changesUri) # download changes file
if (dataChanges is None):
raise Exception("Downloaded changes is null")
docManager.saveFile(dataChanges, historyManager.getChangesZipPath(versionDir)) # save file changes to the diff.zip archive
hist = None
hist = body.get('changeshistory')
@ -115,6 +124,10 @@ def processForceSave(body, filename, usAddr):
except Exception:
newFilename = True
data = docManager.downloadFileFromUri(download) # download document file
if (data is None):
raise Exception("Downloaded document is null")
isSubmitForm = body.get('forcesavetype') == 3 # SubmitForm
if(isSubmitForm):
@ -130,7 +143,7 @@ def processForceSave(body, filename, usAddr):
if (forcesavePath == ""):
forcesavePath = docManager.getForcesavePath(filename, usAddr, True)
docManager.saveFileFromUri(download, forcesavePath)
docManager.saveFile(download, forcesavePath) # save document file
if(isSubmitForm):
uid = body['actions'][0]['userid'] # get the user id

View File

@ -80,7 +80,7 @@ def convert(request):
else:
correctName = docManager.getCorrectName(fileUtils.getFileNameWithoutExt(filename) + newExt, request) # otherwise, create a new name with the necessary extension
path = docManager.getStoragePath(correctName, request)
docManager.saveFileFromUri(newUri, path, request, True) # save the file from the new url in the storage directory
docManager.downloadFileFromUri(newUri, path, True) # save the file from the new url in the storage directory
docManager.removeFile(filename, request) # remove the original file
response.setdefault('filename', correctName) # pass the name of the converted file to the response
else:
@ -130,7 +130,7 @@ def saveAs(request):
response.setdefault('error', 'File type is not supported')
raise Exception('File type is not supported')
docManager.saveFileFromUri(saveAsFileUrl, path, request, True) # save the file from the new url in the storage directory
docManager.downloadFileFromUri(saveAsFileUrl, path, True) # save the file from the new url in the storage directory
response.setdefault('file', filename)
except Exception as e:
@ -397,18 +397,22 @@ def csv(request):
def download(request):
try:
fileName = fileUtils.getFileName(request.GET['fileName']) # get the file name
userAddress = request.GET.get('userAddress') if request.GET.get('userAddress') else request
userAddress = request.GET.get('userAddress')
isEmbedded = request.GET.get('dmode')
if (jwtManager.isEnabled() and isEmbedded == None):
if (jwtManager.isEnabled() and isEmbedded == None and userAddress):
jwtHeader = 'Authorization' if config.DOC_SERV_JWT_HEADER is None or config.DOC_SERV_JWT_HEADER == '' else config.DOC_SERV_JWT_HEADER
token = request.headers.get(jwtHeader)
if token:
token = token[len('Bearer '):]
try:
body = jwtManager.decode(token)
except Exception:
return HttpResponse('JWT validation failed', status=403)
try:
body = jwtManager.decode(token)
except Exception:
return HttpResponse('JWT validation failed', status=403)
if (userAddress == None):
userAddress = request
filePath = docManager.getForcesavePath(fileName, userAddress, False) # get the path to the forcesaved file version
if (filePath == ""):

View File

@ -90,7 +90,7 @@ GEM
execjs (2.8.1)
ffi (1.15.5)
ffi (1.15.5-x64-mingw-ucrt)
globalid (1.0.0)
globalid (1.0.1)
activesupport (>= 5.0)
i18n (1.12.0)
concurrent-ruby (~> 1.0)
@ -102,7 +102,7 @@ GEM
railties (>= 4.2.0)
thor (>= 0.14, < 2.0)
jwt (2.4.1)
loofah (2.19.0)
loofah (2.19.1)
crass (~> 1.0.2)
nokogiri (>= 1.5.9)
macaddr (1.7.2)
@ -112,7 +112,7 @@ GEM
marcel (1.0.2)
method_source (1.0.0)
mini_mime (1.1.2)
minitest (5.16.3)
minitest (5.17.0)
net-imap (0.2.3)
digest
net-protocol
@ -128,14 +128,14 @@ GEM
net-protocol
timeout
nio4r (2.5.8)
nokogiri (1.13.9-x64-mingw-ucrt)
nokogiri (1.13.10-x64-mingw-ucrt)
racc (~> 1.4)
nokogiri (1.13.9-x86_64-linux)
nokogiri (1.13.10-x86_64-linux)
racc (~> 1.4)
psych (4.0.5)
stringio
racc (1.6.0)
rack (2.2.4)
racc (1.6.1)
rack (2.2.6.2)
rack-cors (1.1.1)
rack (>= 2.0.0)
rack-test (2.0.2)
@ -157,8 +157,8 @@ GEM
rails-dom-testing (2.0.3)
activesupport (>= 4.2.0)
nokogiri (>= 1.6)
rails-html-sanitizer (1.4.3)
loofah (~> 2.3)
rails-html-sanitizer (1.4.4)
loofah (~> 2.19, >= 2.19.1)
railties (7.0.3.1)
actionpack (= 7.0.3.1)
activesupport (= 7.0.3.1)

View File

@ -272,17 +272,17 @@ class HomeController < ApplicationController
user_address = params[:userAddress]
isEmbedded = params[:dmode]
if JwtHelper.is_enabled && isEmbedded == nil
if JwtHelper.is_enabled && isEmbedded == nil && user_address != nil
jwtHeader = Rails.configuration.header.empty? ? "Authorization" : Rails.configuration.header;
if request.headers[jwtHeader]
hdr = request.headers[jwtHeader]
hdr.slice!(0, "Bearer ".length)
token = JwtHelper.decode(hdr)
if !token || token.eql?("")
render plain: "JWT validation failed", :status => 403
return
end
end
end
if !token || token.eql?("")
render plain: "JWT validation failed", :status => 403
return
end
end
file_path = DocumentHelper.forcesave_path(file_name, user_address, false) # get the path to the force saved document version

View File

@ -63,22 +63,23 @@ class TrackHelper
# file saving process
def process_save(file_data, file_name, user_address)
download_uri = file_data['url']
if (download_uri.eql?(nil))
if download_uri.eql?(nil)
saved = 1
return saved
end
new_file_name = file_name
download_ext = "."+file_data['filetype'] # get the extension of the downloaded file
cur_ext = File.extname(file_name).downcase # get current file extension
# convert downloaded file to the file with the current extension if these extensions aren't equal
if (!cur_ext.eql?(download_ext))
key = ServiceConverter.generate_revision_id(download_uri) # get the document key
unless cur_ext.eql?(download_ext)
key = ServiceConverter.generate_revision_id(download_uri) # get the document key
begin
percent, new_file_uri = ServiceConverter.get_converted_uri(download_uri, download_ext.delete('.'), cur_ext.delete('.'), key, false, nil) # get the url of the converted file
if (new_file_uri == nil || new_file_uri.empty?)
new_file_name = DocumentHelper.get_correct_name(File.basename(file_name, cur_ext) + download_ext, user_address) # get the correct file name if it already exists
percent, new_file_uri = ServiceConverter.get_converted_uri(download_uri, download_ext.delete('.'), cur_ext.delete('.'), key, false, nil) # get the url of the converted file
if new_file_uri == nil || new_file_uri.empty?
new_file_name = DocumentHelper.get_correct_name(File.basename(file_name, cur_ext) + download_ext, user_address) # get the correct file name if it already exists
else
download_uri = new_file_uri
end
@ -88,6 +89,12 @@ class TrackHelper
end
saved = 1
data = download_file(download_uri) # download document file
if data.eql?(nil)
return saved
end
begin
storage_path = DocumentHelper.storage_path(new_file_name, user_address) # get the storage directory of the new file
@ -97,17 +104,17 @@ class TrackHelper
FileUtils.mkdir_p(ver_dir) # create the version directory if doesn't exist
FileUtils.move(DocumentHelper.storage_path(file_name, user_address), File.join(ver_dir, "prev#{cur_ext}")) # move the file from the storage directory to the previous file version directory
save_from_uri(storage_path, download_uri) # save the downloaded file to the storage directory
if (file_data["changesurl"]) # if the changesurl is in the body
save_from_uri(File.join(ver_dir, "diff.zip"), file_data["changesurl"]) # get the information from this url to the file with document versions differences
end
save_file(data, storage_path) # save the downloaded file to the storage directory
change_data = download_file(file_data["changesurl"]) # download file with document versions differences
save_file(change_data, File.join(ver_dir, "diff.zip")) # save file with document versions differences
hist_data = file_data["changeshistory"]
if (!hist_data) # if there are no changes in the history
hist_data = file_data["history"].to_json # write the original history information to the history data
unless hist_data # if there are no changes in the history
hist_data = file_data["history"].to_json # write the original history information to the history data
end
if (hist_data)
if hist_data
File.open(File.join(ver_dir, "changes.json"), 'wb') do |file| # open the file with document changes
file.write(hist_data) # and write history data to this file
end
@ -119,8 +126,8 @@ class TrackHelper
end
forcesave_path = DocumentHelper.forcesave_path(new_file_name, user_address, false) # get the path to the forcesaved file
if (!forcesave_path.eql?("")) # if this path is empty
File.delete(forcesave_path) # remove it
unless forcesave_path.eql?("") # if this path is empty
File.delete(forcesave_path) # remove it
end
saved = 0
@ -128,16 +135,17 @@ class TrackHelper
saved = 1
end
return saved
saved
end
# file force saving process
def process_force_save(file_data, file_name, user_address)
download_uri = file_data['url']
if (download_uri.eql?(nil))
if download_uri.eql?(nil)
saved = 1
return saved
end
download_ext = "."+file_data['filetype'] # get the extension of the downloaded file
cur_ext = File.extname(file_name).downcase # get current file extension
@ -145,11 +153,11 @@ class TrackHelper
new_file_name = false
# convert downloaded file to the file with the current extension if these extensions aren't equal
if (!cur_ext.eql?(download_ext))
key = ServiceConverter.generate_revision_id(download_uri) # get the document key
unless cur_ext.eql?(download_ext)
key = ServiceConverter.generate_revision_id(download_uri) # get the document key
begin
percent, new_file_uri = ServiceConverter.get_converted_uri(download_uri, download_ext.delete('.'), cur_ext.delete('.'), key, false, nil) # get the url of the converted file
if (new_file_uri == nil || new_file_uri.empty?)
percent, new_file_uri = ServiceConverter.get_converted_uri(download_uri, download_ext.delete('.'), cur_ext.delete('.'), key, false, nil) # get the url of the converted file
if new_file_uri == nil || new_file_uri.empty?
new_file_name = true
else
download_uri = new_file_uri
@ -160,29 +168,35 @@ class TrackHelper
end
saved = 1
data = download_file(download_uri) # download document file
if data.eql?(nil)
return saved
end
begin
is_submit_form = file_data["forcesavetype"].to_i == 3 # check if the forcesave type is equal to 3 (the form was submitted)
if (is_submit_form)
if (new_file_name)
if is_submit_form
if new_file_name
file_name = DocumentHelper.get_correct_name(File.basename(file_name, cur_ext) + "-form" + download_ext, user_address) # get the correct file name if it already exists
else
file_name = DocumentHelper.get_correct_name(File.basename(file_name, cur_ext) + "-form" + cur_ext, user_address)
end
forcesave_path = DocumentHelper.storage_path(file_name, user_address) # get the path to the new file
else
if (new_file_name)
if new_file_name
file_name = DocumentHelper.get_correct_name(File.basename(file_name, cur_ext) + download_ext, user_address)
end
forcesave_path = DocumentHelper.forcesave_path(file_name, user_address, false)
if (forcesave_path.eql?(""))
if forcesave_path.eql?("")
forcesave_path = DocumentHelper.forcesave_path(file_name, user_address, true) # if the path to the new file doesn't exist, create it
end
end
save_from_uri(forcesave_path, download_uri) # download the form
save_file(data, forcesave_path) # save the downloaded file to the storage directory
if (is_submit_form)
if is_submit_form
uid = file_data['actions'][0]['userid']
DocumentHelper.create_meta(file_name, uid, "Filling Form", user_address) # create file meta information with the Filling form tag instead of user name
end
@ -192,7 +206,7 @@ class TrackHelper
saved = 1
end
return saved
saved
end
# send the command request
@ -238,7 +252,7 @@ class TrackHelper
end
# save file from the url
def save_from_uri(path, uristr)
def download_file(uristr)
uri = URI.parse(uristr) # parse the url string
http = Net::HTTP.new(uri.host, uri.port) # create a connection to the http server
http.open_timeout = 5
@ -249,17 +263,20 @@ class TrackHelper
res = http.request(req) # get the response
status_code = res.code
if status_code != 200 # checking status code
if status_code != '200' # checking status code
raise "Document editing service returned status: #{status_code}"
end
data = res.body # and take its body
if data == nil
raise 'stream is null'
raise 'stream is null'
end
data
end
def save_file(data, path)
File.open(path, 'wb') do |file| # open the file from the path specified
file.write(data) # and write the response data to it
file.write(data) # and write the response data to it
end
end
end