Skip to content

Commit

Permalink
OnlyOffice for kodbox: v3.0, support document history
Browse files Browse the repository at this point in the history
  • Loading branch information
zhtengw committed Jun 1, 2020
1 parent 1434baa commit a035ef9
Show file tree
Hide file tree
Showing 8 changed files with 499 additions and 27 deletions.
219 changes: 201 additions & 18 deletions kodbox-plugins/OnlyOffice/app.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,35 @@ public function index() {
$fileUrl = $this->filePathLinkOut($this->in['path']);
$fileName = $this->fileInfo['name'];
$fileExt = get_path_ext($this->fileInfo['name']);
$mtime = IO::infoFull($path)['modifyTime'];

// kodbox中,同一文件在内部分享链接中打开时,path是不同的,但sourceID不变
// 而本地路径的文件没有sourceID
$sourceID = IO::infoFull($path)['sourceID']? : $path;
//show_tips($sourceID);
$config = $this->getConfig();
if (!empty($this->in['clearhist'])) {
if (Action("explorer.auth")->fileCanWrite($path)) {
// 清空文档历史记录
$histDir = $this->getHistDir($sourceID,false);
$msg_title = "清空文档历史";
if (file_exists($histDir)) {
// 页面上确认清理后调用clearHistDir函数,否则显示取消信息。
echo "<script>if (confirm('是否清理“".$fileName."”的文档历史?')){";
echo "location.href='".$this->pluginApi."clearHistDir&histDir=".$histDir."';}</script>";
$msg_content = "用户取消。";
include($this->pluginPath.'/php/show_msg.php');
return;
} else {
$msg_content = ''.$fileName.'”没有文档历史记录,无需清理。';
include($this->pluginPath.'/php/show_msg.php');
return;
}
} else {
show_tips("没有权限。");
}
}

if (substr(APP_HOST,0,8) == 'https://') {
$dsServer = $config['apiServer-https'];
$http_header = 'https://';
Expand All @@ -32,7 +59,7 @@ public function index() {
$options = [
'document' => [
'fileType' => $this->fileTypeAlias($fileExt),
'key' => IO::hashSimple($path),
'key' => IO::hashSimple($path).$mtime,
'title' => $fileName,
'url' => $fileUrl,
'permissions' => [
Expand All @@ -41,7 +68,7 @@ public function index() {
'print' => true,
],
],
'documentType' => $this->getDocumentType($fileExt),
'documentType' => $this->getDocumentType($fileExt),
'type' => 'desktop',
'editorConfig' => [
'callbackUrl' => "",
Expand All @@ -52,12 +79,13 @@ public function index() {
'name' => Session::get('kodUser.nickName').' ('.Session::get('kodUser.name').')',
],
'customization' => [
'chat' => true,
'autosave' => true,
'chat' => strpos($config['editorOpt'],'chat') !== false? true: false,
'commentAuthorOnly' => true,
'comments' => true,
'comments' => strpos($config['editorOpt'],'comments') !== false? true: false,
'compactHeader' => false,
'compactToolbar' => false,
'help' => false,
'help' => strpos($config['editorOpt'],'help') !== false? true: false,
'toolbarNoTabs' => false,
'hideRightMenu' => false,
],
Expand All @@ -68,12 +96,12 @@ public function index() {

// 设定未登录用户的文档信息
if (Session::get('kodUser') == null) {
$options['user']['id'] = 'guest';
$options['user']['name'] = 'guest';
$options['editorConfig']['user']['id'] = 'guest';
$options['editorConfig']['user']['name'] = 'guest';
$options['document']['permissions']['download'] = false;
$options['document']['permissions']['print'] = false;
}

//可读权限检测,可读则可下载及打印
if (Action("explorer.auth")->fileCanRead($path)) {
$options['document']['permissions']['download'] = true;
Expand All @@ -85,6 +113,28 @@ public function index() {
$options['editorConfig']['mode'] = 'edit';
$options['document']['permissions']['edit'] = true;
$options['editorConfig']['callbackUrl'] = $this->pluginApi.'save&path='.rawurlencode($path);

//如果开启了文档历史记录,且为文字文档
if ($config['history'] && $this->supportHistory($fileExt)) {
$curkey = $options['document']['key'];
$curDocUrl = $options['document']['url'];
$histDir = $this->getHistDir($sourceID,true);

$options['editorConfig']['callbackUrl'] .= '&hist='.$histDir;
$curDoc = file_get_contents($options['document']['url']);
file_put_contents($histDir.'/'.$curkey.'.'.$fileExt,$curDoc,LOCK_EX);

$curInfo = [
'created' => date('Y-m-d H:i:s', $mtime),
'key' => $curkey,
'user' => [
'id' => $options['editorConfig']['user']['id'],
'name' => $options['editorConfig']['user']['name'],
],
];
$allHist = $this->getHistory($histDir,$curInfo,$curDocUrl,$fileExt);
//show_tips($allHist);
}
}
//内部对话框打开时,使用紧凑显示
if ($config['openWith'] == 'dialog') {
Expand All @@ -96,19 +146,113 @@ public function index() {
if (is_wap()) {
$options['type'] = 'mobile';
}

if (strlen($dsServer) > 0) {
include($this->pluginPath.'/php/office.php');
} else {
$error_msg = "OnlyOffice Document Server is not available.<br/>".
"The API of \"".$http_header."\" must be filled.";
"The API of \"".$http_header."\" must be filled.";
show_tips($error_msg);
}
}
public function getHistDir($path,$gen = false) {
//在temp目录生成文档历史文件夹,用路径的md5命名
$pathID = md5($path);
$prefix = 'OnlyOffice/';
$histDir = TEMP_PATH.$prefix.$pathID;
if ($gen) {
if (!file_exists($histDir) && !is_dir($histDir)) {
mk_dir($histDir);
}
}
return $histDir;
}

public function getHistory($histDir,$curInfo, $curUrl,$ext) {
// 文档历史由三个文件提供信息
// history.json 保存基本信息
// docid.扩展名
// changes-docid.zip
// 参考资料:
// https://api.onlyoffice.com/editors/callback
// https://api.onlyoffice.com/editors/history
// https://blog.51cto.com/8200238/2085279
// https://github.com/ONLYOFFICE/document-server-integration/blob/master/web/documentserver-example/php/webeditor-ajax.php

$histInfo = $histDir.'/history.json';
$curkey = $curInfo['key'];
if (file_exists($histInfo) && $history = json_decode(file_get_contents($histInfo),TRUE)) {
$curVer = end($history)['version']+1;

} else {
$curVer = 0;
$history = [];
}
$histData = [];
for ($i = 0; $i <= $curVer; $i++) {
$histObj = [];
$dataObj = [];

$key = $i == $curVer ? $curkey : $history[$i]['key'];
$histObj["key"] = $key;
$histObj["version"] = $i;

$dataObj["key"] = $key;
$dataObj["version"] = $i;
$changesFile = $histDir.'/changes-'.$key.'.zip';
$histDoc = $histDir.'/'.$key.'.'.$ext;
if ($i !== $curVer) {
// changesUrl用handle.php处理以避免CORS
$dataObj["changesUrl"] = $this->pluginHost.'php/handler.php?act=sent&path='.rawurlencode($changesFile);
}
$dataObj["url"] = $i == $curVer ? $curUrl : $this->pluginHost.'php/handler.php?act=sent&path='.rawurlencode($histDoc);

if ($i > 0) {
$prehist = $history[$i-1];
$prekey = $prehist['key'];
$preDoc = $histDir.'/'.$prekey.'.'.$ext;

$dataObj['previous'] = [
"key" => $prekey,
"url" => $this->pluginHost.'php/handler.php?act=sent&path='.rawurlencode($preDoc),
];
}

$histData[$i] = $dataObj;
}
$curInfo['version'] = $curVer;
array_push($history,$curInfo);

$allhist = [];
array_push($allhist, [
"currentVersion" => $curVer,
"history" => $history
],$histData);

return $allhist;
}

public function clearHistDir() {
del_dir($_GET['histDir']);
$msg_title = "清空文档历史";
$msg_content = "清理完成。";
include($this->pluginPath.'/php/show_msg.php');
return "clear history done";
}

private function supportHistory($ext) {
// OnlyOffice文档历史仅支持可编辑的文字文档
$supportExts = array("doc", "docx", "dotx", "html", "odt", "ott", "rtf", "txt");
if (in_array($ext,$supportExts)) {
return true;
} else {
return false;
}
}
private function getDocumentType($ext) {
$ExtsDoc = array("doc", "docm", "docx", "dot", "dotm", "dotx", "epub", "fodt", "htm", "html", "mht", "odt", "pdf", "rtf", "txt", "djvu", "xps");
$ExtsPre = array("fodp", "odp", "pot", "potm", "potx", "pps", "ppsm", "ppsx", "ppt", "pptm", "pptx");
$ExtsSheet = array("csv", "fods", "ods", "xls", "xlsm", "xlsx", "xlt", "xltm", "xltx");
$ExtsDoc = array("doc", "docm", "docx", "dot", "dotm", "dotx", "epub", "fodt", "ott", "htm", "html", "mht", "odt", "pdf", "rtf", "txt", "djvu", "xps");
$ExtsPre = array("fodp", "odp", "pot", "potm", "potx", "pps", "ppsm", "ppsx", "ppt", "pptm", "pptx", "otp");
$ExtsSheet = array("xls", "xlsx", "xltx", "ods", "ots", "csv", "xlt", "xltm", "fods");
if (in_array($ext,$ExtsDoc)) {
return "text";
} elseif (in_array($ext,$ExtsPre)) {
Expand All @@ -130,17 +274,56 @@ private function fileTypeAlias($ext) {
return $ext;
}
public function save() {

$response = ['error' => 0];

if (($body_stream = file_get_contents("php://input")) === FALSE) {
echo "Bad Request";
$response['error'] = "Bad Request";
}
$data = json_decode($body_stream, TRUE);
if ($data["status"] == 2) {
if (($new_office_content = file_get_contents($data["url"])) === FALSE) {
echo "Bad Response";
$response['error'] = "Bad Response";
} else {
$this->pluginCacheFileSet($_GET['path'], $new_office_content);
if (isset($_GET['hist'])) {
$histDir = $_GET['hist'];
$histInfo = $histDir.'/history.json';

// 读取旧历史信息并设定文档版本
if (file_exists($histInfo) && $prehist = file_get_contents($histInfo)) {
$history = json_decode($prehist,TRUE);
$version = end($history)['version'] + 1;
} else {
$history = [];
$version = 0 ;
}

// New history
$key = $data['key'];
$changesFile = $histDir.'/changes-'.$key.'.zip';
$histDoc = $histDir.'/'.$key.'.'.pathinfo($data["url"], PATHINFO_EXTENSION);
$serverVersion = $data['history']['serverVersion'];

$changes = $data['history']['changes'];
if ($changesData = file_get_contents($data['changesurl'])) {
file_put_contents($changesFile,$changesData, LOCK_EX);
}

array_push($history,
array(
"changes" => $changes,
"created" => $changes[0]['created'],
"key" => $key,
"serverVersion" => $serverVersion,
"user" => $changes[0]['user'],
"version" => $version,
)
);
file_put_contents($histInfo,json_encode($history),LOCK_EX);
}
$this->pluginCacheFileSet($_GET['path'], $new_office_content);
}
}
echo "{\"error\":0}";
die(json_encode($response));
}
}
}
7 changes: 7 additions & 0 deletions kodbox-plugins/OnlyOffice/i18n/en.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,14 @@
"OnlyOffice.meta.name" => "OnlyOffice Online Editor",
"OnlyOffice.meta.title" => "OnlyOffice Online Editor",
"OnlyOffice.meta.desc" => "View and Edit office documents online",
"OnlyOffice.clear.title" => "Clean Document History",
"OnlyOffice.Config.office" => "Office Settings",
"OnlyOffice.Config.previewMode" => "Preview Mode",
"OnlyOffice.Config.editorOpt" => "Editor Options",
"OnlyOffice.Config.chat" => "Chat",
"OnlyOffice.Config.comments" => "Comments",
"OnlyOffice.Config.help" => "Help",
"OnlyOffice.Config.history" => "Documents History",
"OnlyOffice.Config.apiServer" => "Document Server API",
"OnlyOffice.Config.apiServerDesc" => "
<div class='can-select pt-10'>
Expand Down
7 changes: 7 additions & 0 deletions kodbox-plugins/OnlyOffice/i18n/zh-CN.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,14 @@
"OnlyOffice.meta.name" => "OnlyOffice 在线编辑器",
"OnlyOffice.meta.title" => "OnlyOffice 在线编辑器",
"OnlyOffice.meta.desc" => "在线查看和编辑Office文档",
"OnlyOffice.clear.title" => "清空文档历史",
"OnlyOffice.Config.office" => "Office设置",
"OnlyOffice.Config.previewMode" => "预览模式",
"OnlyOffice.Config.editorOpt" => "编辑器设置",
"OnlyOffice.Config.chat" => "开启聊天",
"OnlyOffice.Config.comments" => "开启评论",
"OnlyOffice.Config.help" => "显示帮助",
"OnlyOffice.Config.history" => "文档历史",
"OnlyOffice.Config.apiServer" => "服务器接口",
"OnlyOffice.Config.apiServerDesc" => "
<div class='can-select pt-10'>
Expand Down
32 changes: 24 additions & 8 deletions kodbox-plugins/OnlyOffice/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"id":"OnlyOffice",
"name":"{{LNG['OnlyOffice.meta.name']}}",
"title":"{{LNG['OnlyOffice.meta.title']}}",
"version":"2.4",
"version":"3.0",
"category":"file",
"source":{
"icon":"{{pluginHost}}static/images/icon.png",
Expand All @@ -22,7 +22,8 @@
"className":"form-box-title-right",
"tabs":{
"{{LNG['OnlyOffice.Config.apiServer']}}":"apiServer-http,apiServer-https",
"{{LNG['admin.setting.base']}}":"pluginAuth,pluginAuthOpen,sep001,previewMode,openWith,fileExt,fileSort"
"{{LNG['admin.setting.base']}}":"pluginAuth,pluginAuthOpen,sep001,openWith,fileExt,fileSort",
"{{LNG['OnlyOffice.Config.office']}}":"previewMode,editorOpt,history"
}
},
"pluginAuth":{
Expand All @@ -33,11 +34,6 @@
"require":1
},
"sep001":"<hr/>",
"previewMode":{
"type":"switch",
"value":0,
"display":"{{LNG['OnlyOffice.Config.previewMode']}}"
},
"openWith":{
"type":"radio",
"value":"dialog",
Expand All @@ -51,7 +47,7 @@
"type":"tags",
"display":"{{LNG['admin.plugin.fileExt']}}",
"desc":"{{LNG['admin.plugin.fileExtDesc']}}",
"value":"doc,docm,docx,dot,dotm,dotx,epub,fodt,htm,html,mht,odt,pdf,rtf,txt,djvu,xps,fodp,odp,pot,potm,potx,pps,ppsm,ppsx,ppt,pptm,pptx,csv,fods,ods,xls,xlsm,xlsx,xlt,xltm,xltx"
"value":"doc,docx,dotx,epub,html,mht,odt,ott,pdf,rtf,txt,djvu,xps,otp,odp,potx,ppt,pptx,csv,ots,ods,xls,xlsx,xltx"
},
"fileSort":{
"type":"number",
Expand All @@ -70,6 +66,26 @@
"value":"",
"display":"https://",
"desc":"<span class='grey-8'>/web-apps/apps/api/documents/api.js</span>{{LNG['OnlyOffice.Config.apiServerDesc']}}"
},
"previewMode":{
"type":"switch",
"value":0,
"display":"{{LNG['OnlyOffice.Config.previewMode']}}"
},
"editorOpt":{
"type":"checkbox",
"value":"chat,comments,help",
"display":"{{LNG['OnlyOffice.Config.editorOpt']}}",
"info":{
"chat": "{{LNG['OnlyOffice.Config.chat']}}",
"comments":"{{LNG['OnlyOffice.Config.comments']}}",
"help":"{{LNG['OnlyOffice.Config.help']}}"
}
},
"history":{
"type":"switch",
"value":0,
"display":"{{LNG['OnlyOffice.Config.history']}}"
}
}
}
Loading

0 comments on commit a035ef9

Please sign in to comment.