Merge branch 'seeddms-5.1.x' into seeddms-6.0.x

This commit is contained in:
Uwe Steinmann 2019-07-05 08:10:42 +02:00
commit 801f0f0ed2
8 changed files with 237 additions and 48 deletions

View File

@ -135,6 +135,9 @@
- rest api also checks for duplicate folder/document names if turned on - 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 - 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 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 Changes in version 5.1.11

View File

@ -1039,6 +1039,12 @@ class SeedDMS_Core_Folder extends SeedDMS_Core_Object {
* Remove recursively a folder * Remove recursively a folder
* *
* Removes a folder, all its subfolders and documents * 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 * @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; 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 * Returns a list of access privileges
* *

View File

@ -1692,6 +1692,7 @@ add method SeedDMS_Core_DatabaseAccess::setLogFp()
- add SeedDMS_Core_Folder::hasSubFolderByName() - add SeedDMS_Core_Folder::hasSubFolderByName()
- fix SeedDMS_Core_Folder::hasDocumentByName() which returned an int > 0 if documents - 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. has been loaded before and even if the document searching for was not among them.
- add new method SeedDMS_Core_Folder::empty()
</notes> </notes>
</release> </release>
<release> <release>

View File

@ -0,0 +1,76 @@
<?php
/**
* Implementation of EmptyFolder controller
*
* @category DMS
* @package SeedDMS
* @license GPL 2
* @version @version@
* @author Uwe Steinmann <uwe@steinmann.cx>
* @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 <uwe@steinmann.cx>
* @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;
}
}

View File

@ -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(); $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(); $usersinformed = array();
$groupsinformed = array();
foreach($workflow->getNextTransitions($transition->getNextState()) as $ntransition) { foreach($workflow->getNextTransitions($transition->getNextState()) as $ntransition) {
foreach($ntransition->getUsers() as $tuser) { foreach($ntransition->getUsers() as $tuser) {
if(!in_array($tuser->getUser()->getID(), $usersinformed)) { if(!in_array($tuser->getUser()->getID(), $usersinformed)) {
@ -125,7 +126,10 @@ if($version->triggerWorkflowTransition($user, $transition, $_POST["comment"])) {
} }
} }
foreach($ntransition->getGroups() as $tuser) { 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);
}
} }
} }
} }

View File

@ -1144,6 +1144,7 @@ background-image: linear-gradient(to bottom, #882222, #111111);;
$icons["sxm"] = "ooo_formula.png"; $icons["sxm"] = "ooo_formula.png";
$icons["smf"] = "ooo_formula.png"; $icons["smf"] = "ooo_formula.png";
$icons["mml"] = "ooo_formula.png"; $icons["mml"] = "ooo_formula.png";
$icons["folder"] = "folder.svg";
$icons["default"] = "text-x-preview.svg"; //"default.png"; $icons["default"] = "text-x-preview.svg"; //"default.png";
@ -2522,7 +2523,7 @@ $(document).ready( function() {
$content = ''; $content = '';
$content .= "<tr id=\"table-row-folder-".$subFolder->getID()."\" draggable=\"true\" rel=\"folder_".$subFolder->getID()."\" class=\"folder table-row-folder\" formtoken=\"".createFormKey('movefolder')."\">"; $content .= "<tr id=\"table-row-folder-".$subFolder->getID()."\" draggable=\"true\" rel=\"folder_".$subFolder->getID()."\" class=\"folder table-row-folder\" formtoken=\"".createFormKey('movefolder')."\">";
$content .= "<td><a _rel=\"folder_".$subFolder->getID()."\" draggable=\"false\" href=\"../out/out.ViewFolder.php?folderid=".$subFolder->getID()."&showtree=".$showtree."\"><img draggable=\"false\" src=\"".$this->imgpath."folder.svg\" width=\"24\" height=\"24\" border=0></a></td>\n"; $content .= "<td><a _rel=\"folder_".$subFolder->getID()."\" draggable=\"false\" href=\"../out/out.ViewFolder.php?folderid=".$subFolder->getID()."&showtree=".$showtree."\"><img draggable=\"false\" src=\"".$this->getMimeIcon(".folder")."\" width=\"24\" height=\"24\" border=0></a></td>\n";
$content .= "<td><a draggable=\"false\" _rel=\"folder_".$subFolder->getID()."\" href=\"../out/out.ViewFolder.php?folderid=".$subFolder->getID()."&showtree=".$showtree."\">" . htmlspecialchars($subFolder->getName()) . "</a>"; $content .= "<td><a draggable=\"false\" _rel=\"folder_".$subFolder->getID()."\" href=\"../out/out.ViewFolder.php?folderid=".$subFolder->getID()."&showtree=".$showtree."\">" . htmlspecialchars($subFolder->getName()) . "</a>";
$content .= "<br /><span style=\"font-size: 85%; font-style: italic; color: #666;\">".getMLText('owner').": <b>".htmlspecialchars($owner->getFullName())."</b>, ".getMLText('creation_date').": <b>".date('Y-m-d', $subFolder->getDate())."</b></span>"; $content .= "<br /><span style=\"font-size: 85%; font-style: italic; color: #666;\">".getMLText('owner').": <b>".htmlspecialchars($owner->getFullName())."</b>, ".getMLText('creation_date').": <b>".date('Y-m-d', $subFolder->getDate())."</b></span>";
if($comment) { if($comment) {

View File

@ -91,6 +91,79 @@ class SeedDMS_View_Clipboard extends SeedDMS_Bootstrap_Style {
echo $content; 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 .= "<tr draggable=\"true\" rel=\"folder_".$folder->getID()."\" class=\"folder table-row-folder\" formtoken=\"".createFormKey('movefolder')."\">";
$content .= "<td><a draggable=\"false\" href=\"out.ViewFolder.php?folderid=".$folder->getID()."&showtree=".showtree()."\"><img draggable=\"false\" src=\"".$this->getMimeIcon(".folder")."\" width=\"24\" height=\"24\" border=0></a></td>\n";
$content .= "<td><a draggable=\"false\" href=\"out.ViewFolder.php?folderid=".$folder->getID()."&showtree=".showtree()."\">" . htmlspecialchars($folder->getName()) . "</a>";
if($comment) {
$content .= "<br /><span style=\"font-size: 85%;\">".htmlspecialchars($comment)."</span>";
}
$content .= "</td>\n";
$content .= "<td>\n";
$content .= "<div class=\"list-action\"><a class=\"removefromclipboard\" rel=\"F".$folder->getID()."\" msg=\"".getMLText('splash_removed_from_clipboard')."\" title=\"".getMLText('rm_from_clipboard')."\"><i class=\"icon-remove\"></i></a></div>";
$content .= "</td>\n";
$content .= "</tr>\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 .= "<tr draggable=\"true\" rel=\"document_".$document->getID()."\" class=\"table-row-document\" formtoken=\"".createFormKey('movedocument')."\">";
if (file_exists($dms->contentDir . $latestContent->getPath())) {
$content .= "<td><a draggable=\"false\" href=\"../op/op.Download.php?documentid=".$document->getID()."&version=".$version."\">";
if($previewer->hasPreview($latestContent)) {
$content .= "<img draggable=\"false\" class=\"mimeicon\" width=\"40\"src=\"../op/op.Preview.php?documentid=".$document->getID()."&version=".$latestContent->getVersion()."&width=40\" title=\"".htmlspecialchars($latestContent->getMimeType())."\">";
} else {
$content .= "<img draggable=\"false\" class=\"mimeicon\" src=\"".$this->getMimeIcon($latestContent->getFileType())."\" title=\"".htmlspecialchars($latestContent->getMimeType())."\">";
}
$content .= "</a></td>";
} else
$content .= "<td><img draggable=\"false\" class=\"mimeicon\" src=\"".$this->getMimeIcon($latestContent->getFileType())."\" title=\"".htmlspecialchars($latestContent->getMimeType())."\"></td>";
$content .= "<td><a draggable=\"false\" href=\"out.ViewDocument.php?documentid=".$document->getID()."&showtree=".showtree()."\">" . htmlspecialchars($document->getName()) . "</a>";
if($comment) {
$content .= "<br /><span style=\"font-size: 85%;\">".htmlspecialchars($comment)."</span>";
}
$content .= "</td>\n";
$content .= "<td>\n";
$content .= "<div class=\"list-action\"><a class=\"removefromclipboard\" rel=\"D".$document->getID()."\" msg=\"".getMLText('splash_removed_from_clipboard')."\" _href=\"../op/op.RemoveFromClipboard.php?folderid=".(isset($this->params['folder']) ? $this->params['folder']->getID() : '')."&id=".$document->getID()."&type=document\" title=\"".getMLText('rm_from_clipboard')."\"><i class=\"icon-remove\"></i></a></div>";
$content .= "</td>\n";
$content .= "</tr>";
}
return $content;
} /* }}} */
/** /**
* Return clipboard content rendered as html * Return clipboard content rendered as html
* *
@ -112,19 +185,13 @@ class SeedDMS_View_Clipboard extends SeedDMS_Bootstrap_Style {
foreach($clipboard['folders'] as $folderid) { foreach($clipboard['folders'] as $folderid) {
/* FIXME: check for access rights, which could have changed after adding the folder to the clipboard */ /* FIXME: check for access rights, which could have changed after adding the folder to the clipboard */
if($folder = $dms->getFolder($folderid)) { if($folder = $dms->getFolder($folderid)) {
$comment = $folder->getComment(); $txt = $this->callHook('folderClipboardItem', $folder, 'clipboard');
if (strlen($comment) > 150) $comment = substr($comment, 0, 147) . "..."; if(is_string($txt))
$content .= "<tr draggable=\"true\" rel=\"folder_".$folder->getID()."\" class=\"folder table-row-folder\" formtoken=\"".createFormKey('movefolder')."\">"; $content .= $txt;
$content .= "<td><a draggable=\"false\" href=\"out.ViewFolder.php?folderid=".$folder->getID()."&showtree=".showtree()."\"><img draggable=\"false\" src=\"".$this->imgpath."folder.png\" width=\"24\" height=\"24\" border=0></a></td>\n"; else {
$content .= "<td><a draggable=\"false\" href=\"out.ViewFolder.php?folderid=".$folder->getID()."&showtree=".showtree()."\">" . htmlspecialchars($folder->getName()) . "</a>"; $content .= $this->folderClipboardRow($folder);
if($comment) {
$content .= "<br /><span style=\"font-size: 85%;\">".htmlspecialchars($comment)."</span>";
} }
$content .= "</td>\n";
$content .= "<td>\n";
$content .= "<div class=\"list-action\"><a class=\"removefromclipboard\" rel=\"F".$folderid."\" msg=\"".getMLText('splash_removed_from_clipboard')."\" _href=\"../op/op.RemoveFromClipboard.php?folderid=".(isset($this->params['folder']) ? $this->params['folder']->getID() : '')."&id=".$folderid."&type=folder\" title=\"".getMLText('rm_from_clipboard')."\"><i class=\"icon-remove\"></i></a></div>";
$content .= "</td>\n";
$content .= "</tr>\n";
$foldercount++; $foldercount++;
} }
} }
@ -133,40 +200,15 @@ class SeedDMS_View_Clipboard extends SeedDMS_Bootstrap_Style {
foreach($clipboard['docs'] as $docid) { foreach($clipboard['docs'] as $docid) {
/* FIXME: check for access rights, which could have changed after adding the document to the clipboard */ /* FIXME: check for access rights, which could have changed after adding the document to the clipboard */
if($document = $dms->getDocument($docid)) { if($document = $dms->getDocument($docid)) {
$comment = $document->getComment(); $document->verifyLastestContentExpriry();
if (strlen($comment) > 150) $comment = substr($comment, 0, 147) . "..."; $txt = $this->callHook('documentClipboardItem', $document, $previewer, 'clipboard');
$latestContent = $this->callHook('documentLatestContent', $document); if(is_string($txt))
if($latestContent === null) $content .= $txt;
$latestContent = $document->getLatestContent(); else {
if($latestContent) { $content .= $this->documentClipboardRow($document, $previewer);
$previewer->createPreview($latestContent);
$version = $latestContent->getVersion();
$status = $latestContent->getStatus();
$content .= "<tr draggable=\"true\" rel=\"document_".$docid."\" class=\"table-row-document\" formtoken=\"".createFormKey('movedocument')."\">";
if (file_exists($dms->contentDir . $latestContent->getPath())) {
$content .= "<td><a draggable=\"false\" href=\"../op/op.Download.php?documentid=".$docid."&version=".$version."\">";
if($previewer->hasPreview($latestContent)) {
$content .= "<img draggable=\"false\" class=\"mimeicon\" width=\"40\"src=\"../op/op.Preview.php?documentid=".$document->getID()."&version=".$latestContent->getVersion()."&width=40\" title=\"".htmlspecialchars($latestContent->getMimeType())."\">";
} else {
$content .= "<img draggable=\"false\" class=\"mimeicon\" src=\"".$this->getMimeIcon($latestContent->getFileType())."\" title=\"".htmlspecialchars($latestContent->getMimeType())."\">";
}
$content .= "</a></td>";
} else
$content .= "<td><img draggable=\"false\" class=\"mimeicon\" src=\"".$this->getMimeIcon($latestContent->getFileType())."\" title=\"".htmlspecialchars($latestContent->getMimeType())."\"></td>";
$content .= "<td><a draggable=\"false\" href=\"out.ViewDocument.php?documentid=".$docid."&showtree=".showtree()."\">" . htmlspecialchars($document->getName()) . "</a>";
if($comment) {
$content .= "<br /><span style=\"font-size: 85%;\">".htmlspecialchars($comment)."</span>";
}
$content .= "</td>\n";
$content .= "<td>\n";
$content .= "<div class=\"list-action\"><a class=\"removefromclipboard\" rel=\"D".$docid."\" msg=\"".getMLText('splash_removed_from_clipboard')."\" _href=\"../op/op.RemoveFromClipboard.php?folderid=".(isset($this->params['folder']) ? $this->params['folder']->getID() : '')."&id=".$docid."&type=document\" title=\"".getMLText('rm_from_clipboard')."\"><i class=\"icon-remove\"></i></a></div>";
$content .= "</td>\n";
$content .= "</tr>";
$doccount++;
} }
$doccount++;
} }
} }
} }

View File

@ -40,7 +40,7 @@ class SeedDMS_View_ErrorDlg extends SeedDMS_Bootstrap_Style {
$settings = $this->params['settings']; $settings = $this->params['settings'];
if(!$plain) { if(!$plain) {
$this->htmlStartPage($pagetitle, 'errorpage', $settings->_httpRoot."out"); $this->htmlStartPage($pagetitle, 'errorpage', $settings->_httpRoot."out/");
$this->globalNavigation(); $this->globalNavigation();
$this->contentStart(); $this->contentStart();
} }