From 0012de73378a0715ae49a09c8d2217ddc9cff1f8 Mon Sep 17 00:00:00 2001 From: Uwe Steinmann Date: Thu, 23 Nov 2023 15:50:25 +0100 Subject: [PATCH 01/13] allow ttf files in directory 'res' --- .htaccess | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.htaccess b/.htaccess index 69e29975e..d9ef34429 100644 --- a/.htaccess +++ b/.htaccess @@ -32,7 +32,7 @@ RewriteRule ^ext/[^/]+/icon.(?:png|svg)$ - [L] RewriteCond %{REQUEST_URI} "ext/[^/]+/" RewriteRule !^ext/[^/]+/.*(?:op|out|res|node_modules) - [F] RewriteCond %{REQUEST_URI} "ext/[^/]+/res/.*$" [NC] -RewriteRule !^ext/[^/]+/res/.*\.(?:css|js|png|gif|svg|ico|html|woff) - [F] +RewriteRule !^ext/[^/]+/res/.*\.(?:css|js|png|gif|svg|ico|html|woff|ttf) - [F] RewriteCond %{REQUEST_FILENAME} -f RewriteRule ^ext/.*$ - [L] From d59a4c18c9f2a62793ee192ddde6a2fedf51733e Mon Sep 17 00:00:00 2001 From: Uwe Steinmann Date: Tue, 28 Nov 2023 10:23:08 +0100 Subject: [PATCH 02/13] use conversion manager --- out/out.Clipboard.php | 2 ++ views/bootstrap/class.Clipboard.php | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/out/out.Clipboard.php b/out/out.Clipboard.php index 4460a3012..3d5147f1b 100644 --- a/out/out.Clipboard.php +++ b/out/out.Clipboard.php @@ -43,7 +43,9 @@ if (isset($_GET["folderid"]) && is_numeric($_GET["folderid"])) { if($view) { $view->setParam('folder', $folder); + $view->setParam('conversionmgr', $conversionmgr); $view->setParam('previewWidthList', $settings->_previewWidthList); + $view->setParam('previewConverters', isset($settings->_converters['preview']) ? $settings->_converters['preview'] : array()); $view->setParam('timeout', $settings->_cmdTimeout); $view->setParam('xsendfile', $settings->_enableXsendfile); $view($_GET); diff --git a/views/bootstrap/class.Clipboard.php b/views/bootstrap/class.Clipboard.php index 0bbc0c7b0..3b75db496 100644 --- a/views/bootstrap/class.Clipboard.php +++ b/views/bootstrap/class.Clipboard.php @@ -159,11 +159,17 @@ class SeedDMS_View_Clipboard extends SeedDMS_Theme_Style { $dms = $this->params['dms']; $clipboard = $this->params['session']->getClipboard(); $cachedir = $this->params['cachedir']; + $conversionmgr = $this->params['conversionmgr']; $previewwidth = $this->params['previewWidthList']; + $previewconverters = $this->params['previewConverters']; $timeout = $this->params['timeout']; $xsendfile = $this->params['xsendfile']; $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout, $xsendfile); + if($conversionmgr) + $previewer->setConversionMgr($conversionmgr); + else + $previewer->setConverters($previewconverters); $content = ''; $txt = $this->callHook('preClipboard', $clipboard); if(is_string($txt)) From 8ff33030157eafc425db28934f2bebfadb5bf130 Mon Sep 17 00:00:00 2001 From: Uwe Steinmann Date: Tue, 28 Nov 2023 10:23:23 +0100 Subject: [PATCH 03/13] add changes for 5.1.33 --- CHANGELOG | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG b/CHANGELOG index 2134d49ee..07d4f0baa 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -17,6 +17,7 @@ - nicer output on info page - do not show filter for categories in database search if they don't exist - show logs of finished worflows +- show preview of documents on clipboard -------------------------------------------------------------------------------- Changes in version 5.1.32 From dbb938157321757e5a6be805f3891ec444711adc Mon Sep 17 00:00:00 2001 From: Uwe Steinmann Date: Thu, 30 Nov 2023 16:59:00 +0100 Subject: [PATCH 04/13] use controller when adding a new document --- restapi/index.php | 89 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 87 insertions(+), 2 deletions(-) diff --git a/restapi/index.php b/restapi/index.php index 3eceae4f0..85abbbd5a 100644 --- a/restapi/index.php +++ b/restapi/index.php @@ -608,6 +608,7 @@ class RestapiController { /* {{{ */ $userobj = $this->container->userobj; $settings = $this->container->config; $notifier = $this->container->notifier; + $fulltextservice = $this->container->fulltextservice; if(!$userobj) { return $response->withJson(array('success'=>false, 'message'=>'Not logged in', 'data'=>''), 403); @@ -693,11 +694,94 @@ class RestapiController { /* {{{ */ return $response->withJson(array('success'=>false, 'message'=>getMLText("document_duplicate_name"), 'data'=>''), 409); } } + // Get the list of reviewers and approvers for this document. + $reviewers = array(); + $approvers = array(); + $reviewers["i"] = array(); + $reviewers["g"] = array(); + $approvers["i"] = array(); + $approvers["g"] = array(); + $workflow = null; + if($settings->_workflowMode == 'traditional' || $settings->_workflowMode == 'traditional_only_approval') { + // add mandatory reviewers/approvers + if($settings->_workflowMode == 'traditional') { + $mreviewers = getMandatoryReviewers($folder, $userobj); + if($mreviewers['i']) + $reviewers['i'] = array_merge($reviewers['i'], $mreviewers['i']); + if($mreviewers['g']) + $reviewers['g'] = array_merge($reviewers['g'], $mreviewers['g']); + } + $mapprovers = getMandatoryApprovers($folder, $userobj); + if($mapprovers['i']) + $approvers['i'] = array_merge($approvers['i'], $mapprovers['i']); + if($mapprovers['g']) + $approvers['g'] = array_merge($approvers['g'], $mapprovers['g']); + } elseif($settings->_workflowMode == 'advanced') { + if($workflows = $userobj->getMandatoryWorkflows()) { + $workflow = array_shift($workflows); + } + } $temp = $file_info->file; $finfo = finfo_open(FILEINFO_MIME_TYPE); $userfiletype = finfo_file($finfo, $temp); $fileType = ".".pathinfo($origfilename, PATHINFO_EXTENSION); - finfo_close($finfo); + finfo_close($finfo); + $attributes_version = []; + $notusers = []; + $notgroups = []; + $controller = Controller::factory('AddDocument'); + $controller->setParam('documentsource', 'restapi'); + $controller->setParam('documentsourcedetails', null); + $controller->setParam('dms', $dms); + $controller->setParam('user', $userobj); + $controller->setParam('folder', $mfolder); + $controller->setParam('fulltextservice', $fulltextservice); + $controller->setParam('name', $docname); + $controller->setParam('comment', $comment); + $controller->setParam('expires', $expires); + $controller->setParam('keywords', $keywords); + $controller->setParam('categories', $cats); + $controller->setParam('owner', $owner ? $owner : $userobj); + $controller->setParam('userfiletmp', $temp); + $controller->setParam('userfilename', $origfilename ? $origfilename : basename($temp)); + $controller->setParam('filetype', $fileType); + $controller->setParam('userfiletype', $userfiletype); + $controller->setParam('sequence', $sequence); + $controller->setParam('reviewers', $reviewers); + $controller->setParam('approvers', $approvers); + $controller->setParam('reqversion', $reqversion); + $controller->setParam('versioncomment', $version_comment); + $controller->setParam('attributes', $attributes); + $controller->setParam('attributesversion', $attributes_version); + $controller->setParam('workflow', $workflow); + $controller->setParam('notificationgroups', $notgroups); + $controller->setParam('notificationusers', $notusers); + $controller->setParam('maxsizeforfulltext', $settings->_maxSizeForFullText); + $controller->setParam('defaultaccessdocs', $settings->_defaultAccessDocs); + + if(!($document = $controller())) { + $err = $controller->getErrorMsg(); + if(is_string($err)) + $errmsg = getMLText($err); + elseif(is_array($err)) { + $errmsg = getMLText($err[0], $err[1]); + } else { + $errmsg = $err; + } + unlink($temp); + return $response->withJson(array('success'=>false, 'message'=>'Upload failed', 'data'=>''), 500); + } else { + if($controller->hasHook('cleanUpDocument')) { + $controller->callHook('cleanUpDocument', $document, $file); + } + // Send notification to subscribers of folder. + if($notifier) { + $notifier->sendNewDocumentMail($document, $userobj); + } + unlink($temp); + return $response->withJson(array('success'=>true, 'message'=>'Upload succeded', 'data'=>$this->__getLatestVersionData($document->getLatestContent())), 201); + } + /* $res = $mfolder->addDocument($docname, $comment, $expires, $owner ? $owner : $userobj, $keywords, $cats, $temp, $origfilename ? $origfilename : basename($temp), $fileType, $userfiletype, $sequence, array(), array(), $reqversion, $version_comment, $attributes); unlink($temp); if($res) { @@ -708,7 +792,8 @@ class RestapiController { /* {{{ */ return $response->withJson(array('success'=>true, 'message'=>'Upload succeded', 'data'=>$this->__getLatestVersionData($doc->getLatestContent())), 201); } else { return $response->withJson(array('success'=>false, 'message'=>'Upload failed', 'data'=>''), 500); - } + } + */ } else { return $response->withJson(array('success'=>false, 'message'=>'No access', 'data'=>''), 403); } From 1133d655443d9c3619837d30bc58bc6e02b67be7 Mon Sep 17 00:00:00 2001 From: Uwe Steinmann Date: Thu, 30 Nov 2023 17:00:18 +0100 Subject: [PATCH 05/13] new method to delete group --- restapi/index.php | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/restapi/index.php b/restapi/index.php index 85abbbd5a..f28a86220 100644 --- a/restapi/index.php +++ b/restapi/index.php @@ -2201,6 +2201,25 @@ class RestapiController { /* {{{ */ return $response->withJson(array('success'=>true, 'message'=>'', 'data'=>$this->__getGroupData($newGroup)), 201); } /* }}} */ + function deleteGroup($request, $response, $args) { /* {{{ */ + $dms = $this->container->dms; + $userobj = $this->container->userobj; + + $check = $this->checkIfAdmin($request, $response); + if($check !== true) + return $check; + + if($group = $dms->getGroup($args['id'])) { + if($result = $group->remove($userobj)) { + return $response->withJson(array('success'=>$result, 'message'=>'', 'data'=>''), 200); + } else { + return $response->withJson(array('success'=>$result, 'message'=>'Could not delete group', 'data'=>''), 500); + } + } else { + return $response->withJson(array('success'=>false, 'message'=>'No such group', 'data'=>''), 404); + } + } /* }}} */ + function getGroup($request, $response, $args) { /* {{{ */ $dms = $this->container->dms; $userobj = $this->container->userobj; @@ -2869,6 +2888,7 @@ $app->put('/users/{id}/disable', \RestapiController::class.':setDisabledUser'); $app->put('/users/{id}/password', \RestapiController::class.':changeUserPassword'); $app->post('/groups', \RestapiController::class.':createGroup'); $app->get('/groups', \RestapiController::class.':getGroups'); +$app->delete('/groups/{id}', \RestapiController::class.':deleteGroup'); $app->get('/groups/{id}', \RestapiController::class.':getGroup'); $app->put('/groups/{id}/addUser', \RestapiController::class.':addUserToGroup'); $app->put('/groups/{id}/removeUser', \RestapiController::class.':removeUserFromGroup'); From b131c63dd78957df8520376622b74001129b625a Mon Sep 17 00:00:00 2001 From: Uwe Steinmann Date: Thu, 30 Nov 2023 17:01:16 +0100 Subject: [PATCH 06/13] fix error msg when creating a group without passing a name --- restapi/index.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/restapi/index.php b/restapi/index.php index f28a86220..eebf0182a 100644 --- a/restapi/index.php +++ b/restapi/index.php @@ -2186,7 +2186,7 @@ class RestapiController { /* {{{ */ return $check; $params = $request->getParsedBody(); if (empty($params['name'])) { - return $response->withJson(array('success'=>false, 'message'=>'Need a category.', 'data'=>''), 400); + return $response->withJson(array('success'=>false, 'message'=>'Need a group name.', 'data'=>''), 400); } $groupName = $params['name']; From 576b866b7f6cd9c6536d6cd95aab65ca505d7e6c Mon Sep 17 00:00:00 2001 From: Uwe Steinmann Date: Thu, 30 Nov 2023 17:02:28 +0100 Subject: [PATCH 07/13] fix return code of changeGroupMembership() if no user id is passed --- restapi/index.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/restapi/index.php b/restapi/index.php index eebf0182a..9766a8de7 100644 --- a/restapi/index.php +++ b/restapi/index.php @@ -2260,7 +2260,7 @@ class RestapiController { /* {{{ */ $params = $request->getParsedBody(); if (empty($params['userid'])) { - return $response->withJson(array('success'=>false, 'message'=>'Missing userid', 'data'=>''), 200); + return $response->withJson(array('success'=>false, 'message'=>'Missing userid', 'data'=>''), 500); } $userId = $params['userid']; if(ctype_digit($userId)) From 03de004b3056a156ebd62a00f6d0358eaf4dda3c Mon Sep 17 00:00:00 2001 From: Uwe Steinmann Date: Thu, 30 Nov 2023 17:02:51 +0100 Subject: [PATCH 08/13] fix calling changeGroupMembership() --- restapi/index.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/restapi/index.php b/restapi/index.php index 9766a8de7..15a695ec2 100644 --- a/restapi/index.php +++ b/restapi/index.php @@ -2303,11 +2303,11 @@ class RestapiController { /* {{{ */ } /* }}} */ function addUserToGroup($request, $response, $args) { /* {{{ */ - return changeGroupMembership($request, $response, $args, 'add'); + return $this->changeGroupMembership($request, $response, $args, 'add'); } /* }}} */ function removeUserFromGroup($request, $response, $args) { /* {{{ */ - return changeGroupMembership($request, $response, $args, 'remove'); + return $this->changeGroupMembership($request, $response, $args, 'remove'); } /* }}} */ function setFolderInheritsAccess($request, $response, $args) { /* {{{ */ From 2a2035cccff2be355d914ec6d2462e25a7ab12be Mon Sep 17 00:00:00 2001 From: Uwe Steinmann Date: Wed, 13 Dec 2023 08:07:38 +0100 Subject: [PATCH 09/13] use showActions() to output list of buttons on attachment tab --- views/bootstrap/class.ViewDocument.php | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/views/bootstrap/class.ViewDocument.php b/views/bootstrap/class.ViewDocument.php index 074abeb14..a1e9bec76 100644 --- a/views/bootstrap/class.ViewDocument.php +++ b/views/bootstrap/class.ViewDocument.php @@ -141,7 +141,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Theme_Style { $txt = $this->callHook('documentListItem', $document, $previewer, false, 'viewitem'); if(is_string($txt)) $content = $txt; - else + else $content = $this->documentListRow($document, $previewer, true); echo $content; } @@ -337,7 +337,8 @@ $(document).ready( function() { } print ""; - print "
    \n"; + print ""; + print "
      \n"; print "
    • ".htmlspecialchars($file->getName())."
    • \n"; if($file->getName() != $file->getOriginalFileName()) print "
    • ".htmlspecialchars($file->getOriginalFileName())."
    • \n"; @@ -355,23 +356,26 @@ $(document).ready( function() { print "
    "; print "".htmlspecialchars($file->getComment()).""; - print "
      "; + $this->showActions($items); + $items = []; if (($document->getAccessMode($user) == M_ALL)||($file->getUserID()==$user->getID())) { - print $this->html_link('RemoveDocumentFile', array('documentid'=>$document->getID(), 'fileid'=>$file->getID()), array(), ''.getMLText("delete"), false, true, array('
    • ', '
    • ')); - print $this->html_link('EditDocumentFile', array('documentid'=>$document->getID(), 'fileid'=>$file->getID()), array(), ''.getMLText("edit"), false, true, array('
    • ', '
    • ')); + $items[] = array('link'=>$this->html_url('RemoveDocumentFile', array('documentid'=>$document->getID(), 'fileid'=>$file->getID())), 'icon'=>'remove', 'label'=>'delete'); + $items[] = array('link'=>$this->html_url('EditDocumentFile', array('documentid'=>$document->getID(), 'fileid'=>$file->getID())), 'icon'=>'edit', 'label'=>'edit'); } - print "
    "; + $this->showActions($items); + print ""; print ""; } From cab5f5bb2ef3173ef96b93ec9d639dcf72103d28 Mon Sep 17 00:00:00 2001 From: Uwe Steinmann Date: Wed, 13 Dec 2023 08:23:19 +0100 Subject: [PATCH 10/13] __getDocumentData() sets categories --- restapi/index.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/restapi/index.php b/restapi/index.php index 15a695ec2..97a9cf3b2 100644 --- a/restapi/index.php +++ b/restapi/index.php @@ -44,13 +44,19 @@ class RestapiController { /* {{{ */ } /* }}} */ protected function __getDocumentData($document) { /* {{{ */ + $cats = $document->getCategories(); + $tmp = []; + foreach($cats as $cat) { + $tmp[] = $this->__getCategoryData($cat); + } $data = array( 'type'=>'document', 'id'=>(int)$document->getId(), 'date'=>date('Y-m-d H:i:s', $document->getDate()), 'name'=>$document->getName(), 'comment'=>$document->getComment(), - 'keywords'=>$document->getKeywords() + 'keywords'=>$document->getKeywords(), + 'categories'=>$tmp ); return $data; } /* }}} */ From 1ac232476a86076f403576961faf5042eee354f9 Mon Sep 17 00:00:00 2001 From: Uwe Steinmann Date: Wed, 13 Dec 2023 08:23:58 +0100 Subject: [PATCH 11/13] simplified removeDocumentCategory --- restapi/index.php | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/restapi/index.php b/restapi/index.php index 97a9cf3b2..8f391f6c3 100644 --- a/restapi/index.php +++ b/restapi/index.php @@ -1562,24 +1562,20 @@ class RestapiController { /* {{{ */ } $document = $dms->getDocument($args['id']); + if(!$document) + return $response->withJson(array('success'=>false, 'message'=>'No such document', 'data'=>''), 404); $category = $dms->getDocumentCategory($args['catid']); + if(!$category) + return $response->withJson(array('success'=>false, 'message'=>'No such category', 'data'=>''), 404); - if($document && $category) { - if ($document->getAccessMode($userobj, 'removeDocumentCategory') >= M_READWRITE) { - $ret = $document->removeCategories(array($category)); - if ($ret) - return $response->withJson(array('success'=>true, 'message'=>'Deleted category successfully.', 'data'=>''), 200); - else - return $response->withJson(array('success'=>true, 'message'=>'', 'data'=>''), 200); - } else { - return $response->withJson(array('success'=>false, 'message'=>'No access', 'data'=>''), 403); - } + if ($document->getAccessMode($userobj, 'removeDocumentCategory') >= M_READWRITE) { + $ret = $document->removeCategories(array($category)); + if ($ret) + return $response->withJson(array('success'=>true, 'message'=>'Deleted category successfully.', 'data'=>''), 200); + else + return $response->withJson(array('success'=>true, 'message'=>'', 'data'=>''), 200); } else { - if(!$document) - return $response->withJson(array('success'=>false, 'message'=>'No such document', 'data'=>''), 404); - if(!$category) - return $response->withJson(array('success'=>false, 'message'=>'No such category', 'data'=>''), 404); - return $response->withJson(array('success'=>false, 'message'=>'', 'data'=>''), 500); + return $response->withJson(array('success'=>false, 'message'=>'No access', 'data'=>''), 403); } } /* }}} */ From 08415039ca41d775a76cb88df570f7294d51fe4a Mon Sep 17 00:00:00 2001 From: Uwe Steinmann Date: Wed, 13 Dec 2023 08:24:30 +0100 Subject: [PATCH 12/13] add name of attribute def. in error msg when setting an attribute --- restapi/index.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/restapi/index.php b/restapi/index.php index 8f391f6c3..9d744745c 100644 --- a/restapi/index.php +++ b/restapi/index.php @@ -1669,7 +1669,7 @@ class RestapiController { /* {{{ */ $doc = $dms->getDocument($args['id']); if($doc && $attrdef) { if($attrdef->getObjType() !== SeedDMS_Core_AttributeDefinition::objtype_document) { - return $response->withJson(array('success'=>false, 'message'=>'Attribute definition not suitable for documents', 'data'=>''), 409); + return $response->withJson(array('success'=>false, 'message'=>'Attribute definition "'.$attrdef->getName().'" not suitable for documents', 'data'=>''), 409); } $params = $request->getParsedBody(); @@ -1726,7 +1726,7 @@ class RestapiController { /* {{{ */ $version = $doc->getContentByVersion($args['version']); if($doc && $attrdef && $version) { if($attrdef->getObjType() !== SeedDMS_Core_AttributeDefinition::objtype_documentcontent) { - return $response->withJson(array('success'=>false, 'message'=>'Attribute definition not suitable for document versions', 'data'=>''), 409); + return $response->withJson(array('success'=>false, 'message'=>'Attribute definition "'.$attrdef->getName().'" not suitable for document versions', 'data'=>''), 409); } $params = $request->getParsedBody(); @@ -1780,7 +1780,7 @@ class RestapiController { /* {{{ */ $obj = $dms->getFolder($args['id']); if($obj && $attrdef) { if($attrdef->getObjType() !== SeedDMS_Core_AttributeDefinition::objtype_folder) { - return $response->withJson(array('success'=>false, 'message'=>'Attribute definition not suitable for folders', 'data'=>''), 409); + return $response->withJson(array('success'=>false, 'message'=>'Attribute definition "'.$attrdef->getName().'" not suitable for folders', 'data'=>''), 409); } $params = $request->getParsedBody(); From f330477003046083e2ceafe7fcc0013ffcd69cd6 Mon Sep 17 00:00:00 2001 From: Uwe Steinmann Date: Wed, 13 Dec 2023 08:26:16 +0100 Subject: [PATCH 13/13] add changes for 5.1.33 --- CHANGELOG | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index 07d4f0baa..9477ffeaf 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -18,6 +18,8 @@ - do not show filter for categories in database search if they don't exist - show logs of finished worflows - show preview of documents on clipboard +- minor improvements in restapi +- update layout of tab for attachments -------------------------------------------------------------------------------- Changes in version 5.1.32