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
--------------------------------------------------------------------------------

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
#restapi webapp

View File

@ -216,6 +216,12 @@ full text search engine support, you will also need to unpack
> Server
> 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
staging, cache and lucene and make sure they are writable by your web server,
but not accessible through the web.

View File

@ -243,7 +243,7 @@ class SeedDMS_Core_DMS {
$this->convertFileTypes = array();
$this->version = '@package_version@';
if($this->version[0] == '@')
$this->version = '4.3.1';
$this->version = '4.3.2';
} /* }}} */
function getDB() { /* {{{ */
@ -493,7 +493,7 @@ class SeedDMS_Core_DMS {
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);
$thirty = array (4, 6, 9, 11);
@ -524,7 +524,7 @@ class SeedDMS_Core_DMS {
}
return mktime($hour, $min, $sec, $month, $day, $year);
}
} /* }}} */
/*
* Search the database for documents
@ -999,6 +999,85 @@ class SeedDMS_Core_DMS {
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
*

View File

@ -149,13 +149,37 @@ class SeedDMS_Core_Folder extends SeedDMS_Core_Object {
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
*
* This function moves a folder from one parent folder into another parent
* 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
*/
function setParent($newParent) { /* {{{ */
@ -165,6 +189,13 @@ class SeedDMS_Core_Folder extends SeedDMS_Core_Object {
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
$pathPrefix="";
$path = $newParent->getPath();

View File

@ -12,11 +12,11 @@
<email>uwe@steinmann.cx</email>
<active>yes</active>
</lead>
<date>2013-09-05</date>
<time>07:41:57</time>
<date>2013-11-27</date>
<time>10:57:32</time>
<version>
<release>4.3.0</release>
<api>4.3.0</api>
<release>4.3.2</release>
<api>4.3.2</api>
</version>
<stability>
<release>stable</release>
@ -24,11 +24,9 @@
</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
- new method SeedDMS_Core_Folder::isSubFolder()
- check for subFolder in SeedDMS_Core_Folder::setParent()
- new methods SeedDMS_Core_DMS::checkFolders() and SeedDMS_Core_DMS::checkDocuments()
</notes>
<contents>
<dir baseinstalldir="SeedDMS" name="/">
@ -549,5 +547,25 @@ New release
- admins can be added as reviewer/approver again
</notes>
</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>
</package>

View File

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

View File

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

View File

@ -869,6 +869,8 @@ $text = array(
'unknown_owner' => "Unknown owner id",
'unknown_user' => "Unknown user id",
'unlinked_content' => "Unlinked content",
'unlinked_folders' => "Unlinked folders",
'unlinked_documents' => "Unlinked documents",
'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_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"));
}
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) {
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']) {
$target = $dms->getFolder($_GET["targetid"]);
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) {
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 {
$target = null;
}

View File

@ -56,11 +56,13 @@ if(isset($_GET['setchecksum']) && $_GET['setchecksum'] == 1) {
$folder = $dms->getFolder($settings->_rootFolderID);
$unlinkedversions = $dms->getUnlinkedDocumentContent();
$unlinkedfolders = $dms->checkFolders();
$unlinkeddocuments = $dms->checkDocuments();
$nofilesizeversions = $dms->getNoFileSizeDocumentContent();
$nochecksumversions = $dms->getNoChecksumDocumentContent();
$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) {
$view->show();
exit;

View File

@ -998,7 +998,7 @@ function clearFilename<?php print $formName ?>() {
$subfolders = SeedDMS_Core_DMS::filterAccess($subfolders, $user, $accessmode);
$children = array();
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($showdocs) {
$documents = $folder->getDocuments();
@ -1018,7 +1018,7 @@ function clearFilename<?php print $formName ?>() {
$subfolders = SeedDMS_Core_DMS::filterAccess($subfolders, $user, $accessmode);
$children = array();
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;
}
return $children;

View File

@ -39,7 +39,7 @@ class SeedDMS_View_DocumentChooser extends SeedDMS_Bootstrap_Style {
$this->htmlStartPage(getMLText("choose_target_document"));
$this->contentContainerStart();
$this->printNewTreeNavigation($folderid, M_READ, 1, $form);
$this->printNewTreeNavigation($folder->getID(), M_READ, 1, $form);
$this->contentContainerEnd();
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 */
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();
/* Check the folder */
if($folderList != $path) {
@ -146,6 +168,8 @@ class SeedDMS_View_ObjectCheck extends SeedDMS_Bootstrap_Style {
$user = $this->params['user'];
$folder = $this->params['folder'];
$unlinkedversions = $this->params['unlinkedcontent'];
$unlinkedfolders = $this->params['unlinkedfolders'];
$unlinkeddocuments = $this->params['unlinkeddocuments'];
$nofilesizeversions = $this->params['nofilesizeversions'];
$nochecksumversions = $this->params['nochecksumversions'];
$repair = $this->params['repair'];
@ -180,6 +204,52 @@ class SeedDMS_View_ObjectCheck extends SeedDMS_Bootstrap_Style {
}
$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->contentContainerStart();
if($unlink) {