diff --git a/CHANGELOG b/CHANGELOG index 15c02f48c..ca1a4d85d 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,10 +1,17 @@ -------------------------------------------------------------------------------- Changes in version 4.2.0 -------------------------------------------------------------------------------- +- sqlite3 database can be updated +- use awesome font for icons +- currently logged in user can be changed temporarily if being admin - count documents/folders recursively for output in folder list (Bug #43) - remove multiple log files at once (Bug #35) - return to same tab on LogManagement page as before removing a log file (Bug #30) +- new bootstrap datepicker with localization (Bug #36) +- users can be assigned to a group when edited or added (Bug #39) +- place a message on ViewDocument page if the document needs an action + in the workflow (Bug #4) -------------------------------------------------------------------------------- Changes in version 4.1.3 @@ -13,6 +20,7 @@ - fixed typo in variable name which cause a PHP warning when sending the notification mail after updating a folder comment - fixed code to determine required approver and reviewer +- fixed wrong language setting in installer (Bug #45) -------------------------------------------------------------------------------- Changes in version 4.1.2 diff --git a/Makefile b/Makefile index a6948766a..cee6fb096 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -VERSION=4.1.3 +VERSION=4.2.0 SRC=CHANGELOG inc conf utils index.php languages views op out README.md README.Notification README.Ubuntu drop-tables-innodb.sql styles js TODO LICENSE Makefile webdav install #restapi webapp diff --git a/SeedDMS_Core/Core/inc.ClassDMS.php b/SeedDMS_Core/Core/inc.ClassDMS.php index dee5164a4..5a8c8abf0 100644 --- a/SeedDMS_Core/Core/inc.ClassDMS.php +++ b/SeedDMS_Core/Core/inc.ClassDMS.php @@ -205,6 +205,24 @@ class SeedDMS_Core_DMS { return $newArr; } /* }}} */ + /** + * Filter document links + * + * Returns a filtered list of links which are accessible by the + * given user. + * + * @param array $links list of objects of type SeedDMS_Core_DocumentLink + * @param object $user user for which access is being checked + * @return filtered list of links + */ + static function filterDocumentLinks($user, $links) { /* {{{ */ + $tmp = array(); + foreach ($links as $link) + if ($link->isPublic() || ($link->getUser()->getID() == $user->getID()) || $user->isAdmin()) + array_push($tmp, $link); + return $tmp; + } /* }}} */ + /** * Create a new instance of the dms * @@ -225,7 +243,7 @@ class SeedDMS_Core_DMS { $this->convertFileTypes = array(); $this->version = '@package_version@'; if($this->version[0] == '@') - $this->version = '4.1.3'; + $this->version = '4.2.0'; } /* }}} */ function getDB() { /* {{{ */ diff --git a/SeedDMS_Core/Core/inc.ClassDocument.php b/SeedDMS_Core/Core/inc.ClassDocument.php index 595ecbd61..65d36b083 100644 --- a/SeedDMS_Core/Core/inc.ClassDocument.php +++ b/SeedDMS_Core/Core/inc.ClassDocument.php @@ -1409,6 +1409,13 @@ class SeedDMS_Core_Document extends SeedDMS_Core_Object { /* {{{ */ return true; } /* }}} */ + /** + * Return a certain document link + * + * @param integer $linkID id of link + * @return object instance of SeedDMS_Core_DocumentLink or false in case of + * an error. + */ function getDocumentLink($linkID) { /* {{{ */ $db = $this->_dms->getDB(); @@ -1425,6 +1432,15 @@ class SeedDMS_Core_Document extends SeedDMS_Core_Object { /* {{{ */ return new SeedDMS_Core_DocumentLink($resArr["id"], $document, $target, $resArr["userID"], $resArr["public"]); } /* }}} */ + /** + * Return all document links + * + * The list contains all links to other documents, even those which + * may not be visible certain users. The application should call + * SeedDMS_Core_DMS::filterDocumentLinks() afterwards. + * + * @return array list of objects of class SeedDMS_Core_DocumentLink + */ function getDocumentLinks() { /* {{{ */ if (!isset($this->_documentLinks)) { $db = $this->_dms->getDB(); @@ -3594,6 +3610,31 @@ class SeedDMS_Core_DocumentContent extends SeedDMS_Core_Object { /* {{{ */ return $workflowlog; } /* }}} */ + /** + * Check if the document content needs an action by a user + * + * This method will return true if document content is in a transition + * which can be triggered by the given user. + * + * @param SeedDMS_Core_User $user + * @return boolean true is action is needed + */ + function needsWorkflowAction($user) { /* {{{ */ + $needwkflaction = false; + if($this->_workflow) { + if (!$this->_workflowState) + $this->getWorkflowState(); + $workflowstate = $this->_workflowState; + $transitions = $this->_workflow->getNextTransitions($workflowstate); + foreach($transitions as $transition) { + if($this->triggerWorkflowTransitionIsAllowed($user, $transition)) { + $needwkflaction = true; + } + } + } + return $needwkflaction; + } /* }}} */ + } /* }}} */ diff --git a/SeedDMS_Core/Core/inc.ClassFolder.php b/SeedDMS_Core/Core/inc.ClassFolder.php index 5420e9458..10cf65a3d 100644 --- a/SeedDMS_Core/Core/inc.ClassFolder.php +++ b/SeedDMS_Core/Core/inc.ClassFolder.php @@ -555,6 +555,94 @@ class SeedDMS_Core_Folder extends SeedDMS_Core_Object { return $this->_documents; } /* }}} */ + /** + * Count all documents and subfolders of the folder + * + * This function also counts documents and folders of subfolders, so + * basically it works like recursively counting children. + * + * This function checks for access rights up the given limit. If more + * documents or folders are found, the returned value will be the number + * of objects available and the precise flag in the return array will be + * set to false. This number should not be revelead to the + * user, because it allows to gain information about the existens of + * objects without access right. + * Setting the parameter $limit to 0 will turn off access right checking + * which is reasonable if the $user is an administrator. + * + * @param string $orderby if set to 'n' the list is ordered by name, otherwise + * it will be ordered by sequence + * @param integer $limit maximum number of folders and documents that will + * be precisly counted by taken the access rights into account + * @return array array with four elements 'document_count', 'folder_count' + * 'document_precise', 'folder_precise' holding + * the counted number and a flag if the number is precise. + */ + function countChildren($user, $limit=10000) { /* {{{ */ + $db = $this->_dms->getDB(); + + $pathPrefix=""; + $path = $this->getPath(); + foreach ($path as $f) { + $pathPrefix .= ":".$f->getID(); + } + if (strlen($pathPrefix)>1) { + $pathPrefix .= ":"; + } + + $queryStr = "SELECT id FROM tblFolders WHERE folderList like '".$pathPrefix. "%'"; + $resArr = $db->getResultArray($queryStr); + if (is_bool($resArr) && !$resArr) + return false; + + $result = array(); + + $folders = array(); + $folderids = array($this->_id); + $cfolders = count($resArr); + if($cfolders < $limit) { + foreach ($resArr as $row) { + $folder = $this->_dms->getFolder($row["id"]); + if ($folder->getAccessMode($user) >= M_READ) { + array_push($folders, $folder); + array_push($folderids, $row['id']); + } + } + $result['folder_count'] = count($folders); + $result['folder_precise'] = true; + } else { + foreach ($resArr as $row) { + array_push($folderids, $row['id']); + } + $result['folder_count'] = $cfolders; + $result['folder_precise'] = false; + } + + $documents = array(); + if($folderids) { + $queryStr = "SELECT id FROM tblDocuments WHERE folder in (".implode(',', $folderids). ")"; + $resArr = $db->getResultArray($queryStr); + if (is_bool($resArr) && !$resArr) + return false; + + $cdocs = count($resArr); + if($cdocs < $limit) { + foreach ($resArr as $row) { + $document = $this->_dms->getDocument($row["id"]); + if ($document->getAccessMode($user) >= M_READ) + array_push($documents, $document); + } + $result['document_count'] = count($documents); + $result['document_precise'] = true; + } else { + $result['document_count'] = $cdocs; + $result['document_precise'] = false; + } + } + + return $result; + } /* }}} */ + // $comment will be used for both document and version leaving empty the version_comment /** * Add a new document to the folder diff --git a/SeedDMS_Core/package.xml b/SeedDMS_Core/package.xml index 93bf65580..818489229 100644 --- a/SeedDMS_Core/package.xml +++ b/SeedDMS_Core/package.xml @@ -12,11 +12,11 @@ uwe@steinmann.cx yes - 2013-04-08 - + 2013-04-22 + - 4.1.3 - 4.1.0 + 4.2.0 + 4.2.0 stable @@ -24,7 +24,7 @@ GPL License -- stay in sync with seeddms application +- added method SeedDMS_Core_DMS::filterDocumentLinks() @@ -481,5 +481,21 @@ New release - set propper folderList of sub folders after moving a folder + + 2013-04-08 + + + 4.1.3 + 4.1.0 + + + stable + stable + + GPL License + +- stay in sync with seeddms application + + diff --git a/conf/settings.xml.template b/conf/settings.xml.template index 383e93637..480478255 100644 --- a/conf/settings.xml.template +++ b/conf/settings.xml.template @@ -12,7 +12,7 @@ footNote = "SeedDMS free document management system - www.seeddms.org" printDisclaimer="true" language = "en_GB" - theme = "clean" + theme = "bootstrap" >
diff --git a/views/bootstrap/class.DocumentAccess.php b/views/bootstrap/class.DocumentAccess.php index a75a4679d..66e932b5e 100644 --- a/views/bootstrap/class.DocumentAccess.php +++ b/views/bootstrap/class.DocumentAccess.php @@ -99,7 +99,7 @@ function checkForm() } ?> - +
getId();?>"> printAccessModeSelection($document->getDefaultAccess()); ?> - + getId()."\">\n"; print "\n"; print "getID()."\">\n"; - print ""; + print ""; print "\n"; print "\n"; print "
\n"; @@ -208,7 +208,7 @@ function checkForm() print "getId()."\">"; print ""; print "getID()."\">"; - print ""; + print ""; print "\n"; print "
"; print "
\n"; diff --git a/views/bootstrap/class.EditAttributes.php b/views/bootstrap/class.EditAttributes.php index e5c92adbf..1e06f8485 100644 --- a/views/bootstrap/class.EditAttributes.php +++ b/views/bootstrap/class.EditAttributes.php @@ -65,7 +65,7 @@ class SeedDMS_View_EditAttributes extends SeedDMS_Bootstrap_Style { } ?> - "> +
diff --git a/views/bootstrap/class.EditComment.php b/views/bootstrap/class.EditComment.php index 41ba901b3..1ce1f65c2 100644 --- a/views/bootstrap/class.EditComment.php +++ b/views/bootstrap/class.EditComment.php @@ -80,7 +80,7 @@ function checkForm() - "> + diff --git a/views/bootstrap/class.EditDocument.php b/views/bootstrap/class.EditDocument.php index e6c944453..aaec2b129 100644 --- a/views/bootstrap/class.EditDocument.php +++ b/views/bootstrap/class.EditDocument.php @@ -128,7 +128,7 @@ function checkForm() ?> - "> + diff --git a/views/bootstrap/class.EditEvent.php b/views/bootstrap/class.EditEvent.php index aa06d49b8..f8c3ebe1c 100644 --- a/views/bootstrap/class.EditEvent.php +++ b/views/bootstrap/class.EditEvent.php @@ -101,7 +101,7 @@ function checkForm() - "> + diff --git a/views/bootstrap/class.EditFolder.php b/views/bootstrap/class.EditFolder.php index e1dc4e379..1dd9c4ba1 100644 --- a/views/bootstrap/class.EditFolder.php +++ b/views/bootstrap/class.EditFolder.php @@ -106,7 +106,7 @@ function checkForm() ?> - "> + diff --git a/views/bootstrap/class.EditUserData.php b/views/bootstrap/class.EditUserData.php index 033034780..83e550772 100644 --- a/views/bootstrap/class.EditUserData.php +++ b/views/bootstrap/class.EditUserData.php @@ -154,7 +154,7 @@ function checkForm() - "> + diff --git a/views/bootstrap/class.FolderAccess.php b/views/bootstrap/class.FolderAccess.php index 05ecdf8d2..86b31acf4 100644 --- a/views/bootstrap/class.FolderAccess.php +++ b/views/bootstrap/class.FolderAccess.php @@ -95,7 +95,7 @@ function checkForm() } ?> - + getID();?>"> printAccessModeSelection($folder->getDefaultAccess()); ?> - + printAccessModeSelection($userAccess->getMode()); print "\n"; print "\n"; - print ""; + print ""; print "\n"; print "\n"; print "
\n"; @@ -202,7 +202,7 @@ function checkForm() $this->printAccessModeSelection($groupAccess->getMode()); print "\n"; print "\n"; - print ""; + print ""; print "\n"; print "
"; print "
\n"; diff --git a/views/bootstrap/class.GroupMgr.php b/views/bootstrap/class.GroupMgr.php index bdaa5b3ab..d12a7defe 100644 --- a/views/bootstrap/class.GroupMgr.php +++ b/views/bootstrap/class.GroupMgr.php @@ -170,7 +170,7 @@ function showUser(selectObj) { - "> +
diff --git a/views/bootstrap/class.LogManagement.php b/views/bootstrap/class.LogManagement.php index 2403704ac..440722ed8 100644 --- a/views/bootstrap/class.LogManagement.php +++ b/views/bootstrap/class.LogManagement.php @@ -31,13 +31,15 @@ require_once("class.Bootstrap.php"); */ class SeedDMS_View_LogManagement extends SeedDMS_Bootstrap_Style { - function filelist($entries) { /* {{{ */ + function filelist($entries, $mode) { /* {{{ */ $print_header = true; foreach ($entries as $entry){ if ($print_header){ + print "
\n"; print "\n"; print "\n\n"; + print "\n"; print "\n"; print "\n"; print "\n"; @@ -47,13 +49,14 @@ class SeedDMS_View_LogManagement extends SeedDMS_Bootstrap_Style { } print "\n"; + print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "
".getMLText("name")."".getMLText("creation_date")."".getMLText("file_size")."
".$entry."".getLongReadableDate(filectime($this->contentdir.$entry))."".SeedDMS_Core_File::format_filesize(filesize($this->contentdir.$entry)).""; - print " ".getMLText("rm_file").""; + print " ".getMLText("rm_file").""; print " "; print " ".getMLText("download").""; print " "; @@ -63,7 +66,7 @@ class SeedDMS_View_LogManagement extends SeedDMS_Bootstrap_Style { } if ($print_header) printMLText("empty_notify_list"); - else print "
\n"; + else print "
\n"; } /* }}} */ function show() { /* {{{ */ @@ -71,6 +74,7 @@ class SeedDMS_View_LogManagement extends SeedDMS_Bootstrap_Style { $user = $this->params['user']; $this->contentdir = $this->params['contentdir']; $logname = $this->params['logname']; + $mode = $this->params['mode']; if(!$logname) { $this->htmlStartPage(getMLText("log_management")); @@ -103,21 +107,21 @@ class SeedDMS_View_LogManagement extends SeedDMS_Bootstrap_Style { } ?>
-
+
contentContainerStart(); - $this->filelist($entries); + $this->filelist($entries, 'web'); $this->contentContainerEnd(); ?>
-
+
contentContainerStart(); - $this->filelist($wentries); + $this->filelist($wentries, 'webdav'); $this->contentContainerEnd(); ?>
diff --git a/views/bootstrap/class.RemoveLog.php b/views/bootstrap/class.RemoveLog.php index 3b5c74977..c4ad70f42 100644 --- a/views/bootstrap/class.RemoveLog.php +++ b/views/bootstrap/class.RemoveLog.php @@ -34,7 +34,8 @@ class SeedDMS_View_RemoveLog extends SeedDMS_Bootstrap_Style { function show() { /* {{{ */ $dms = $this->params['dms']; $user = $this->params['user']; - $logname = $this->params['logname']; + $lognames = $this->params['lognames']; + $mode = $this->params['mode']; $this->htmlStartPage(getMLText("backup_tools")); $this->globalNavigation(); @@ -45,8 +46,14 @@ class SeedDMS_View_RemoveLog extends SeedDMS_Bootstrap_Style { ?>
- -

$logname));?>

+ +\n"; + + } +?> +

implode(', ', $lognames)));?>


- +   - + @@ -190,12 +190,12 @@ function chooseKeywords(target) { - +   - + diff --git a/views/bootstrap/class.SetExpires.php b/views/bootstrap/class.SetExpires.php index a7efecd8f..4d98bed6b 100644 --- a/views/bootstrap/class.SetExpires.php +++ b/views/bootstrap/class.SetExpires.php @@ -57,7 +57,7 @@ class SeedDMS_View_SetExpires extends SeedDMS_Bootstrap_Style { : - +   @@ -68,7 +68,7 @@ class SeedDMS_View_SetExpires extends SeedDMS_Bootstrap_Style { - "> + diff --git a/views/bootstrap/class.Settings.php b/views/bootstrap/class.Settings.php index 90c347407..5ddb82a9b 100644 --- a/views/bootstrap/class.Settings.php +++ b/views/bootstrap/class.Settings.php @@ -160,6 +160,14 @@ if(!is_writeable($settings->_configFilePath)) { + "> + : + _enableRecursiveCount) echo "checked" ?> /> + + "> + : + + "> : _enableLanguageSelector) echo "checked" ?> /> @@ -512,7 +520,7 @@ if(!is_writeable($settings->_configFilePath)) { _configFilePath)) { ?> - " /> + diff --git a/views/bootstrap/class.SubstituteUser.php b/views/bootstrap/class.SubstituteUser.php new file mode 100644 index 000000000..b94cbfedb --- /dev/null +++ b/views/bootstrap/class.SubstituteUser.php @@ -0,0 +1,83 @@ + + * @copyright Copyright (C) 2002-2005 Markus Westphal, + * 2006-2008 Malcolm Cowe, 2010 Matteo Lucarelli, + * 2010-2012 Uwe Steinmann + * @version Release: @package_version@ + */ + +/** + * Include parent class + */ +require_once("class.Bootstrap.php"); + +/** + * Class which outputs the html page for SubstituteUser view + * + * @category DMS + * @package SeedDMS + * @author Markus Westphal, Malcolm Cowe, Uwe Steinmann + * @copyright Copyright (C) 2002-2005 Markus Westphal, + * 2006-2008 Malcolm Cowe, 2010 Matteo Lucarelli, + * 2010-2012 Uwe Steinmann + * @version Release: @package_version@ + */ +class SeedDMS_View_SubstituteUser extends SeedDMS_Bootstrap_Style { + + function show() { /* {{{ */ + $dms = $this->params['dms']; + $user = $this->params['user']; + $allUsers = $this->params['allusers']; + + $this->htmlStartPage(getMLText("substitute_user")); + $this->globalNavigation(); + $this->contentStart(); + $this->pageNavigation(getMLText("admin_tools"), "admin_tools"); + + $this->contentHeading(getMLText("substitute_user")); + $this->contentContainerStart(); +?> + + +"; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + } + echo "
"; + echo $currUser->getFullName()." (".$currUser->getLogin().")
"; + echo "".$currUser->getComment().""; + echo "
"; + echo "getEmail()."\">".$currUser->getEmail()."
"; + echo "
"; + $groups = $currUser->getGroups(); + if (count($groups) != 0) { + for ($j = 0; $j < count($groups); $j++) { + print $groups[$j]->getName(); + if ($j +1 < count($groups)) + print ", "; + } + } + echo ""; + if($currUser->getID() != $user->getID()) { + echo "getID()."\"> ".getMLText('substitute_user')." "; + } + echo "
"; + $this->contentContainerEnd(); + + $this->htmlEndPage(); + } /* }}} */ +} +?> + diff --git a/views/bootstrap/class.UpdateDocument.php b/views/bootstrap/class.UpdateDocument.php index 4dc683c96..9ecb1906f 100644 --- a/views/bootstrap/class.UpdateDocument.php +++ b/views/bootstrap/class.UpdateDocument.php @@ -142,7 +142,7 @@ function checkForm() : - +   diff --git a/views/bootstrap/class.UserDefaultKeywords.php b/views/bootstrap/class.UserDefaultKeywords.php index a1d6433e2..e4a512953 100644 --- a/views/bootstrap/class.UserDefaultKeywords.php +++ b/views/bootstrap/class.UserDefaultKeywords.php @@ -120,7 +120,7 @@ function showKeywords(selectObj) { - "> + diff --git a/views/bootstrap/class.UsrMgr.php b/views/bootstrap/class.UsrMgr.php index d56605523..236f1b589 100644 --- a/views/bootstrap/class.UsrMgr.php +++ b/views/bootstrap/class.UsrMgr.php @@ -169,6 +169,16 @@ function showUser(selectObj) { : + + : + + : @@ -198,7 +208,7 @@ function showUser(selectObj) {
:
- : + + : + + : isHidden() ? " checked='checked'" : "");?>> @@ -423,7 +443,7 @@ function showUser(selectObj) {
:
- :
- getMandatoryApprovers(); foreach ($users as $usr) { @@ -466,7 +486,7 @@ function showUser(selectObj) {
:
- - "> + diff --git a/views/bootstrap/class.ViewDocument.php b/views/bootstrap/class.ViewDocument.php index 33ad75eaa..a9dee42e6 100644 --- a/views/bootstrap/class.ViewDocument.php +++ b/views/bootstrap/class.ViewDocument.php @@ -103,8 +103,24 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { /* Retrieve linked documents */ $links = $document->getDocumentLinks(); - $links = filterDocumentLinks($user, $links); + $links = SeedDMS_Core_DMS::filterDocumentLinks($user, $links); + /* Retrieve latest content */ + $latestContent = $document->getLatestContent(); + $needwkflaction = false; + if($workflowmode == 'traditional') { + } else { + $workflow = $latestContent->getWorkflow(); + if($workflow) { + $workflowstate = $latestContent->getWorkflowState(); + $transitions = $workflow->getNextTransitions($workflowstate); + $needwkflaction = $latestContent->needsWorkflowAction($user); + } + } + + if($needwkflaction) { + $this->infoMsg(getMLText('needs_workflow_action')); + } ?>