diff --git a/CHANGELOG b/CHANGELOG index d8b20d350..f3c5fdf2e 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -135,6 +135,9 @@ - rest api also checks for duplicate folder/document names if turned on - before moving a document/folder the target folder is checked for an object with the same name, if this is turned on in the configuration +- new controller EmptyFolder (currently not used) +- check for duplicate mails to the same group when a workflow was triggered +- new hook to output clipboard items -------------------------------------------------------------------------------- Changes in version 5.1.11 diff --git a/SeedDMS_Core/Core/inc.ClassFolder.php b/SeedDMS_Core/Core/inc.ClassFolder.php index 6bdf5670d..8a6a06d2e 100644 --- a/SeedDMS_Core/Core/inc.ClassFolder.php +++ b/SeedDMS_Core/Core/inc.ClassFolder.php @@ -1039,6 +1039,12 @@ class SeedDMS_Core_Folder extends SeedDMS_Core_Object { * Remove recursively a folder * * Removes a folder, all its subfolders and documents + * This method triggers the callbacks onPreRemoveFolder and onPostRemoveFolder. + * If onPreRemoveFolder returns a boolean then this method will return + * imediately with the value returned by the callback. Otherwise the + * regular removal is executed, which in turn + * triggers further onPreRemoveFolder and onPostRemoveFolder callbacks + * and its counterparts for documents (onPreRemoveDocument, onPostRemoveDocument). * * @return boolean true on success, false in case of an error */ @@ -1094,6 +1100,62 @@ class SeedDMS_Core_Folder extends SeedDMS_Core_Object { return $ret; } /* }}} */ + /** + * Empty recursively a folder + * + * Removes all subfolders and documents of a folder but not the folder itself + * This method will call remove() on all its children. + * This method triggers the callbacks onPreEmptyFolder and onPostEmptyFolder. + * If onPreEmptyFolder returns a boolean then this method will return + * imediately. + * Be aware that the recursive calls of remove() will trigger the callbacks + * onPreRemoveFolder, onPostRemoveFolder, onPreRemoveDocument and onPostRemoveDocument. + * + * @return boolean true on success, false in case of an error + */ + function empty() { /* {{{ */ + /** @noinspection PhpUnusedLocalVariableInspection */ + $db = $this->_dms->getDB(); + + /* Check if 'onPreEmptyFolder' callback is set */ + if(isset($this->_dms->callbacks['onPreEmptyFolder'])) { + foreach($this->_dms->callbacks['onPreEmptyFolder'] as $callback) { + $ret = call_user_func($callback[0], $callback[1], $this); + if(is_bool($ret)) + return $ret; + } + } + + //Entfernen der Unterordner und Dateien + $res = $this->getSubFolders(); + if (is_bool($res) && !$res) return false; + $res = $this->getDocuments(); + if (is_bool($res) && !$res) return false; + + foreach ($this->_subFolders as $subFolder) { + $res = $subFolder->remove(); + if (!$res) { + return false; + } + } + + foreach ($this->_documents as $document) { + $res = $document->remove(); + if (!$res) { + return false; + } + } + + /* Check if 'onPostEmptyFolder' callback is set */ + if(isset($this->_dms->callbacks['onPostEmptyFolder'])) { + foreach($this->_dms->callbacks['onPostEmptyFolder'] as $callback) { + call_user_func($callback[0], $callback[1], $this); + } + } + + return true; + } /* }}} */ + /** * Returns a list of access privileges * diff --git a/SeedDMS_Core/package.xml b/SeedDMS_Core/package.xml index 21fa59525..a9fbd916e 100644 --- a/SeedDMS_Core/package.xml +++ b/SeedDMS_Core/package.xml @@ -1692,6 +1692,7 @@ add method SeedDMS_Core_DatabaseAccess::setLogFp() - add SeedDMS_Core_Folder::hasSubFolderByName() - fix SeedDMS_Core_Folder::hasDocumentByName() which returned an int > 0 if documents has been loaded before and even if the document searching for was not among them. +- add new method SeedDMS_Core_Folder::empty() diff --git a/controllers/class.EmptyFolder.php b/controllers/class.EmptyFolder.php new file mode 100644 index 000000000..f31f64209 --- /dev/null +++ b/controllers/class.EmptyFolder.php @@ -0,0 +1,76 @@ + + * @copyright Copyright (C) 2010-2013 Uwe Steinmann + * @version Release: @package_version@ + */ + +/** + * Class which does the busines logic for downloading a document + * + * @category DMS + * @package SeedDMS + * @author Uwe Steinmann + * @copyright Copyright (C) 2010-2013 Uwe Steinmann + * @version Release: @package_version@ + */ +class SeedDMS_Controller_EmptyFolder extends SeedDMS_Controller_Common { + + public function run() { + $dms = $this->params['dms']; + $user = $this->params['user']; + $settings = $this->params['settings']; + $folder = $this->params['folder']; + $index = $this->params['index']; + $indexconf = $this->params['indexconf']; + + /* Get the document id and name before removing the document */ + $foldername = $folder->getName(); + $folderid = $folder->getID(); + + if(false === $this->callHook('preEmptyFolder')) { + if(empty($this->errormsg)) + $this->errormsg = 'hook_preEmptyFolder_failed'; + return null; + } + + $result = $this->callHook('emptyFolder', $folder); + if($result === null) { + /* Register a callback which removes each document from the fulltext index + * The callback must return null other the removal will be canceled. + */ + function removeFromIndex($arr, $document) { + $index = $arr[0]; + $indexconf = $arr[1]; + $lucenesearch = new $indexconf['Search']($index); + if($hit = $lucenesearch->getDocument($document->getID())) { + $index->delete($hit->id); + $index->commit(); + } + return null; + } + if($index) + $dms->setCallback('onPreEmptyDocument', 'removeFromIndex', array($index, $indexconf)); + + if (!$folder->empty()) { + $this->errormsg = 'error_occured'; + return false; + } + } elseif($result === false) { + if(empty($this->errormsg)) + $this->errormsg = 'hook_emptyFolder_failed'; + return false; + } + + if(!$this->callHook('postEmptyFolder')) { + } + + return true; + } +} diff --git a/op/op.TriggerWorkflow.php b/op/op.TriggerWorkflow.php index 0e0e46d4f..5c572f08d 100644 --- a/op/op.TriggerWorkflow.php +++ b/op/op.TriggerWorkflow.php @@ -117,6 +117,7 @@ if($version->triggerWorkflowTransition($user, $transition, $_POST["comment"])) { $params['url'] = "http".((isset($_SERVER['HTTPS']) && (strcmp($_SERVER['HTTPS'],'off')!=0)) ? "s" : "")."://".$_SERVER['HTTP_HOST'].$settings->_httpRoot."out/out.ViewDocument.php?documentid=".$document->getID(); $usersinformed = array(); + $groupsinformed = array(); foreach($workflow->getNextTransitions($transition->getNextState()) as $ntransition) { foreach($ntransition->getUsers() as $tuser) { if(!in_array($tuser->getUser()->getID(), $usersinformed)) { @@ -125,7 +126,10 @@ if($version->triggerWorkflowTransition($user, $transition, $_POST["comment"])) { } } foreach($ntransition->getGroups() as $tuser) { - $notifier->toGroup($user, $tuser->getGroup(), $subject, $message, $params); + if(!in_array($tuser->getUser()->getID(), $groupsinformed)) { + $groupsinformed[] = $tuser->getGroup()->getID(); + $notifier->toGroup($user, $tuser->getGroup(), $subject, $message, $params); + } } } } diff --git a/views/bootstrap/class.Bootstrap.php b/views/bootstrap/class.Bootstrap.php index 11c97804f..afb1f5d48 100644 --- a/views/bootstrap/class.Bootstrap.php +++ b/views/bootstrap/class.Bootstrap.php @@ -1144,6 +1144,7 @@ background-image: linear-gradient(to bottom, #882222, #111111);; $icons["sxm"] = "ooo_formula.png"; $icons["smf"] = "ooo_formula.png"; $icons["mml"] = "ooo_formula.png"; + $icons["folder"] = "folder.svg"; $icons["default"] = "text-x-preview.svg"; //"default.png"; @@ -2522,7 +2523,7 @@ $(document).ready( function() { $content = ''; $content .= "getID()."\" draggable=\"true\" rel=\"folder_".$subFolder->getID()."\" class=\"folder table-row-folder\" formtoken=\"".createFormKey('movefolder')."\">"; - $content .= "getID()."\" draggable=\"false\" href=\"../out/out.ViewFolder.php?folderid=".$subFolder->getID()."&showtree=".$showtree."\">imgpath."folder.svg\" width=\"24\" height=\"24\" border=0>\n"; + $content .= "getID()."\" draggable=\"false\" href=\"../out/out.ViewFolder.php?folderid=".$subFolder->getID()."&showtree=".$showtree."\">getMimeIcon(".folder")."\" width=\"24\" height=\"24\" border=0>\n"; $content .= "getID()."\" href=\"../out/out.ViewFolder.php?folderid=".$subFolder->getID()."&showtree=".$showtree."\">" . htmlspecialchars($subFolder->getName()) . ""; $content .= "
".getMLText('owner').": ".htmlspecialchars($owner->getFullName()).", ".getMLText('creation_date').": ".date('Y-m-d', $subFolder->getDate()).""; if($comment) { diff --git a/views/bootstrap/class.Clipboard.php b/views/bootstrap/class.Clipboard.php index d912e2e57..34f2f4451 100644 --- a/views/bootstrap/class.Clipboard.php +++ b/views/bootstrap/class.Clipboard.php @@ -91,6 +91,79 @@ class SeedDMS_View_Clipboard extends SeedDMS_Bootstrap_Style { echo $content; } /* }}} */ + /** + * Return row of clipboard for a folder + * + * @param object $folder + * @return string rendered html content + */ + public function folderClipboardRow($folder) { /* {{{ */ + $dms = $this->params['dms']; + + $content = ''; + $comment = $folder->getComment(); + if (strlen($comment) > 150) $comment = substr($comment, 0, 147) . "..."; + $content .= "getID()."\" class=\"folder table-row-folder\" formtoken=\"".createFormKey('movefolder')."\">"; + $content .= "getID()."&showtree=".showtree()."\">getMimeIcon(".folder")."\" width=\"24\" height=\"24\" border=0>\n"; + $content .= "getID()."&showtree=".showtree()."\">" . htmlspecialchars($folder->getName()) . ""; + if($comment) { + $content .= "
".htmlspecialchars($comment).""; + } + $content .= "\n"; + $content .= "\n"; + $content .= ""; + $content .= "\n"; + $content .= "\n"; + + return $content; + } /* }}} */ + + /** + * Return row of clipboard for a document + * + * @param object $document + * @return string rendered html content + */ + public function documentClipboardRow($document, $previewer) { /* {{{ */ + $dms = $this->params['dms']; + + $content = ''; + $comment = $document->getComment(); + if (strlen($comment) > 150) $comment = substr($comment, 0, 147) . "..."; + $latestContent = $this->callHook('documentLatestContent', $document); + if($latestContent === null) + $latestContent = $document->getLatestContent(); + if($latestContent) { + $previewer->createPreview($latestContent); + $version = $latestContent->getVersion(); + $status = $latestContent->getStatus(); + + $content .= "getID()."\" class=\"table-row-document\" formtoken=\"".createFormKey('movedocument')."\">"; + + if (file_exists($dms->contentDir . $latestContent->getPath())) { + $content .= "getID()."&version=".$version."\">"; + if($previewer->hasPreview($latestContent)) { + $content .= "getID()."&version=".$latestContent->getVersion()."&width=40\" title=\"".htmlspecialchars($latestContent->getMimeType())."\">"; + } else { + $content .= "getMimeIcon($latestContent->getFileType())."\" title=\"".htmlspecialchars($latestContent->getMimeType())."\">"; + } + $content .= ""; + } else + $content .= "getMimeIcon($latestContent->getFileType())."\" title=\"".htmlspecialchars($latestContent->getMimeType())."\">"; + + $content .= "getID()."&showtree=".showtree()."\">" . htmlspecialchars($document->getName()) . ""; + if($comment) { + $content .= "
".htmlspecialchars($comment).""; + } + $content .= "\n"; + $content .= "\n"; + $content .= ""; + $content .= "\n"; + $content .= ""; + } + return $content; + } /* }}} */ + /** * Return clipboard content rendered as html * @@ -112,19 +185,13 @@ class SeedDMS_View_Clipboard extends SeedDMS_Bootstrap_Style { foreach($clipboard['folders'] as $folderid) { /* FIXME: check for access rights, which could have changed after adding the folder to the clipboard */ if($folder = $dms->getFolder($folderid)) { - $comment = $folder->getComment(); - if (strlen($comment) > 150) $comment = substr($comment, 0, 147) . "..."; - $content .= "getID()."\" class=\"folder table-row-folder\" formtoken=\"".createFormKey('movefolder')."\">"; - $content .= "getID()."&showtree=".showtree()."\">imgpath."folder.png\" width=\"24\" height=\"24\" border=0>\n"; - $content .= "getID()."&showtree=".showtree()."\">" . htmlspecialchars($folder->getName()) . ""; - if($comment) { - $content .= "
".htmlspecialchars($comment).""; + $txt = $this->callHook('folderClipboardItem', $folder, 'clipboard'); + if(is_string($txt)) + $content .= $txt; + else { + $content .= $this->folderClipboardRow($folder); } - $content .= "\n"; - $content .= "\n"; - $content .= ""; - $content .= "\n"; - $content .= "\n"; + $foldercount++; } } @@ -133,40 +200,15 @@ class SeedDMS_View_Clipboard extends SeedDMS_Bootstrap_Style { foreach($clipboard['docs'] as $docid) { /* FIXME: check for access rights, which could have changed after adding the document to the clipboard */ if($document = $dms->getDocument($docid)) { - $comment = $document->getComment(); - if (strlen($comment) > 150) $comment = substr($comment, 0, 147) . "..."; - $latestContent = $this->callHook('documentLatestContent', $document); - if($latestContent === null) - $latestContent = $document->getLatestContent(); - if($latestContent) { - $previewer->createPreview($latestContent); - $version = $latestContent->getVersion(); - $status = $latestContent->getStatus(); - - $content .= ""; - - if (file_exists($dms->contentDir . $latestContent->getPath())) { - $content .= ""; - if($previewer->hasPreview($latestContent)) { - $content .= "getID()."&version=".$latestContent->getVersion()."&width=40\" title=\"".htmlspecialchars($latestContent->getMimeType())."\">"; - } else { - $content .= "getMimeIcon($latestContent->getFileType())."\" title=\"".htmlspecialchars($latestContent->getMimeType())."\">"; - } - $content .= ""; - } else - $content .= "getMimeIcon($latestContent->getFileType())."\" title=\"".htmlspecialchars($latestContent->getMimeType())."\">"; - - $content .= "" . htmlspecialchars($document->getName()) . ""; - if($comment) { - $content .= "
".htmlspecialchars($comment).""; - } - $content .= "\n"; - $content .= "\n"; - $content .= ""; - $content .= "\n"; - $content .= ""; - $doccount++; + $document->verifyLastestContentExpriry(); + $txt = $this->callHook('documentClipboardItem', $document, $previewer, 'clipboard'); + if(is_string($txt)) + $content .= $txt; + else { + $content .= $this->documentClipboardRow($document, $previewer); } + + $doccount++; } } } diff --git a/views/bootstrap/class.ErrorDlg.php b/views/bootstrap/class.ErrorDlg.php index ef5cc64ed..66bd63507 100644 --- a/views/bootstrap/class.ErrorDlg.php +++ b/views/bootstrap/class.ErrorDlg.php @@ -40,7 +40,7 @@ class SeedDMS_View_ErrorDlg extends SeedDMS_Bootstrap_Style { $settings = $this->params['settings']; if(!$plain) { - $this->htmlStartPage($pagetitle, 'errorpage', $settings->_httpRoot."out"); + $this->htmlStartPage($pagetitle, 'errorpage', $settings->_httpRoot."out/"); $this->globalNavigation(); $this->contentStart(); }