Merge branch 'seeddms-4.3.2' into develop

Conflicts:
	Makefile
This commit is contained in:
Uwe Steinmann 2013-11-27 14:10:05 +01:00
commit 39f19f25bb
15 changed files with 249 additions and 22 deletions

View File

@ -1,3 +1,15 @@
--------------------------------------------------------------------------------
Changes in version 4.3.2
--------------------------------------------------------------------------------
- fix approval of documents by group if owner of document is member of group
- make jumploader work with java 1.7
- turning of the language selector will no longer turn off user substitution
- use PATH_SEPARATOR and DIRECTORY_SEPARATOR when checking the include path
for files
- check if target folder is a child of the current folder when moving folders
- fix missing documents in tree of document choser (Bug #105)
- add another folder/document check
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
Changes in version 4.3.1 Changes in version 4.3.1
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------

View File

@ -1,4 +1,4 @@
VERSION=4.3.1 VERSION=4.3.2
SRC=CHANGELOG inc conf utils index.php languages views op out controllers README.md README.Notification README.Ubuntu drop-tables-innodb.sql styles js TODO LICENSE Makefile webdav install SRC=CHANGELOG inc conf utils index.php languages views op out controllers README.md README.Notification README.Ubuntu drop-tables-innodb.sql styles js TODO LICENSE Makefile webdav install
#restapi webapp #restapi webapp

View File

@ -216,6 +216,12 @@ full text search engine support, you will also need to unpack
> Server > Server
> Server.php > Server.php
If you run PHP in CGI mode, you also need to place a .htaccess file
in the webdav directory with the following content.
RewriteEngine on
RewriteRule .* - [env=HTTP_AUTHORIZATION:%{HTTP:Authorization},last]
* Create a data folder somewhere on your web server including the subdirectories * Create a data folder somewhere on your web server including the subdirectories
staging, cache and lucene and make sure they are writable by your web server, staging, cache and lucene and make sure they are writable by your web server,
but not accessible through the web. but not accessible through the web.

View File

@ -243,7 +243,7 @@ class SeedDMS_Core_DMS {
$this->convertFileTypes = array(); $this->convertFileTypes = array();
$this->version = '@package_version@'; $this->version = '@package_version@';
if($this->version[0] == '@') if($this->version[0] == '@')
$this->version = '4.3.1'; $this->version = '4.3.2';
} /* }}} */ } /* }}} */
function getDB() { /* {{{ */ function getDB() { /* {{{ */
@ -493,7 +493,7 @@ class SeedDMS_Core_DMS {
return $version; return $version;
} /* }}} */ } /* }}} */
function makeTimeStamp($hour, $min, $sec, $year, $month, $day) { function makeTimeStamp($hour, $min, $sec, $year, $month, $day) { /* {{{ */
$thirtyone = array (1, 3, 5, 7, 8, 10, 12); $thirtyone = array (1, 3, 5, 7, 8, 10, 12);
$thirty = array (4, 6, 9, 11); $thirty = array (4, 6, 9, 11);
@ -524,7 +524,7 @@ class SeedDMS_Core_DMS {
} }
return mktime($hour, $min, $sec, $month, $day, $year); return mktime($hour, $min, $sec, $month, $day, $year);
} } /* }}} */
/* /*
* Search the database for documents * Search the database for documents
@ -999,6 +999,85 @@ class SeedDMS_Core_DMS {
return $folder; return $folder;
} /* }}} */ } /* }}} */
/**
* Returns a list of folders and error message not linked in the tree
*
* This function checks all folders in the database.
*
* @return array list of errors
*/
function checkFolders() { /* {{{ */
$queryStr = "SELECT * FROM tblFolders";
$resArr = $this->db->getResultArray($queryStr);
if (is_bool($resArr) && $resArr === false)
return false;
$cache = array();
foreach($resArr as $rec) {
$cache[$rec['id']] = array('name'=>$rec['name'], 'parent'=>$rec['parent'], 'folderList'=>$rec['folderList']);
}
$errors = array();
foreach($cache as $id=>$rec) {
if(!array_key_exists($rec['parent'], $cache) && $rec['parent'] != 0) {
$errors[$id] = array('id'=>$id, 'name'=>$rec['name'], 'parent'=>$rec['parent'], 'msg'=>'Missing parent');
} else {
$tmparr = explode(':', $rec['folderList']);
array_shift($tmparr);
if(count($tmparr) != count(array_unique($tmparr))) {
$errors[$id] = array('id'=>$id, 'name'=>$rec['name'], 'parent'=>$rec['parent'], 'msg'=>'Duplicate entry in folder list ('.$rec['folderList'].')');
}
}
}
return $errors;
} /* }}} */
/**
* Returns a list of documents and error message not linked in the tree
*
* This function checks all documents in the database.
*
* @return array list of errors
*/
function checkDocuments() { /* {{{ */
$queryStr = "SELECT * FROM tblFolders";
$resArr = $this->db->getResultArray($queryStr);
if (is_bool($resArr) && $resArr === false)
return false;
$fcache = array();
foreach($resArr as $rec) {
$fcache[$rec['id']] = array('name'=>$rec['name'], 'parent'=>$rec['parent'], 'folderList'=>$rec['folderList']);
}
$queryStr = "SELECT * FROM tblDocuments";
$resArr = $this->db->getResultArray($queryStr);
if (is_bool($resArr) && $resArr === false)
return false;
$dcache = array();
foreach($resArr as $rec) {
$dcache[$rec['id']] = array('name'=>$rec['name'], 'parent'=>$rec['folder'], 'folderList'=>$rec['folderList']);
}
$errors = array();
foreach($dcache as $id=>$rec) {
if(!array_key_exists($rec['parent'], $fcache) && $rec['parent'] != 0) {
$errors[$id] = array('id'=>$id, 'name'=>$rec['name'], 'parent'=>$rec['parent'], 'msg'=>'Missing parent');
} else {
$tmparr = explode(':', $rec['folderList']);
array_shift($tmparr);
if(count($tmparr) != count(array_unique($tmparr))) {
$errors[$id] = array('id'=>$id, 'name'=>$rec['name'], 'parent'=>$rec['parent'], 'msg'=>'Duplicate entry in folder list ('.$rec['folderList'].'');
}
}
}
return $errors;
} /* }}} */
/** /**
* Return a user by its id * Return a user by its id
* *

View File

@ -149,13 +149,37 @@ class SeedDMS_Core_Folder extends SeedDMS_Core_Object {
return $this->_parent; return $this->_parent;
} /* }}} */ } /* }}} */
/**
* Check if the folder is subfolder
*
* This function checks if the passed folder is a subfolder of the current
* folder.
*
* @param object $subFolder potential sub folder
* @return boolean true if passes folder is a subfolder
*/
function isSubFolder($subfolder) { /* {{{ */
$db = $this->_dms->getDB();
$path = $this->getPath();
$sfpath = $subfolder->getPath();
/* It is a potential sub folder start with the path of the current folder.
* If the path differs, it can't be a sub folder.
*/
for($i=0; $i < count($path); $i++) {
if($path[$i] != $sfpath[$i])
return false;
}
return true;
} /* }}} */
/** /**
* Set a new folder * Set a new folder
* *
* This function moves a folder from one parent folder into another parent * This function moves a folder from one parent folder into another parent
* folder. It will fail if the root folder is moved. * folder. It will fail if the root folder is moved.
* *
* @param object new parent folder * @param object $newParent new parent folder
* @return boolean true if operation was successful otherwise false * @return boolean true if operation was successful otherwise false
*/ */
function setParent($newParent) { /* {{{ */ function setParent($newParent) { /* {{{ */
@ -165,6 +189,13 @@ class SeedDMS_Core_Folder extends SeedDMS_Core_Object {
return false; return false;
} }
/* Check if the new parent is the folder to be moved or even
* a subfolder of that folder
*/
if($this->isSubFolder($newParent)) {
return false;
}
// Update the folderList of the folder // Update the folderList of the folder
$pathPrefix=""; $pathPrefix="";
$path = $newParent->getPath(); $path = $newParent->getPath();

View File

@ -12,11 +12,11 @@
<email>uwe@steinmann.cx</email> <email>uwe@steinmann.cx</email>
<active>yes</active> <active>yes</active>
</lead> </lead>
<date>2013-09-05</date> <date>2013-11-27</date>
<time>07:41:57</time> <time>10:57:32</time>
<version> <version>
<release>4.3.0</release> <release>4.3.2</release>
<api>4.3.0</api> <api>4.3.2</api>
</version> </version>
<stability> <stability>
<release>stable</release> <release>stable</release>
@ -24,11 +24,9 @@
</stability> </stability>
<license uri="http://opensource.org/licenses/gpl-license">GPL License</license> <license uri="http://opensource.org/licenses/gpl-license">GPL License</license>
<notes> <notes>
- various small corrections - new method SeedDMS_Core_Folder::isSubFolder()
- comment of version is no longer taken from document if version comment is empty - check for subFolder in SeedDMS_Core_Folder::setParent()
- passing an array of users to SeedDMЅ_Core_DMS::search() instead of a single user ist now allowed - new methods SeedDMS_Core_DMS::checkFolders() and SeedDMS_Core_DMS::checkDocuments()
- turn on foreign key constraints for sqlite3
- SeedDMЅ_Core_Folder::getPath() can handle a subfolder treated as a root folder
</notes> </notes>
<contents> <contents>
<dir baseinstalldir="SeedDMS" name="/"> <dir baseinstalldir="SeedDMS" name="/">
@ -549,5 +547,25 @@ New release
- admins can be added as reviewer/approver again - admins can be added as reviewer/approver again
</notes> </notes>
</release> </release>
<release>
<date>2013-09-05</date>
<time>07:41:57</time>
<version>
<release>4.3.0</release>
<api>4.3.0</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<license uri="http://opensource.org/licenses/gpl-license">GPL License</license>
<notes>
- various small corrections
- comment of version is no longer taken from document if version comment is empty
- passing an array of users to SeedDMЅ_Core_DMS::search() instead of a single user ist now allowed
- turn on foreign key constraints for sqlite3
- SeedDMЅ_Core_Folder::getPath() can handle a subfolder treated as a root folder
</notes>
</release>
</changelog> </changelog>
</package> </package>

View File

@ -20,7 +20,7 @@
class SeedDMS_Version { class SeedDMS_Version {
var $_number = "4.3.1"; var $_number = "4.3.2";
var $_string = "SeedDMS"; var $_string = "SeedDMS";
function SeedDMS_Version() { function SeedDMS_Version() {

View File

@ -116,7 +116,7 @@ function fileExistsInIncludePath($file) { /* {{{ */
* Load default settings + set * Load default settings + set
*/ */
define("SEEDDMS_INSTALL", "on"); define("SEEDDMS_INSTALL", "on");
define("SEEDDMS_VERSION", "4.3.1"); define("SEEDDMS_VERSION", "4.3.2");
require_once('../inc/inc.ClassSettings.php'); require_once('../inc/inc.ClassSettings.php');

View File

@ -869,6 +869,8 @@ $text = array(
'unknown_owner' => "Unknown owner id", 'unknown_owner' => "Unknown owner id",
'unknown_user' => "Unknown user id", 'unknown_user' => "Unknown user id",
'unlinked_content' => "Unlinked content", 'unlinked_content' => "Unlinked content",
'unlinked_folders' => "Unlinked folders",
'unlinked_documents' => "Unlinked documents",
'unlinking_objects' => "Unlinking content", 'unlinking_objects' => "Unlinking content",
'unlock_cause_access_mode_all' => "You can still update it because you have access-mode \"all\". Locking will automatically be removed.", 'unlock_cause_access_mode_all' => "You can still update it because you have access-mode \"all\". Locking will automatically be removed.",
'unlock_cause_locking_user' => "You can still update it because you are also the one that locked it. Locking will automatically be removed.", 'unlock_cause_locking_user' => "You can still update it because you are also the one that locked it. Locking will automatically be removed.",

View File

@ -50,6 +50,10 @@ if (!is_object($targetFolder)) {
UI::exitError(getMLText("folder_title", array("foldername" => getMLText("invalid_folder_id"))),getMLText("invalid_folder_id")); UI::exitError(getMLText("folder_title", array("foldername" => getMLText("invalid_folder_id"))),getMLText("invalid_folder_id"));
} }
if($folder->isSubFolder($targetFolder)) {
UI::exitError(getMLText("folder_title", array("foldername" => $folder->getName())),getMLText("invalid_target_folder"));
}
if ($folder->getAccessMode($user) < M_READWRITE || $targetFolder->getAccessMode($user) < M_READWRITE) { if ($folder->getAccessMode($user) < M_READWRITE || $targetFolder->getAccessMode($user) < M_READWRITE) {
UI::exitError(getMLText("folder_title", array("foldername" => $folder->getName())),getMLText("access_denied")); UI::exitError(getMLText("folder_title", array("foldername" => $folder->getName())),getMLText("access_denied"));
} }

View File

@ -46,13 +46,16 @@ if ($folder->getAccessMode($user) < M_READWRITE) {
if(isset($_GET['targetid']) && $_GET['targetid']) { if(isset($_GET['targetid']) && $_GET['targetid']) {
$target = $dms->getFolder($_GET["targetid"]); $target = $dms->getFolder($_GET["targetid"]);
if (!is_object($target)) { if (!is_object($target)) {
UI::exitError(getMLText("document_title", array("documentname" => $document->getName())),getMLText("invalid_target_folder")); UI::exitError(getMLText("folder_title", array("foldername" => $folder->getName())),getMLText("invalid_target_folder"));
} }
if ($target->getAccessMode($user) < M_READWRITE) { if ($target->getAccessMode($user) < M_READWRITE) {
UI::exitError(getMLText("document_title", array("documentname" => htmlspecialchars($document->getName()))),getMLText("access_denied")); UI::exitError(getMLText("folder_title", array("foldername" => htmlspecialchars($folder->getName()))),getMLText("access_denied"));
} }
if($folder->isSubFolder($target)) {
UI::exitError(getMLText("folder_title", array("foldername" => $folder->getName())),getMLText("invalid_target_folder"));
}
} else { } else {
$target = null; $target = null;
} }

View File

@ -56,11 +56,13 @@ if(isset($_GET['setchecksum']) && $_GET['setchecksum'] == 1) {
$folder = $dms->getFolder($settings->_rootFolderID); $folder = $dms->getFolder($settings->_rootFolderID);
$unlinkedversions = $dms->getUnlinkedDocumentContent(); $unlinkedversions = $dms->getUnlinkedDocumentContent();
$unlinkedfolders = $dms->checkFolders();
$unlinkeddocuments = $dms->checkDocuments();
$nofilesizeversions = $dms->getNoFileSizeDocumentContent(); $nofilesizeversions = $dms->getNoFileSizeDocumentContent();
$nochecksumversions = $dms->getNoChecksumDocumentContent(); $nochecksumversions = $dms->getNoChecksumDocumentContent();
$tmp = explode('.', basename($_SERVER['SCRIPT_FILENAME'])); $tmp = explode('.', basename($_SERVER['SCRIPT_FILENAME']));
$view = UI::factory($theme, $tmp[1], array('dms'=>$dms, 'user'=>$user, 'folder'=>$folder, 'unlinkedcontent'=>$unlinkedversions, 'nofilesizeversions'=>$nofilesizeversions, 'nochecksumversions'=>$nochecksumversions, 'unlink'=>$unlink, 'setfilesize'=>$setfilesize, 'setchecksum'=>$setchecksum, 'repair'=>$repair)); $view = UI::factory($theme, $tmp[1], array('dms'=>$dms, 'user'=>$user, 'folder'=>$folder, 'unlinkedcontent'=>$unlinkedversions, 'unlinkedfolders'=>$unlinkedfolders, 'unlinkeddocuments'=>$unlinkeddocuments, 'nofilesizeversions'=>$nofilesizeversions, 'nochecksumversions'=>$nochecksumversions, 'unlink'=>$unlink, 'setfilesize'=>$setfilesize, 'setchecksum'=>$setchecksum, 'repair'=>$repair));
if($view) { if($view) {
$view->show(); $view->show();
exit; exit;

View File

@ -998,7 +998,7 @@ function clearFilename<?php print $formName ?>() {
$subfolders = SeedDMS_Core_DMS::filterAccess($subfolders, $user, $accessmode); $subfolders = SeedDMS_Core_DMS::filterAccess($subfolders, $user, $accessmode);
$children = array(); $children = array();
foreach($subfolders as $subfolder) { foreach($subfolders as $subfolder) {
$node = array('label'=>$subfolder->getName(), 'id'=>$subfolder->getID(), 'load_on_demand'=>$subfolder->hasSubFolders() ? true : false, 'is_folder'=>true); $node = array('label'=>$subfolder->getName(), 'id'=>$subfolder->getID(), 'load_on_demand'=>($subfolder->hasSubFolders() || ($subfolder->hasDocuments() && $showdocs)) ? true : false, 'is_folder'=>true);
if($expandtree || $pathfolder->getID() == $subfolder->getID()) { if($expandtree || $pathfolder->getID() == $subfolder->getID()) {
if($showdocs) { if($showdocs) {
$documents = $folder->getDocuments(); $documents = $folder->getDocuments();
@ -1018,7 +1018,7 @@ function clearFilename<?php print $formName ?>() {
$subfolders = SeedDMS_Core_DMS::filterAccess($subfolders, $user, $accessmode); $subfolders = SeedDMS_Core_DMS::filterAccess($subfolders, $user, $accessmode);
$children = array(); $children = array();
foreach($subfolders as $subfolder) { foreach($subfolders as $subfolder) {
$node = array('label'=>$subfolder->getName(), 'id'=>$subfolder->getID(), 'load_on_demand'=>$subfolder->hasSubFolders() ? true : false, 'is_folder'=>true); $node = array('label'=>$subfolder->getName(), 'id'=>$subfolder->getID(), 'load_on_demand'=>($subfolder->hasSubFolders() || ($subfolder->hasDocuments() && $showdocs)) ? true : false, 'is_folder'=>true);
$children[] = $node; $children[] = $node;
} }
return $children; return $children;

View File

@ -39,7 +39,7 @@ class SeedDMS_View_DocumentChooser extends SeedDMS_Bootstrap_Style {
$this->htmlStartPage(getMLText("choose_target_document")); $this->htmlStartPage(getMLText("choose_target_document"));
$this->contentContainerStart(); $this->contentContainerStart();
$this->printNewTreeNavigation($folderid, M_READ, 1, $form); $this->printNewTreeNavigation($folder->getID(), M_READ, 1, $form);
$this->contentContainerEnd(); $this->contentContainerEnd();
echo "</body>\n</html>\n"; echo "</body>\n</html>\n";
} /* }}} */ } /* }}} */

View File

@ -35,6 +35,28 @@ class SeedDMS_View_ObjectCheck extends SeedDMS_Bootstrap_Style {
/* Don't do folderlist check for root folder */ /* Don't do folderlist check for root folder */
if($path != ':') { if($path != ':') {
/* If the path contains a folder id twice, the a cyclic relation
* exists.
*/
$tmparr = explode(':', $path);
array_shift($tmparr);
if(count($tmparr) != count(array_unique($tmparr))) {
print "<tr>\n";
print "<td><a class=\"standardText\" href=\"../out/out.ViewFolder.php?folderid=".$folder->getID()."\"><img src=\"../out/images/folder_closed.gif\" width=18 height=18 border=0></a></td>";
print "<td><a class=\"standardText\" href=\"../out/out.ViewFolder.php?folderid=".$folder->getID()."\">";
print htmlspecialchars($path);
print "</a></td>";
$owner = $folder->getOwner();
print "<td>".htmlspecialchars($owner->getFullName())."</td>";
print "<td>Folder path contains cyclic relation</td>";
if($repair) {
print "<td><span class=\"success\">".getMLText('repaired')."</span></td>\n";
} else {
print "<td></td>\n";
}
print "</tr>\n";
}
$folderList = $folder->getFolderList(); $folderList = $folder->getFolderList();
/* Check the folder */ /* Check the folder */
if($folderList != $path) { if($folderList != $path) {
@ -146,6 +168,8 @@ class SeedDMS_View_ObjectCheck extends SeedDMS_Bootstrap_Style {
$user = $this->params['user']; $user = $this->params['user'];
$folder = $this->params['folder']; $folder = $this->params['folder'];
$unlinkedversions = $this->params['unlinkedcontent']; $unlinkedversions = $this->params['unlinkedcontent'];
$unlinkedfolders = $this->params['unlinkedfolders'];
$unlinkeddocuments = $this->params['unlinkeddocuments'];
$nofilesizeversions = $this->params['nofilesizeversions']; $nofilesizeversions = $this->params['nofilesizeversions'];
$nochecksumversions = $this->params['nochecksumversions']; $nochecksumversions = $this->params['nochecksumversions'];
$repair = $this->params['repair']; $repair = $this->params['repair'];
@ -180,6 +204,52 @@ class SeedDMS_View_ObjectCheck extends SeedDMS_Bootstrap_Style {
} }
$this->contentContainerEnd(); $this->contentContainerEnd();
if($unlinkedfolders) {
$this->contentHeading(getMLText("unlinked_folders"));
$this->contentContainerStart();
print "<table class=\"table-condensed\">";
print "<thead>\n<tr>\n";
print "<th>".getMLText("name")."</th>\n";
print "<th>".getMLText("id")."</th>\n";
print "<th>".getMLText("parent")."</th>\n";
print "<th>".getMLText("error")."</th>\n";
print "<th></th>\n";
print "</tr>\n</thead>\n<tbody>\n";
foreach($unlinkedfolders as $error) {
echo "<tr>";
echo "<td>".$error['name']."</td>";
echo "<td>".$error['id']."</td>";
echo "<td>".$error['parent']."</td>";
echo "<td>".$error['msg']."</td>";
echo "</tr>";
}
print "</tbody></table>\n";
$this->contentContainerEnd();
}
if($unlinkeddocuments) {
$this->contentHeading(getMLText("unlinked_documents"));
$this->contentContainerStart();
print "<table class=\"table-condensed\">";
print "<thead>\n<tr>\n";
print "<th>".getMLText("name")."</th>\n";
print "<th>".getMLText("id")."</th>\n";
print "<th>".getMLText("parent")."</th>\n";
print "<th>".getMLText("error")."</th>\n";
print "<th></th>\n";
print "</tr>\n</thead>\n<tbody>\n";
foreach($unlinkeddocuments as $error) {
echo "<tr>";
echo "<td>".$error['name']."</td>";
echo "<td>".$error['id']."</td>";
echo "<td>".$error['parent']."</td>";
echo "<td>".$error['msg']."</td>";
echo "</tr>";
}
print "</tbody></table>\n";
$this->contentContainerEnd();
}
$this->contentHeading(getMLText("unlinked_content")); $this->contentHeading(getMLText("unlinked_content"));
$this->contentContainerStart(); $this->contentContainerStart();
if($unlink) { if($unlink) {