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

This commit is contained in:
Uwe Steinmann 2021-09-22 10:54:54 +02:00
commit 3b55c458c2
38 changed files with 780 additions and 849 deletions

View File

@ -214,6 +214,8 @@
- major overhaul of notifications
- check view access for FolderAccess and DocumentAccess
- more settings to disable import and download of extensions
- add new configuration for excluding sequence and comment when creating
a folder
--------------------------------------------------------------------------------
Changes in version 5.1.23

View File

@ -1,122 +1,122 @@
<?php
/**
* Implementation of user and group access object
*
* @category DMS
* @package SeedDMS_Core
* @license GPL 2
* @version @version@
* @author Uwe Steinmann <uwe@steinmann.cx>
* @copyright Copyright (C) 2002-2005 Markus Westphal, 2006-2008 Malcolm Cowe,
* 2010 Uwe Steinmann
* @version Release: @package_version@
*/
/**
* Class to represent a user access right.
* This class cannot be used to modify access rights.
*
* @category DMS
* @package SeedDMS_Core
* @author Markus Westphal, Malcolm Cowe, Uwe Steinmann <uwe@steinmann.cx>
* @copyright Copyright (C) 2002-2005 Markus Westphal, 2006-2008 Malcolm Cowe,
* 2010 Uwe Steinmann
* @version Release: @package_version@
*/
class SeedDMS_Core_UserAccess { /* {{{ */
/**
* @var SeedDMS_Core_User
*/
var $_user;
/**
* @var
*/
var $_mode;
/**
* SeedDMS_Core_UserAccess constructor.
* @param $user
* @param $mode
*/
function __construct($user, $mode) {
$this->_user = $user;
$this->_mode = $mode;
}
/**
* @return int
*/
function getUserID() { return $this->_user->getID(); }
/**
* @return mixed
*/
function getMode() { return $this->_mode; }
/**
* @return bool
*/
function isAdmin() {
return ($this->_mode == SeedDMS_Core_User::role_admin);
}
/**
* @return SeedDMS_Core_User
*/
function getUser() {
return $this->_user;
}
} /* }}} */
/**
* Class to represent a group access right.
* This class cannot be used to modify access rights.
*
* @category DMS
* @package SeedDMS_Core
* @author Markus Westphal, Malcolm Cowe, Uwe Steinmann <uwe@steinmann.cx>
* @copyright Copyright (C) 2002-2005 Markus Westphal, 2006-2008 Malcolm Cowe, 2010 Uwe Steinmann
* @version Release: @package_version@
*/
class SeedDMS_Core_GroupAccess { /* {{{ */
/**
* @var SeedDMS_Core_Group
*/
var $_group;
/**
* @var
*/
var $_mode;
/**
* SeedDMS_Core_GroupAccess constructor.
* @param $group
* @param $mode
*/
function __construct($group, $mode) {
$this->_group = $group;
$this->_mode = $mode;
}
/**
* @return int
*/
function getGroupID() { return $this->_group->getID(); }
/**
* @return mixed
*/
function getMode() { return $this->_mode; }
/**
* @return SeedDMS_Core_Group
*/
function getGroup() {
return $this->_group;
}
} /* }}} */
<?php
/**
* Implementation of user and group access object
*
* @category DMS
* @package SeedDMS_Core
* @license GPL 2
* @version @version@
* @author Uwe Steinmann <uwe@steinmann.cx>
* @copyright Copyright (C) 2002-2005 Markus Westphal, 2006-2008 Malcolm Cowe,
* 2010 Uwe Steinmann
* @version Release: @package_version@
*/
/**
* Class to represent a user access right.
* This class cannot be used to modify access rights.
*
* @category DMS
* @package SeedDMS_Core
* @author Markus Westphal, Malcolm Cowe, Uwe Steinmann <uwe@steinmann.cx>
* @copyright Copyright (C) 2002-2005 Markus Westphal, 2006-2008 Malcolm Cowe,
* 2010 Uwe Steinmann
* @version Release: @package_version@
*/
class SeedDMS_Core_UserAccess { /* {{{ */
/**
* @var SeedDMS_Core_User
*/
var $_user;
/**
* @var
*/
var $_mode;
/**
* SeedDMS_Core_UserAccess constructor.
* @param $user
* @param $mode
*/
function __construct($user, $mode) {
$this->_user = $user;
$this->_mode = $mode;
}
/**
* @return int
*/
function getUserID() { return $this->_user->getID(); }
/**
* @return mixed
*/
function getMode() { return $this->_mode; }
/**
* @return bool
*/
function isAdmin() {
return ($this->_mode == SeedDMS_Core_User::role_admin);
}
/**
* @return SeedDMS_Core_User
*/
function getUser() {
return $this->_user;
}
} /* }}} */
/**
* Class to represent a group access right.
* This class cannot be used to modify access rights.
*
* @category DMS
* @package SeedDMS_Core
* @author Markus Westphal, Malcolm Cowe, Uwe Steinmann <uwe@steinmann.cx>
* @copyright Copyright (C) 2002-2005 Markus Westphal, 2006-2008 Malcolm Cowe, 2010 Uwe Steinmann
* @version Release: @package_version@
*/
class SeedDMS_Core_GroupAccess { /* {{{ */
/**
* @var SeedDMS_Core_Group
*/
var $_group;
/**
* @var
*/
var $_mode;
/**
* SeedDMS_Core_GroupAccess constructor.
* @param $group
* @param $mode
*/
function __construct($group, $mode) {
$this->_group = $group;
$this->_mode = $mode;
}
/**
* @return int
*/
function getGroupID() { return $this->_group->getID(); }
/**
* @return mixed
*/
function getMode() { return $this->_mode; }
/**
* @return SeedDMS_Core_Group
*/
function getGroup() {
return $this->_group;
}
} /* }}} */

View File

@ -175,7 +175,7 @@ class SeedDMS_Core_Attribute { /* {{{ */
if(is_array($values)) {
if($values) {
$vsep = $this->getValueSetSeparator();
$vsep = $this->_attrdef->getValueSetSeparator();
if($valueset) {
/* Validation should have been done before
$error = false;
@ -409,7 +409,9 @@ class SeedDMS_Core_AttributeDefinition { /* {{{ */
protected $_dms;
/**
* @var string
* @var string just the separator of a value set (not used)
*
* @access protected
*/
protected $_separator;
@ -441,6 +443,25 @@ class SeedDMS_Core_AttributeDefinition { /* {{{ */
const objtype_document = '2';
const objtype_documentcontent = '3';
/*
* The validation error codes
*/
const val_error_none = 0;
const val_error_min_values = 1;
const val_error_max_values = 2;
const val_error_boolean = 8;
const val_error_int = 6;
const val_error_date = 9;
const val_error_float = 7;
const val_error_regex = 3;
const val_error_email = 5;
const val_error_url = 4;
const val_error_document = 10;
const val_error_folder = 11;
const val_error_user = 12;
const val_error_group = 13;
const val_error_valueset = 14;
/**
* Constructor
*
@ -465,10 +486,10 @@ class SeedDMS_Core_AttributeDefinition { /* {{{ */
$this->_minvalues = $minvalues;
$this->_maxvalues = $maxvalues;
$this->_valueset = $valueset;
$this->_separator = '';
$this->_separator = substr($valueset, 0, 1);
$this->_regex = $regex;
$this->_dms = null;
$this->_validation_error = 0;
$this->_validation_error = SeedDMS_Core_AttributeDefinition::val_error_none;
} /* }}} */
/**
@ -671,10 +692,10 @@ class SeedDMS_Core_AttributeDefinition { /* {{{ */
if(strlen($this->_valueset) > 1) {
return $this->_valueset[0];
} elseif($this->_multiple) {
if($this->_type == SeedDMS_Core_AttributeDefinition::type_user || $this->_type == SeedDMS_Core_AttributeDefinition::type_group)
return ',';
else
if($this->_type == SeedDMS_Core_AttributeDefinition::type_boolean)
return '';
else
return ',';
} else {
return '';
}
@ -683,6 +704,8 @@ class SeedDMS_Core_AttributeDefinition { /* {{{ */
/**
* Get the whole value set as an array
*
* Each element is trimmed.
*
* @return array values of value set or false if the value set has
* less than 2 chars
*/
@ -694,9 +717,9 @@ class SeedDMS_Core_AttributeDefinition { /* {{{ */
} /* }}} */
/**
* Get the n'th value of a value set
* Get the n'th trimmed value of a value set
*
* @param $ind
* @param $ind starting from 0 for the first element in the value set
* @return string n'th value of value set or false if the index is
* out of range or the value set has less than 2 chars
* @internal param int $index
@ -717,7 +740,9 @@ class SeedDMS_Core_AttributeDefinition { /* {{{ */
*
* A value set is a list of values allowed for an attribute. The values
* are separated by a char which must also be the first char of the
* value set string.
* value set string. The method decomposes the value set, removes all
* leading and trailing white space from the elements and recombines them
* into a string.
*
* @param string $valueset
* @return boolean true if value set could be set, otherwise false
@ -729,8 +754,9 @@ class SeedDMS_Core_AttributeDefinition { /* {{{ */
$tmp[] = str_replace('"', '""', $value);
}
$valuesetstr = implode(",", $tmp);
*/
if(trim($valueset)) {
*/
$valueset = trim($valueset);
if($valueset) {
$valuesetarr = array_map('trim', explode($valueset[0], substr($valueset, 1)));
$valuesetstr = $valueset[0].implode($valueset[0], $valuesetarr);
} else {
@ -744,8 +770,8 @@ class SeedDMS_Core_AttributeDefinition { /* {{{ */
if (!$res)
return false;
$this->_valueset = $valueset;
$this->_separator = substr($valueset, 0, 1);
$this->_valueset = $valuesetstr;
$this->_separator = substr($valuesetstr, 0, 1);
return true;
} /* }}} */
@ -763,12 +789,23 @@ class SeedDMS_Core_AttributeDefinition { /* {{{ */
*
* A value of the attribute must match this regular expression.
*
* The methods checks if the regular expression is valid by running
* preg_match() on an empty string and see if it fails. Trying to set
* an invalid regular expression will not overwrite the current
* regular expression.
*
* All leading and trailing spaces of $regex will be removed.
*
* @param string $regex
* @return boolean true if regex could be set, otherwise false
* @return boolean true if regex could be set or is invalid, otherwise false
*/
function setRegex($regex) { /* {{{ */
$db = $this->_dms->getDB();
$regex = trim($regex);
if($regex && @preg_match($regex, '') === false)
return false;
$queryStr = "UPDATE `tblAttributeDefinitions` SET `regex` =".$db->qstr($regex)." WHERE `id` = " . $this->_id;
$res = $db->getResult($queryStr);
if (!$res)
@ -809,13 +846,15 @@ class SeedDMS_Core_AttributeDefinition { /* {{{ */
/**
* Parse a given value according to attribute definition
*
* The return value is always an array, even if the attribute is single
* value attribute.
* The return value is always an array, even if the attribute is a single
* value attribute. If the type of attribute is any of document, folder, user,
* or group then this method will fetch each object from the database and
* return an array of SeedDMS_Core_Document, SeedDMS_Core_Folder, etc.
*
* @param $value
* @param $value string
* @return array|bool
*/
function parseValue($value) { /* {{{ */
function parseValue(string $value) { /* {{{ */
if($this->getMultipleValues()) {
/* If the value doesn't start with the separator used in the value set,
* then assume that the value was not saved with a leading separator.
@ -1149,8 +1188,10 @@ class SeedDMS_Core_AttributeDefinition { /* {{{ */
*
* @param string|array $attrvalue attribute value
* @param object $object set if the current attribute is saved for this object
* (this will only be passed to the onAttributeValidate callback)
* @param boolean $new set to true if the value is new value and not taken from
* an existing attribute
* an existing attribute
* (this will only be passed to the onAttributeValidate callback)
* @return boolean true if validation succeds, otherwise false
*/
function validate($attrvalue, $object=null, $new=false) { /* {{{ */
@ -1164,36 +1205,38 @@ class SeedDMS_Core_AttributeDefinition { /* {{{ */
}
/* Turn $attrvalue into an array of values. Checks if $attrvalue starts
* with a separator char as set in the value set and uses it to explode
* with a separator char as set in the value set and use it to explode
* the $attrvalue. If the separator doesn't match or this attribute
* definition doesn't have a value set, then just create a one element
* array. if $attrvalue is empty, then create an empty array.
*/
if($this->getMultipleValues()) {
if(is_string($attrvalue)) {
if(is_string($attrvalue) && $attrvalue) {
$sep = $attrvalue[0];
$vsep = $this->getValueSetSeparator();
if($sep == $vsep)
$values = explode($attrvalue[0], substr($attrvalue, 1));
else
$values = array($attrvalue);
} elseif(is_string($attrvalue) && !$attrvalue) {
$values = array();
} else
$values = $attrvalue;
} elseif($attrvalue) {
$values = array($attrvalue);
} elseif($attrvalue !== null) {
$values = array($attrvalue);
} else {
$values = array();
}
/* Check if attribute value has at least the minimum number of values */
$this->_validation_error = 0;
$this->_validation_error = SeedDMS_Core_AttributeDefinition::val_error_none;
if($this->getMinValues() > count($values)) {
$this->_validation_error = 1;
$this->_validation_error = SeedDMS_Core_AttributeDefinition::val_error_min_values;
return false;
}
/* Check if attribute value has not more than maximum number of values */
if($this->getMaxValues() && $this->getMaxValues() < count($values)) {
$this->_validation_error = 2;
$this->_validation_error = SeedDMS_Core_AttributeDefinition::val_error_max_values;
return false;
}
@ -1201,55 +1244,56 @@ class SeedDMS_Core_AttributeDefinition { /* {{{ */
switch((string) $this->getType()) {
case self::type_boolean:
foreach($values as $value) {
$success &= preg_match('/^[01]$/', $value) ? true : false;
$success = $success && (preg_match('/^[01]$/', $value) ? true : false);
}
if(!$success)
$this->_validation_error = 8;
$this->_validation_error = SeedDMS_Core_AttributeDefinition::val_error_boolean;
break;
case self::type_int:
foreach($values as $value) {
$success &= preg_match('/^[0-9]*$/', $value) ? true : false;
$success = $success && (preg_match('/^[0-9]*$/', $value) ? true : false);
}
if(!$success)
$this->_validation_error = 6;
$this->_validation_error = SeedDMS_Core_AttributeDefinition::val_error_int;
break;
case self::type_date:
foreach($values as $value) {
$success &= preg_match('/^[12][0-9]{3}-[01][0-9]-[0-9]{2}$/', $value) ? true : false;
$d = explode('-', $value, 3);
$success = $success && (count($d) == 3)&& checkdate((int) $d[1], (int) $d[2], (int) $d[0]);
}
if(!$success)
$this->_validation_error = 9;
$this->_validation_error = SeedDMS_Core_AttributeDefinition::val_error_date;
break;
case self::type_float:
foreach($values as $value) {
$success &= is_numeric($value);
$success = $success && is_numeric($value);
}
if(!$success)
$this->_validation_error = 7;
$this->_validation_error = SeedDMS_Core_AttributeDefinition::val_error_float;
break;
case self::type_string:
if(trim($this->getRegex()) != '') {
foreach($values as $value) {
$success &= preg_match($this->getRegex(), $value) ? true : false;
$success = $success && (preg_match($this->getRegex(), $value) ? true : false);
}
}
if(!$success)
$this->_validation_error = 3;
$this->_validation_error = SeedDMS_Core_AttributeDefinition::val_error_regex;
break;
case self::type_email:
foreach($values as $value) {
//$success &= filter_var($value, FILTER_VALIDATE_EMAIL) ? true : false;
$success &= preg_match('/^[a-z0-9._-]+@+[a-z0-9._-]+\.+[a-z]{2,63}$/i', $value);
$success = $success && (preg_match('/^[a-z0-9._-]+@[a-z0-9-]{2,63}(\.[a-z0-9-]{2,63})*\.[a-z]{2,63}$/i', $value) ? true : false);
}
if(!$success)
$this->_validation_error = 5;
$this->_validation_error = SeedDMS_Core_AttributeDefinition::val_error_email;
break;
case self::type_url:
foreach($values as $value) {
$success &= preg_match('/^http(s)?:\/\/[a-z0-9-]+(.[a-z0-9-]+)*(:[0-9]+)?(\/.*)?$/i', $value);
$success = $success && (preg_match('/^http(s)?:\/\/[a-z0-9_-]+(\.[a-z0-9-]{2,63})*(:[0-9]+)?(\/.*)?$/i', $value) ? true : false);
}
if(!$success)
$this->_validation_error = 4;
$this->_validation_error = SeedDMS_Core_AttributeDefinition::val_error_url;
break;
case self::type_document:
foreach($values as $value) {
@ -1258,7 +1302,7 @@ class SeedDMS_Core_AttributeDefinition { /* {{{ */
$success = false;
}
if(!$success)
$this->_validation_error = 10;
$this->_validation_error = SeedDMS_Core_AttributeDefinition::val_error_document;
break;
case self::type_folder:
foreach($values as $value) {
@ -1267,7 +1311,7 @@ class SeedDMS_Core_AttributeDefinition { /* {{{ */
$success = false;
}
if(!$success)
$this->_validation_error = 11;
$this->_validation_error = SeedDMS_Core_AttributeDefinition::val_error_folder;
break;
case self::type_user:
foreach($values as $value) {
@ -1276,7 +1320,7 @@ class SeedDMS_Core_AttributeDefinition { /* {{{ */
$success = false;
}
if(!$success)
$this->_validation_error = 12;
$this->_validation_error = SeedDMS_Core_AttributeDefinition::val_error_user;
break;
case self::type_group:
foreach($values as $value) {
@ -1285,7 +1329,7 @@ class SeedDMS_Core_AttributeDefinition { /* {{{ */
$success = false;
}
if(!$success)
$this->_validation_error = 13;
$this->_validation_error = SeedDMS_Core_AttributeDefinition::val_error_group;
break;
}
@ -1294,10 +1338,16 @@ class SeedDMS_Core_AttributeDefinition { /* {{{ */
/* Check if value is in value set */
if($valueset = $this->getValueSetAsArray()) {
foreach($values as $value) {
if(!in_array($value, $valueset)) {
$success = false;
$this->_validation_error = 10;
/* An empty value cannot be the value set */
if(!$values) {
$success = false;
$this->_validation_error = SeedDMS_Core_AttributeDefinition::val_error_valueset;
} else {
foreach($values as $value) {
if(!in_array($value, $valueset)) {
$success = false;
$this->_validation_error = SeedDMS_Core_AttributeDefinition::val_error_valueset;
}
}
}
}

View File

@ -5,9 +5,8 @@
* @category DMS
* @package SeedDMS_Core
* @license GPL 2
* @version @version@
* @author Uwe Steinmann <uwe@steinmann.cx>
* @copyright Copyright (C) 2010, Uwe Steinmann
* @copyright 2010 Uwe Steinmann
* @version Release: @package_version@
*/
@ -123,13 +122,6 @@ class SeedDMS_Core_DMS {
*/
public $maxDirID;
/**
* @var boolean $enableConverting set to true if conversion of content
* is desired
* @access public
*/
public $enableConverting;
/**
* @var boolean $forceRename use renameFile() instead of copyFile() when
* copying the document content into the data store. The default is
@ -141,19 +133,6 @@ class SeedDMS_Core_DMS {
*/
public $forceRename;
/**
* @var array $convertFileTypes list of files types that shall be converted
* @access public
*/
public $convertFileTypes;
/**
* @var array $viewOnlineFileTypes list of files types that can be viewed
* online
* @access public
*/
public $viewOnlineFileTypes;
/**
* @var array $noReadForStatus list of status without read right
* online. DO NOT USE ANYMORE. SeedDMS_Core_DocumentContent::getAccessMode()
@ -219,7 +198,7 @@ class SeedDMS_Core_DMS {
* Checks if two objects are equal by comparing their IDs
*
* The regular php check done by '==' compares all attributes of
* two objects, which is often not required. The method will first check
* two objects, which is often not required. This method will first check
* if the objects are instances of the same class and than if they
* have the same id.
*
@ -277,7 +256,8 @@ class SeedDMS_Core_DMS {
*
* The list of objects to be checked can be of any class, but has to have
* a method getAccessMode($user) which checks if the given user has at
* least access rights to the object as passed in $minMode.
* least the access right on the object as passed in $minMode.
* Hence, passing a group instead of user is possible.
*
* This function can be used for documents and folders and calls
* {@link SeedDMS_Core_Folder::getAccessMode()} or
@ -314,11 +294,12 @@ class SeedDMS_Core_DMS {
* Filter out users which cannot access an object in a given mode.
*
* The list of users to be checked can be of any class, but has to have
* a method getAccessMode($user) which checks if a user has at least
* access rights as passed in $minMode.
* a method getAccessMode($user) which checks if a user has at least the
* access right as passed in $minMode. Hence, passing a list of groups
* instead of users is possible.
*
* @param object $obj object that shall be accessed
* @param array $users list of users which are to check for sufficient
* @param array $users list of users/groups which are to check for sufficient
* access rights
* @param integer $minMode minimum access right on the object for each user
* (M_ANY, M_NONE, M_READ, M_READWRITE, M_ALL)
@ -460,11 +441,10 @@ class SeedDMS_Core_DMS {
else
$this->contentDir = $contentDir.'/';
$this->rootFolderID = 1;
$this->user = null;
$this->maxDirID = 0; //31998;
$this->forceRename = false;
$this->checkWithinRootDir = false;
$this->enableConverting = false;
$this->convertFileTypes = array();
$this->noReadForStatus = array();
$this->user = null;
$this->classnames = array();
@ -583,9 +563,9 @@ class SeedDMS_Core_DMS {
function getDBVersion() { /* {{{ */
$tbllist = $this->db->TableList();
$tbllist = explode(',',strtolower(join(',',$tbllist)));
if(!array_search('tblversion', $tbllist))
if(!in_array('tblversion', $tbllist))
return false;
$queryStr = "SELECT * FROM `tblVersion` order by `major`,`minor`,`subminor` limit 1";
$queryStr = "SELECT * FROM `tblVersion` ORDER BY `major`,`minor`,`subminor` LIMIT 1";
$resArr = $this->db->getResultArray($queryStr);
if (is_bool($resArr) && $resArr == false)
return false;
@ -605,9 +585,9 @@ class SeedDMS_Core_DMS {
function checkVersion() { /* {{{ */
$tbllist = $this->db->TableList();
$tbllist = explode(',',strtolower(join(',',$tbllist)));
if(!array_search('tblversion', $tbllist))
if(!in_array('tblversion', $tbllist))
return true;
$queryStr = "SELECT * FROM `tblVersion` order by `major`,`minor`,`subminor` limit 1";
$queryStr = "SELECT * FROM `tblVersion` ORDER BY `major`,`minor`,`subminor` LIMIT 1";
$resArr = $this->db->getResultArray($queryStr);
if (is_bool($resArr) && $resArr == false)
return false;
@ -622,13 +602,23 @@ class SeedDMS_Core_DMS {
/**
* Set id of root folder
*
* This function must be called right after creating an instance of
* {@link SeedDMS_Core_DMS}
*
* The new root folder id will only be set if the folder actually
* exists. In that case the old root folder id will be returned.
* If it does not exists, the method will return false;
* @param integer $id id of root folder
* @return boolean/int old root folder id if new root folder exists, otherwise false
*/
function setRootFolderID($id) { /* {{{ */
$this->rootFolderID = $id;
if($this->getFolder($id)) {
$oldid = $this->rootFolderID;
$this->rootFolderID = $id;
return $oldid;
}
return false;
} /* }}} */
/**
@ -668,18 +658,6 @@ class SeedDMS_Core_DMS {
return $this->getFolder($this->rootFolderID);
} /* }}} */
function setEnableConverting($enable) { /* {{{ */
$this->enableConverting = $enable;
} /* }}} */
function setConvertFileTypes($types) { /* {{{ */
$this->convertFileTypes = $types;
} /* }}} */
function setViewOnlineFileTypes($types) { /* {{{ */
$this->viewOnlineFileTypes = $types;
} /* }}} */
function setForceRename($enable) { /* {{{ */
$this->forceRename = $enable;
} /* }}} */
@ -691,11 +669,22 @@ class SeedDMS_Core_DMS {
* called right after instanciating the class, because some methods in
* SeedDMS_Core_Document() require the currently logged in user.
*
* @param object $user
* @param object $user this muss not be empty and an instance of SeedDMS_Core_User
* @return bool|object returns the old user object or null on success, otherwise false
*
*/
function setUser($user) { /* {{{ */
$this->user = $user;
if(!$user) {
$olduser = $this->user;
$this->user = null;
return $olduser;
}
if(is_object($user) && (get_class($user) == $this->getClassname('user'))) {
$olduser = $this->user;
$this->user = $user;
return $olduser;
}
return false;
} /* }}} */
/**
@ -716,7 +705,7 @@ class SeedDMS_Core_DMS {
* This function retrieves a document from the database by its id.
*
* @param integer $id internal id of document
* @return SeedDMS_Core_Document instance of {@link SeedDMS_Core_Document} or false
* @return SeedDMS_Core_Document instance of {@link SeedDMS_Core_Document}, null or false
*/
function getDocument($id) { /* {{{ */
$classname = $this->classnames['document'];
@ -752,7 +741,7 @@ class SeedDMS_Core_DMS {
* If the parameter $date is a negative number or a date in the past, then
* all documents from the start of that date till the end of the current
* day will be returned. If $date is a positive integer or $date is a
* date in the future, the all documents from the start of the current
* date in the future, then all documents from the start of the current
* day till the end of the day of the given date will be returned.
* Passing 0 or the
* current date in $date, will return all documents expiring the current
@ -779,7 +768,9 @@ class SeedDMS_Core_DMS {
} elseif(is_string($date)) {
$tmp = explode('-', $date, 3);
if(count($tmp) != 3)
return false;
return false;
if(!self::checkDate($date, 'Y-m-d'))
return false;
$ts = mktime(0, 0, 0, $tmp[1], $tmp[2], $tmp[0]);
} else
return false;
@ -833,14 +824,15 @@ class SeedDMS_Core_DMS {
*
* This function searches a document by its name and restricts the search
* to the given folder if passed as the second parameter.
* If there are more than one document with that name, then only the first
* one will be returned.
* If there are more than one document with that name, then only the
* one with the highest id will be returned.
*
* @param string $name
* @param object $folder
* @return SeedDMS_Core_Document|boolean found document or false
* @param string $name Name of the document
* @param object $folder parent folder of document
* @return SeedDMS_Core_Document|null|boolean found document or null if not document was found or false in case of an error
*/
function getDocumentByName($name, $folder=null) { /* {{{ */
$name = trim($name);
if (!$name) return false;
$queryStr = "SELECT `tblDocuments`.*, `tblDocumentLocks`.`userID` as `lockUser` ".
@ -849,14 +841,14 @@ class SeedDMS_Core_DMS {
"WHERE `tblDocuments`.`name` = " . $this->db->qstr($name);
if($folder)
$queryStr .= " AND `tblDocuments`.`folder` = ". $folder->getID();
$queryStr .= " LIMIT 1";
$queryStr .= " ORDER BY `tblDocuments`.`id` DESC LIMIT 1";
$resArr = $this->db->getResultArray($queryStr);
if (is_bool($resArr) && !$resArr)
return false;
if(!$resArr)
return false;
return null;
$row = $resArr[0];
/** @var SeedDMS_Core_Document $document */
@ -871,12 +863,15 @@ class SeedDMS_Core_DMS {
* This function searches a document by the name of the last document
* version and restricts the search
* to given folder if passed as the second parameter.
* If there are more than one document with that name, then only the
* one with the highest id will be returned.
*
* @param string $name
* @param object $folder
* @return SeedDMS_Core_Document|boolean found document or false
* @param string $name Name of the original file
* @param object $folder parent folder of document
* @return SeedDMS_Core_Document|null|boolean found document or null if not document was found or false in case of an error
*/
function getDocumentByOriginalFilename($name, $folder=null) { /* {{{ */
$name = trim($name);
if (!$name) return false;
if (!$this->db->createTemporaryTable("ttcontentid")) {
@ -890,14 +885,14 @@ class SeedDMS_Core_DMS {
"WHERE `tblDocumentContent`.`orgFileName` = " . $this->db->qstr($name);
if($folder)
$queryStr .= " AND `tblDocuments`.`folder` = ". $folder->getID();
$queryStr .= " LIMIT 1";
$queryStr .= " ORDER BY `tblDocuments`.`id` DESC LIMIT 1";
$resArr = $this->db->getResultArray($queryStr);
if (is_bool($resArr) && !$resArr)
return false;
if(!$resArr)
return false;
return null;
$row = $resArr[0];
/** @var SeedDMS_Core_Document $document */
@ -912,7 +907,8 @@ class SeedDMS_Core_DMS {
* This function retrieves a document content from the database by its id.
*
* @param integer $id internal id of document content
* @return bool|SeedDMS_Core_Document or false
* @return bool|null|SeedDMS_Core_DocumentContent found document content or null if not document content was found or false in case of an error
*/
function getDocumentContent($id) { /* {{{ */
$classname = $this->classnames['documentcontent'];
@ -1820,6 +1816,8 @@ class SeedDMS_Core_DMS {
$tmp = explode('-', $param2, 3);
if(count($tmp) != 3)
return false;
if(!self::checkDate($param2, 'Y-m-d'))
return false;
$ts = mktime(0, 0, 0, $tmp[1], $tmp[2], $tmp[0]);
} else
$ts = mktime(0, 0, 0)-365*86400; /* Start of today - 1 year */
@ -1834,7 +1832,7 @@ class SeedDMS_Core_DMS {
}
$queryStr .=
"WHERE `tblDocuments`.`expires` > ".$startts." AND `tblDocuments`.`expires` < ".$endts." ";
"WHERE `tblDocuments`.`expires` >= ".$startts." AND `tblDocuments`.`expires` <= ".$endts." ";
$user = $param1;
$orderby = $param3;
@ -1958,7 +1956,7 @@ class SeedDMS_Core_DMS {
$queryStr = '';
}
break; // }}}
default:
default: // {{{
return false;
break; // }}}
}
@ -1993,21 +1991,17 @@ class SeedDMS_Core_DMS {
$month = (int) $month;
$day = (int) $day;
if (array_search($month, $thirtyone)) {
if(in_array($month, $thirtyone)) {
$max=31;
}
else if (array_search($month, $thirty)) {
} elseif(in_array($month, $thirty)) {
$max=30;
}
else {
} else {
$max=(($year % 4 == 0) && ($year % 100 != 0 || $year % 400 == 0)) ? 29 : 28;
}
// If the date falls out of bounds, set it to the maximum for the given
// month. Makes assumption about the user's intention, rather than failing
// for absolutely everything.
// Check again if day of month is valid in the given month
if ($day>$max) {
$day=$max;
return false;
}
return mktime($hour, $min, $sec, $month, $day, $year);
@ -2023,12 +2017,15 @@ class SeedDMS_Core_DMS {
* meanѕ that updateѕ of a document will only result in a searchable
* modification if a new version is uploaded.
*
* If the search is filtered by an expiration date, only documents with
* an expiration date will be found. Even if just an end date is given.
*
* @param string $query seach query with space separated words
* @param integer $limit number of items in result set
* @param integer $offset index of first item in result set
* @param string $logicalmode either AND or OR
* @param array $searchin list of fields to search in
* 1 = keywords, 2=name, 3=comment, 4=attributes
* 1 = keywords, 2=name, 3=comment, 4=attributes, 5=id
* @param SeedDMS_Core_Folder|null $startFolder search in the folder only (null for root folder)
* @param SeedDMS_Core_User $owner search for documents owned by this user
* @param array $status list of status
@ -2044,8 +2041,8 @@ class SeedDMS_Core_DMS {
* 0x1 = documents only
* 0x2 = folders only
* 0x3 = both
* @param array $expirationstartdate search for documents expiring after this date
* @param array $expirationenddate search for documents expiring before this date
* @param array $expirationstartdate search for documents expiring after and on this date
* @param array $expirationenddate search for documents expiring before and on this date
* @return array|bool
*/
function search($query, $limit=0, $offset=0, $logicalmode='AND', $searchin=array(), $startFolder=null, $owner=null, $status = array(), $creationstartdate=array(), $creationenddate=array(), $modificationstartdate=array(), $modificationenddate=array(), $categories=array(), $attributes=array(), $mode=0x3, $expirationstartdate=array(), $expirationenddate=array(), $reception=array()) { /* {{{ */
@ -2060,6 +2057,10 @@ class SeedDMS_Core_DMS {
${$paramname} = isset($query[$paramname]) ? $query[$paramname] : '';
$query = isset($query['query']) ? $query['query'] : '';
}
/* Ensure $logicalmode has a valid value */
if($logicalmode != 'OR')
$logicalmode = 'AND';
// Split the search string into constituent keywords.
$tkeys=array();
if (strlen($query)>0) {
@ -2414,8 +2415,6 @@ class SeedDMS_Core_DMS {
if ($expirationstartdate) {
$startdate = SeedDMS_Core_DMS::makeTimeStamp($expirationstartdate['hour'], $expirationstartdate['minute'], $expirationstartdate['second'], $expirationstartdate['year'], $expirationstartdate["month"], $expirationstartdate["day"]);
if ($startdate) {
if($searchExpirationDate)
$searchExpirationDate .= " AND ";
$searchExpirationDate .= "`tblDocuments`.`expires` >= ".$this->db->qstr($startdate);
}
}
@ -2424,6 +2423,8 @@ class SeedDMS_Core_DMS {
if ($stopdate) {
if($searchExpirationDate)
$searchExpirationDate .= " AND ";
else // do not find documents without an expiration date
$searchExpirationDate .= "`tblDocuments`.`expires` != 0 AND ";
$searchExpirationDate .= "`tblDocuments`.`expires` <= ".$this->db->qstr($stopdate);
}
}
@ -2653,28 +2654,9 @@ class SeedDMS_Core_DMS {
* @return SeedDMS_Core_Folder|boolean found folder or false
*/
function getFolderByName($name, $folder=null) { /* {{{ */
$name = trim($name);
$classname = $this->classnames['folder'];
return $classname::getInstanceByName($name, $folder, $this);
if (!$name) return false;
$queryStr = "SELECT * FROM `tblFolders` WHERE `name` = " . $this->db->qstr($name);
if($folder)
$queryStr .= " AND `parent` = ". $folder->getID();
$queryStr .= " LIMIT 1";
$resArr = $this->db->getResultArray($queryStr);
if (is_bool($resArr) && $resArr == false)
return false;
if(!$resArr)
return false;
$resArr = $resArr[0];
/** @var SeedDMS_Core_Folder $folder */
$folder = new $this->classnames['folder']($resArr["id"], $resArr["name"], $resArr["parent"], $resArr["comment"], $resArr["date"], $resArr["owner"], $resArr["inheritAccess"], $resArr["defaultAccess"], $resArr["sequence"]);
$folder->setDMS($this);
return $folder;
} /* }}} */
/**
@ -2699,7 +2681,27 @@ class SeedDMS_Core_DMS {
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 {
}
if(!isset($errors[$id])) {
/* Create the real folderList and compare it with the stored folderList */
$parent = $rec['parent'];
$fl = [];
while($parent) {
array_unshift($fl, $parent);
$parent = $cache[$parent]['parent'];
}
if($fl)
$flstr = ':'.implode(':', $fl).':';
else
$flstr = '';
if($flstr != $rec['folderList'])
$errors[$id] = array('id'=>$id, 'name'=>$rec['name'], 'parent'=>$rec['parent'], 'msg'=>'Wrong folder list '.$flstr.'!='.$rec['folderList']);
}
if(!isset($errors[$id])) {
/* This is the old insufficient test which will most likely not be called
* anymore, because the check for a wrong folder list will cache a folder
* list problem anyway.
*/
$tmparr = explode(':', $rec['folderList']);
array_shift($tmparr);
if(count($tmparr) != count(array_unique($tmparr))) {
@ -2744,7 +2746,21 @@ class SeedDMS_Core_DMS {
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 {
}
if(!isset($errors[$id])) {
/* Create the real folderList and compare it with the stored folderList */
$parent = $rec['parent'];
$fl = [];
while($parent) {
array_unshift($fl, $parent);
$parent = $fcache[$parent]['parent'];
}
if($fl)
$flstr = ':'.implode(':', $fl).':';
if($flstr != $rec['folderList'])
$errors[$id] = array('id'=>$id, 'name'=>$rec['name'], 'parent'=>$rec['parent'], 'msg'=>'Wrong folder list '.$flstr.'!='.$rec['folderList']);
}
if(!isset($errors[$id])) {
$tmparr = explode(':', $rec['folderList']);
array_shift($tmparr);
if(count($tmparr) != count(array_unique($tmparr))) {
@ -2855,7 +2871,7 @@ class SeedDMS_Core_DMS {
/* Check if 'onPostAddUser' callback is set */
if(isset($this->callbacks['onPostAddUser'])) {
foreach($this->callbacks['onPostUser'] as $callback) {
foreach($this->callbacks['onPostAddUser'] as $callback) {
/** @noinspection PhpStatementHasEmptyBodyInspection */
if(!call_user_func($callback[0], $callback[1], $user)) {
}
@ -2883,6 +2899,7 @@ class SeedDMS_Core_DMS {
* @return SeedDMS_Core_Group|boolean group or false if no group was found
*/
function getGroupByName($name) { /* {{{ */
$name = trim($name);
$classname = $this->classnames['group'];
return $classname::getInstance($name, $this, 'name');
} /* }}} */
@ -2906,6 +2923,7 @@ class SeedDMS_Core_DMS {
* case of an error.
*/
function addGroup($name, $comment) { /* {{{ */
$name = trim($name);
if (is_object($this->getGroupByName($name))) {
return false;
}
@ -3033,13 +3051,15 @@ class SeedDMS_Core_DMS {
} /* }}} */
function getKeywordCategory($id) { /* {{{ */
if (!is_numeric($id))
if (!is_numeric($id) || $id < 1)
return false;
$queryStr = "SELECT * FROM `tblKeywordCategories` WHERE `id` = " . (int) $id;
$resArr = $this->db->getResultArray($queryStr);
if ((is_bool($resArr) && !$resArr) || (count($resArr) != 1))
if (is_bool($resArr) && !$resArr)
return false;
if (count($resArr) != 1)
return null;
$resArr = $resArr[0];
$cat = new SeedDMS_Core_Keywordcategory($resArr["id"], $resArr["owner"], $resArr["name"]);
@ -3048,10 +3068,15 @@ class SeedDMS_Core_DMS {
} /* }}} */
function getKeywordCategoryByName($name, $userID) { /* {{{ */
if (!is_numeric($userID) || $userID < 1)
return false;
$name = trim($name);
$queryStr = "SELECT * FROM `tblKeywordCategories` WHERE `name` = " . $this->db->qstr($name) . " AND `owner` = " . (int) $userID;
$resArr = $this->db->getResultArray($queryStr);
if ((is_bool($resArr) && !$resArr) || (count($resArr) != 1))
if (is_bool($resArr) && !$resArr)
return false;
if (count($resArr) != 1)
return null;
$resArr = $resArr[0];
$cat = new SeedDMS_Core_Keywordcategory($resArr["id"], $resArr["owner"], $resArr["name"]);
@ -3061,8 +3086,11 @@ class SeedDMS_Core_DMS {
function getAllKeywordCategories($userIDs = array()) { /* {{{ */
$queryStr = "SELECT * FROM `tblKeywordCategories`";
if ($userIDs)
/* Ensure $userIDs() will only contain integers > 0 */
$userIDs = array_filter(array_unique(array_map('intval', $userIDs)), function($a) {return $a > 0;});
if ($userIDs) {
$queryStr .= " WHERE `owner` IN (".implode(',', $userIDs).")";
}
$resArr = $this->db->getResultArray($queryStr);
if (is_bool($resArr) && !$resArr)
@ -3080,29 +3108,22 @@ class SeedDMS_Core_DMS {
/**
* This function should be replaced by getAllKeywordCategories()
*
* @param $userID
* @return SeedDMS_Core_KeywordCategory[]|bool
*/
function getAllUserKeywordCategories($userID) { /* {{{ */
$queryStr = "SELECT * FROM `tblKeywordCategories`";
if ($userID != -1)
$queryStr .= " WHERE `owner` = " . (int) $userID;
$resArr = $this->db->getResultArray($queryStr);
if (is_bool($resArr) && !$resArr)
if (!is_numeric($userID) || $userID < 1)
return false;
$categories = array();
foreach ($resArr as $row) {
$cat = new SeedDMS_Core_KeywordCategory($row["id"], $row["owner"], $row["name"]);
$cat->setDMS($this);
array_push($categories, $cat);
}
return $categories;
return self::getAllKeywordCategories([$userID]);
} /* }}} */
function addKeywordCategory($userID, $name) { /* {{{ */
if (!is_numeric($userID) || $userID < 1)
return false;
$name = trim($name);
if(!$name)
return false;
if (is_object($this->getKeywordCategoryByName($name, $userID))) {
return false;
}
@ -3125,7 +3146,7 @@ class SeedDMS_Core_DMS {
} /* }}} */
function getDocumentCategory($id) { /* {{{ */
if (!is_numeric($id))
if (!is_numeric($id) || $id < 1)
return false;
$queryStr = "SELECT * FROM `tblCategory` WHERE `id` = " . (int) $id;
@ -3165,6 +3186,7 @@ class SeedDMS_Core_DMS {
* @return SeedDMS_Core_DocumentCategory|boolean instance of {@link SeedDMS_Core_DocumentCategory}
*/
function getDocumentCategoryByName($name) { /* {{{ */
$name = trim($name);
if (!$name) return false;
$queryStr = "SELECT * FROM `tblCategory` where `name`=".$this->db->qstr($name);
@ -3180,6 +3202,9 @@ class SeedDMS_Core_DMS {
} /* }}} */
function addDocumentCategory($name) { /* {{{ */
$name = trim($name);
if(!$name)
return false;
if (is_object($this->getDocumentCategoryByName($name))) {
return false;
}
@ -3316,6 +3341,7 @@ class SeedDMS_Core_DMS {
* @return SeedDMS_Core_AttributeDefinition|boolean instance of {@link SeedDMS_Core_AttributeDefinition} or false
*/
function getAttributeDefinitionByName($name) { /* {{{ */
$name = trim($name);
if (!$name) return false;
$queryStr = "SELECT * FROM `tblAttributeDefinitions` WHERE `name` = " . $this->db->qstr($name);
@ -3378,9 +3404,14 @@ class SeedDMS_Core_DMS {
* @return bool|SeedDMS_Core_User
*/
function addAttributeDefinition($name, $objtype, $type, $multiple=0, $minvalues=0, $maxvalues=1, $valueset='', $regex='') { /* {{{ */
$name = trim($name);
if(!$name)
return false;
if (is_object($this->getAttributeDefinitionByName($name))) {
return false;
}
if(!$objtype)
return false;
if(!$type)
return false;
if(trim($valueset)) {
@ -3435,9 +3466,12 @@ class SeedDMS_Core_DMS {
* Return workflow by its Id
*
* @param integer $id internal id of workflow
* @return SeedDMS_Core_Workflow|bool of instances of {@link SeedDMS_Core_Workflow} or false
* @return SeedDMS_Core_Workflow|bool of instances of {@link SeedDMS_Core_Workflow}, null if no workflow was found or false
*/
function getWorkflow($id) { /* {{{ */
if (!is_numeric($id))
return false;
$queryStr = "SELECT * FROM `tblWorkflows` WHERE `id`=".intval($id);
$resArr = $this->db->getResultArray($queryStr);
@ -3445,7 +3479,7 @@ class SeedDMS_Core_DMS {
return false;
if(!$resArr)
return false;
return null;
$initstate = $this->getWorkflowState($resArr[0]['initstate']);
@ -3459,9 +3493,10 @@ class SeedDMS_Core_DMS {
* Return workflow by its name
*
* @param string $name name of workflow
* @return SeedDMS_Core_Workflow|bool of instances of {@link SeedDMS_Core_Workflow} or false
* @return SeedDMS_Core_Workflow|bool of instances of {@link SeedDMS_Core_Workflow} or null if no workflow was found or false
*/
function getWorkflowByName($name) { /* {{{ */
$name = trim($name);
if (!$name) return false;
$queryStr = "SELECT * FROM `tblWorkflows` WHERE `name`=".$this->db->qstr($name);
@ -3471,7 +3506,7 @@ class SeedDMS_Core_DMS {
return false;
if(!$resArr)
return false;
return null;
$initstate = $this->getWorkflowState($resArr[0]['initstate']);
@ -3490,6 +3525,9 @@ class SeedDMS_Core_DMS {
*/
function addWorkflow($name, $initstate) { /* {{{ */
$db = $this->db;
$name = trim($name);
if(!$name)
return false;
if (is_object($this->getWorkflowByName($name))) {
return false;
}
@ -3516,8 +3554,11 @@ class SeedDMS_Core_DMS {
$queryStr = "SELECT * FROM `tblWorkflowStates` WHERE `id` = " . (int) $id;
$resArr = $this->db->getResultArray($queryStr);
if (is_bool($resArr) && $resArr == false) return false;
if (count($resArr) != 1) return false;
if (is_bool($resArr) && $resArr == false)
return false;
if (count($resArr) != 1)
return null;
$resArr = $resArr[0];
@ -3533,6 +3574,7 @@ class SeedDMS_Core_DMS {
* @return bool|SeedDMS_Core_Workflow_State or false
*/
function getWorkflowStateByName($name) { /* {{{ */
$name = trim($name);
if (!$name) return false;
$queryStr = "SELECT * FROM `tblWorkflowStates` WHERE `name`=".$this->db->qstr($name);
@ -3542,7 +3584,7 @@ class SeedDMS_Core_DMS {
return false;
if(!$resArr)
return false;
return null;
$resArr = $resArr[0];
@ -3583,6 +3625,9 @@ class SeedDMS_Core_DMS {
*/
function addWorkflowState($name, $docstatus) { /* {{{ */
$db = $this->db;
$name = trim($name);
if(!$name)
return false;
if (is_object($this->getWorkflowStateByName($name))) {
return false;
}
@ -3609,8 +3654,11 @@ class SeedDMS_Core_DMS {
$queryStr = "SELECT * FROM `tblWorkflowActions` WHERE `id` = " . (int) $id;
$resArr = $this->db->getResultArray($queryStr);
if (is_bool($resArr) && $resArr == false) return false;
if (count($resArr) != 1) return false;
if (is_bool($resArr) && $resArr == false)
return false;
if (count($resArr) != 1)
return null;
$resArr = $resArr[0];
@ -3628,13 +3676,17 @@ class SeedDMS_Core_DMS {
* @return SeedDMS_Core_Workflow_Action|bool instance of {@link SeedDMS_Core_Workflow_Action} or false
*/
function getWorkflowActionByName($name) { /* {{{ */
$name = trim($name);
if (!$name) return false;
$queryStr = "SELECT * FROM `tblWorkflowActions` WHERE `name` = " . $this->db->qstr($name);
$resArr = $this->db->getResultArray($queryStr);
if (is_bool($resArr) && $resArr == false) return false;
if (count($resArr) != 1) return false;
if (is_bool($resArr) && $resArr == false)
return false;
if (count($resArr) != 1)
return null;
$resArr = $resArr[0];
@ -3674,6 +3726,9 @@ class SeedDMS_Core_DMS {
*/
function addWorkflowAction($name) { /* {{{ */
$db = $this->db;
$name = trim($name);
if(!$name)
return false;
if (is_object($this->getWorkflowActionByName($name))) {
return false;
}
@ -3889,7 +3944,7 @@ class SeedDMS_Core_DMS {
function getDuplicateDocumentContent() { /* {{{ */
$queryStr = "SELECT a.*, b.`id` as dupid FROM `tblDocumentContent` a LEFT JOIN `tblDocumentContent` b ON a.`checksum`=b.`checksum` where a.`id`!=b.`id` ORDER by a.`id` LIMIT 1000";
$resArr = $this->db->getResultArray($queryStr);
if (!$resArr)
if ($resArr === false)
return false;
/** @var SeedDMS_Core_Document[] $versions */
@ -3939,13 +3994,13 @@ class SeedDMS_Core_DMS {
break;
}
/** @noinspection PhpUndefinedVariableInspection */
$queryStr .= " a LEFT JOIN `tblDocuments` b ON a.`documentID`=b.`id` where";
$queryStr .= " a LEFT JOIN `tblDocuments` b ON a.`documentID`=b.`id` WHERE";
switch($usergroup) {
case 'user':
$queryStr .= " a.`type`=0 and a.`required` not in (select `id` from `tblUsers`) ORDER by b.`id`";
$queryStr .= " a.`type`=0 and a.`required` not in (SELECT `id` FROM `tblUsers`) ORDER by b.`id`";
break;
case 'group':
$queryStr .= " a.`type`=1 and a.`required` not in (select `id` from `tblGroups`) ORDER by b.`id`";
$queryStr .= " a.`type`=1 and a.`required` not in (SELECT `id` FROM `tblGroups`) ORDER by b.`id`";
break;
}
return $this->db->getResultArray($queryStr);
@ -4007,58 +4062,60 @@ class SeedDMS_Core_DMS {
* documents or used space per user, recent activity, etc.
*
* @param string $type type of statistic
* @return array|bool
* @return array|bool returns false if the sql statement fails, returns an empty
* array if no documents or folder where found, otherwise returns a non empty
* array with statistical data
*/
function getStatisticalData($type='') { /* {{{ */
switch($type) {
case 'docsperuser':
$queryStr = "select ".$this->db->concat(array('b.`fullName`', "' ('", 'b.`login`', "')'"))." as `key`, count(`owner`) as total from `tblDocuments` a left join `tblUsers` b on a.`owner`=b.`id` group by `owner`, b.`fullName`";
$queryStr = "SELECT ".$this->db->concat(array('b.`fullName`', "' ('", 'b.`login`', "')'"))." AS `key`, count(`owner`) AS total FROM `tblDocuments` a LEFT JOIN `tblUsers` b ON a.`owner`=b.`id` GROUP BY `owner`, b.`fullName`";
$resArr = $this->db->getResultArray($queryStr);
if (!$resArr)
if(is_bool($resArr) && $resArr == false)
return false;
return $resArr;
case 'foldersperuser':
$queryStr = "select ".$this->db->concat(array('b.`fullName`', "' ('", 'b.`login`', "')'"))." as `key`, count(`owner`) as total from `tblFolders` a left join `tblUsers` b on a.`owner`=b.`id` group by `owner`, b.`fullName`";
$queryStr = "SELECT ".$this->db->concat(array('b.`fullName`', "' ('", 'b.`login`', "')'"))." AS `key`, count(`owner`) AS total FROM `tblFolders` a LEFT JOIN `tblUsers` b ON a.`owner`=b.`id` GROUP BY `owner`, b.`fullName`";
$resArr = $this->db->getResultArray($queryStr);
if (!$resArr)
if(is_bool($resArr) && $resArr == false)
return false;
return $resArr;
case 'docspermimetype':
$queryStr = "select b.`mimeType` as `key`, count(`mimeType`) as total from `tblDocuments` a left join `tblDocumentContent` b on a.`id`=b.`document` group by b.`mimeType`";
$queryStr = "SELECT b.`mimeType` AS `key`, count(`mimeType`) AS total FROM `tblDocuments` a LEFT JOIN `tblDocumentContent` b ON a.`id`=b.`document` GROUP BY b.`mimeType`";
$resArr = $this->db->getResultArray($queryStr);
if (!$resArr)
if(is_bool($resArr) && $resArr == false)
return false;
return $resArr;
case 'docspercategory':
$queryStr = "select b.`name` as `key`, count(a.`categoryID`) as total from `tblDocumentCategory` a left join `tblCategory` b on a.`categoryID`=b.id group by a.`categoryID`, b.`name`";
$queryStr = "SELECT b.`name` AS `key`, count(a.`categoryID`) AS total FROM `tblDocumentCategory` a LEFT JOIN `tblCategory` b ON a.`categoryID`=b.id GROUP BY a.`categoryID`, b.`name`";
$resArr = $this->db->getResultArray($queryStr);
if (!$resArr)
if(is_bool($resArr) && $resArr == false)
return false;
return $resArr;
case 'docsperstatus':
/** @noinspection PhpUnusedLocalVariableInspection */
$queryStr = "select b.`status` as `key`, count(b.`status`) as total from (select a.id, max(b.version), max(c.`statusLogID`) as maxlog from `tblDocuments` a left join `tblDocumentStatus` b on a.id=b.`documentID` left join `tblDocumentStatusLog` c on b.`statusID`=c.`statusID` group by a.`id`, b.`version` order by a.`id`, b.`statusID`) a left join `tblDocumentStatusLog` b on a.`maxlog`=b.`statusLogID` group by b.`status`";
$queryStr = "select b.`status` as `key`, count(b.`status`) as total from (select a.`id`, max(c.`statusLogID`) as maxlog from `tblDocuments` a left join `tblDocumentStatus` b on a.id=b.`documentID` left join `tblDocumentStatusLog` c on b.`statusID`=c.`statusID` group by a.`id` order by a.id) a left join `tblDocumentStatusLog` b on a.maxlog=b.`statusLogID` group by b.`status`";
$queryStr = "SELECT b.`status` AS `key`, count(b.`status`) AS total FROM (SELECT a.id, max(b.version), max(c.`statusLogID`) AS maxlog FROM `tblDocuments` a LEFT JOIN `tblDocumentStatus` b ON a.id=b.`documentID` LEFT JOIN `tblDocumentStatusLog` c ON b.`statusID`=c.`statusID` GROUP BY a.`id`, b.`version` ORDER BY a.`id`, b.`statusID`) a LEFT JOIN `tblDocumentStatusLog` b ON a.`maxlog`=b.`statusLogID` GROUP BY b.`status`";
$queryStr = "SELECT b.`status` AS `key`, count(b.`status`) AS total FROM (SELECT a.`id`, max(c.`statusLogID`) AS maxlog FROM `tblDocuments` a LEFT JOIN `tblDocumentStatus` b ON a.id=b.`documentID` LEFT JOIN `tblDocumentStatusLog` c ON b.`statusID`=c.`statusID` GROUP BY a.`id` ORDER BY a.id) a LEFT JOIN `tblDocumentStatusLog` b ON a.maxlog=b.`statusLogID` GROUP BY b.`status`";
$resArr = $this->db->getResultArray($queryStr);
if (!$resArr)
if(is_bool($resArr) && $resArr == false)
return false;
return $resArr;
case 'docspermonth':
$queryStr = "select *, count(`key`) as total from (select ".$this->db->getDateExtract("date", '%Y-%m')." as `key` from `tblDocuments`) a group by `key` order by `key`";
$queryStr = "SELECT *, count(`key`) AS total FROM (SELECT ".$this->db->getDateExtract("date", '%Y-%m')." AS `key` FROM `tblDocuments`) a GROUP BY `key` ORDER BY `key`";
$resArr = $this->db->getResultArray($queryStr);
if (!$resArr)
if(is_bool($resArr) && $resArr == false)
return false;
return $resArr;
case 'docsaccumulated':
$queryStr = "select *, count(`key`) as total from (select ".$this->db->getDateExtract("date")." as `key` from `tblDocuments`) a group by `key` order by `key`";
$queryStr = "SELECT *, count(`key`) AS total FROM (SELECT ".$this->db->getDateExtract("date")." AS `key` FROM `tblDocuments`) a GROUP BY `key` ORDER BY `key`";
$resArr = $this->db->getResultArray($queryStr);
if (!$resArr)
if(is_bool($resArr) && $resArr == false)
return false;
$sum = 0;
@ -4072,9 +4129,9 @@ class SeedDMS_Core_DMS {
}
return $resArr;
case 'sizeperuser':
$queryStr = "select ".$this->db->concat(array('c.`fullName`', "' ('", 'c.`login`', "')'"))." as `key`, sum(`fileSize`) as total from `tblDocuments` a left join `tblDocumentContent` b on a.id=b.`document` left join `tblUsers` c on a.`owner`=c.`id` group by a.`owner`, c.`fullName`";
$queryStr = "SELECT ".$this->db->concat(array('c.`fullName`', "' ('", 'c.`login`', "')'"))." AS `key`, sum(`fileSize`) AS total FROM `tblDocuments` a LEFT JOIN `tblDocumentContent` b ON a.id=b.`document` LEFT JOIN `tblUsers` c ON a.`owner`=c.`id` GROUP BY a.`owner`, c.`fullName`";
$resArr = $this->db->getResultArray($queryStr);
if (!$resArr)
if(is_bool($resArr) && $resArr == false)
return false;
return $resArr;
@ -4127,62 +4184,55 @@ class SeedDMS_Core_DMS {
/**
* Set a callback function
*
* The function passed in $func must be a callable and $name may not be empty.
*
* Setting a callback with the method will remove all priorly set callbacks.
*
* @param string $name internal name of callback
* @param mixed $func function name as expected by {call_user_method}
* @param mixed $params parameter passed as the first argument to the
* callback
* @return bool true if adding the callback succeeds otherwise false
*/
function setCallback($name, $func, $params=null) { /* {{{ */
if($name && $func)
if($name && $func && is_callable($func)) {
$this->callbacks[$name] = array(array($func, $params));
return true;
} else {
return false;
}
} /* }}} */
/**
* Add a callback function
*
* The function passed in $func must be a callable and $name may not be empty.
*
* @param string $name internal name of callback
* @param mixed $func function name as expected by {call_user_method}
* @param mixed $params parameter passed as the first argument to the
* callback
* @return bool true if adding the callback succeeds otherwise false
*/
function addCallback($name, $func, $params=null) { /* {{{ */
if($name && $func)
if($name && $func && is_callable($func)) {
$this->callbacks[$name][] = array($func, $params);
return true;
} else {
return false;
}
} /* }}} */
/**
* Create an sql dump of the complete database
* Check if a callback with the given has been set
*
* @param string $filename name of dump file
* @return bool
* @param string $name internal name of callback
* @return bool true a callback exists otherwise false
*/
function createDump($filename) { /* {{{ */
$h = fopen($filename, "w");
if(!$h)
return false;
$tables = $this->db->TableList('TABLES');
foreach($tables as $table) {
$query = "SELECT * FROM `".$table."`";
$records = $this->db->getResultArray($query);
fwrite($h,"\n-- TABLE: ".$table."--\n\n");
foreach($records as $record) {
$values="";
$i = 1;
foreach ($record as $column) {
if (is_numeric($column)) $values .= $column;
else $values .= $this->db->qstr($column);
if ($i<(count($record))) $values .= ",";
$i++;
}
fwrite($h, "INSERT INTO `".$table."` VALUES (".$values.");\n");
}
}
fclose($h);
return true;
function hasCallback($name) { /* {{{ */
if($name && !empty($this->callbacks[$name]))
return true;
return false;
} /* }}} */
}

View File

@ -1922,6 +1922,7 @@ class SeedDMS_Core_Document extends SeedDMS_Core_Object { /* {{{ */
$docResultSet->addReviewer($reviewer, $i, $res);
// If no error is returned, or if the error is just due to email
// failure, mark the state as "pending review".
// FIXME: There seems to be no error code -4 anymore
if ($res==0 || $res=-3 || $res=-4) {
$pendingReview=true;
}
@ -1938,6 +1939,7 @@ class SeedDMS_Core_Document extends SeedDMS_Core_Object { /* {{{ */
$approver=($i=="i" ? $this->_dms->getUser($approverID) : $this->_dms->getGroup($approverID));
$res=($i=="i" ? $docResultSet->getContent()->addIndApprover($approver, $user, true) : $docResultSet->getContent()->addGrpApprover($approver, $user, !$pendingReview));
$docResultSet->addApprover($approver, $i, $res);
// FIXME: There seems to be no error code -4 anymore
if ($res==0 || $res=-3 || $res=-4) {
$pendingApproval=true;
}
@ -4644,6 +4646,9 @@ class SeedDMS_Core_DocumentContent extends SeedDMS_Core_Object { /* {{{ */
} /* }}} */
function addIndReviewer($user, $requestUser) { /* {{{ */
if(!$user || !$requestUser)
return -1;
$db = $this->_document->getDMS()->getDB();
$userID = $user->getID();
@ -4911,6 +4916,9 @@ class SeedDMS_Core_DocumentContent extends SeedDMS_Core_Object { /* {{{ */
} /* }}} */
function addIndApprover($user, $requestUser) { /* {{{ */
if(!$user || !$requestUser)
return -1;
$db = $this->_document->getDMS()->getDB();
$userID = $user->getID();

View File

@ -79,22 +79,22 @@ class SeedDMS_Core_Folder extends SeedDMS_Core_Object {
protected $_date;
/**
* @var SeedDMS_Core_Folder
* @var SeedDMS_Core_Folder cached parent folder
*/
protected $_parent;
/**
* @var SeedDMS_Core_User
* @var SeedDMS_Core_User cached owner of folder
*/
protected $_owner;
/**
* @var SeedDMS_Core_Folder[]
* @var SeedDMS_Core_Folder[] cached array of sub folders
*/
protected $_subFolders;
/**
* @var SeedDMS_Core_Document[]
* @var SeedDMS_Core_Document[] cache array of child documents
*/
protected $_documents;
@ -126,7 +126,26 @@ class SeedDMS_Core_Folder extends SeedDMS_Core_Object {
$this->_inheritAccess = $inheritAccess;
$this->_defaultAccess = $defaultAccess;
$this->_sequence = $sequence;
$this->_notifyList = array();
$this->_notifyList = array();
/* Cache */
$this->clearCache();
} /* }}} */
/**
* Clear cache of this instance.
*
* The result of some expensive database actions (e.g. get all subfolders
* or documents) will be saved in a class variable to speed up consecutive
* calls of the same method. If a second call of the same method shall not
* use the cache, then it must be cleared.
*
*/
public function clearCache() { /* {{{ */
$this->_parent = null;
$this->_owner = null;
$this->_subFolders = null;
$this->_documents = null;
$this->_accessList = null;
} /* }}} */
/**
@ -244,7 +263,7 @@ class SeedDMS_Core_Folder extends SeedDMS_Core_Object {
return false;
if(!$resArr)
return false;
return null;
return self::getInstanceByData($resArr[0], $dms);
} /* }}} */
@ -321,7 +340,7 @@ class SeedDMS_Core_Folder extends SeedDMS_Core_Object {
} /* }}} */
/**
* Set creation date of the document
* Set creation date of the folder
*
* @param integer $date timestamp of creation date. If false then set it
* to the current timestamp
@ -330,7 +349,7 @@ class SeedDMS_Core_Folder extends SeedDMS_Core_Object {
function setDate($date) { /* {{{ */
$db = $this->_dms->getDB();
if(!$date)
if($date === false)
$date = time();
else {
if(!is_numeric($date))
@ -347,11 +366,12 @@ class SeedDMS_Core_Folder extends SeedDMS_Core_Object {
/**
* Returns the parent
*
* @return bool|SeedDMS_Core_Folder
* @return null|bool|SeedDMS_Core_Folder returns null, if there is no parent folder
* and false in case of an error
*/
public function getParent() { /* {{{ */
if ($this->_id == $this->_dms->rootFolderID || empty($this->_parentID)) {
return false;
return null;
}
if (!isset($this->_parent)) {
@ -363,11 +383,15 @@ class SeedDMS_Core_Folder extends SeedDMS_Core_Object {
/**
* Check if the folder is subfolder
*
* This function checks if the passed folder is a subfolder of the current
* folder.
* This method checks if the current folder is in the path of the
* passed subfolder. In that case the current folder is a parent,
* grant parent, grant grant parent, etc. of the subfolder or
* to say it differently the passed folder is somewhere below the
* current folder.
*
* @param SeedDMS_Core_Folder $subfolder
* @return bool true if passes folder is a subfolder
* @param SeedDMS_Core_Folder $subfolder folder to be checked if it is
* a subfolder on any level of the current folder
* @return bool true if passed folder is a subfolder, otherwise false
*/
function isSubFolder($subfolder) { /* {{{ */
$target_path = $subfolder->getPath();
@ -442,7 +466,7 @@ class SeedDMS_Core_Folder extends SeedDMS_Core_Object {
$res = $db->getResult($queryStr);
}
/* Update path in folderList for all documents */
/* Update path in folderList for all folders */
$queryStr = "SELECT `tblFolders`.`id`, `tblFolders`.`folderList` FROM `tblFolders` WHERE `folderList` LIKE '%:".$this->_id.":%'";
$resArr = $db->getResultArray($queryStr);
if (is_bool($resArr) && $resArr == false)
@ -593,7 +617,7 @@ class SeedDMS_Core_Folder extends SeedDMS_Core_Object {
if (is_bool($resArr) && !$resArr)
return false;
return $resArr[0]['c'];
return (int) $resArr[0]['c'];
} /* }}} */
/**
@ -800,7 +824,7 @@ class SeedDMS_Core_Folder extends SeedDMS_Core_Object {
if (is_bool($resArr) && !$resArr)
return false;
return $resArr[0]['c'];
return (int) $resArr[0]['c'];
} /* }}} */
/**
@ -1464,7 +1488,7 @@ class SeedDMS_Core_Folder extends SeedDMS_Core_Object {
/* Administrators have unrestricted access */
if ($user->isAdmin()) return M_ALL;
/* The owner of the document has unrestricted access */
/* The owner of the folder has unrestricted access */
if ($user->getID() == $this->_ownerID) return M_ALL;
/* Check ACLs */
@ -2014,6 +2038,22 @@ class SeedDMS_Core_Folder extends SeedDMS_Core_Object {
return $resArr[0];
} /* }}} */
/**
* Get the min and max sequence value for folders
*
* @return bool|array array with keys 'min' and 'max', false in case of an error
*/
function getFoldersMinMax() { /* {{{ */
$db = $this->_dms->getDB();
$queryStr = "SELECT min(`sequence`) AS `min`, max(`sequence`) AS `max` FROM `tblFolders` WHERE `parent` = " . (int) $this->_id;
$resArr = $db->getResultArray($queryStr);
if (is_bool($resArr) && $resArr == false)
return false;
return $resArr[0];
} /* }}} */
}
?>

View File

@ -288,7 +288,7 @@ class SeedDMS_Core_Group { /* {{{ */
* set to true, otherwise does not care about manager status
* @return boolean true if user is member, otherwise false
*/
function isMember($user,$asManager=false) { /* {{{ */
function isMember($user, $asManager=false) { /* {{{ */
if (isset($this->_users)&&!$asManager) {
foreach ($this->_users as $usr)
if ($usr->getID() == $user->getID())
@ -297,8 +297,9 @@ class SeedDMS_Core_Group { /* {{{ */
}
$db = $this->_dms->getDB();
if ($asManager) $queryStr = "SELECT * FROM `tblGroupMembers` WHERE `groupID` = " . $this->_id . " AND `userID` = " . $user->getID() . " AND `manager` = 1";
else $queryStr = "SELECT * FROM `tblGroupMembers` WHERE `groupID` = " . $this->_id . " AND `userID` = " . $user->getID();
$queryStr = "SELECT * FROM `tblGroupMembers` WHERE `groupID` = " . $this->_id . " AND `userID` = " . $user->getID();
if ($asManager)
$queryStr .= " AND `manager` = 1";
$resArr = $db->getResultArray($queryStr);

View File

@ -245,21 +245,21 @@ class SeedDMS_Core_User { /* {{{ */
*
* @access protected
*/
var $_id;
protected $_id;
/**
* @var string login name of user
*
* @access protected
*/
var $_login;
protected $_login;
/**
* @var string password of user as saved in database (md5)
*
* @access protected
*/
var $_pwd;
protected $_pwd;
/**
* @var string secret of user for 2-factor authentication
@ -273,21 +273,21 @@ class SeedDMS_Core_User { /* {{{ */
*
* @access protected
*/
var $_pwdExpiration;
protected $_pwdExpiration;
/**
* @var string full human readable name of user
*
* @access protected
*/
var $_fullName;
protected $_fullName;
/**
* @var string email address of user
*
* @access protected
*/
var $_email;
protected $_email;
/**
* @var string prefered language of user
@ -295,21 +295,21 @@ class SeedDMS_Core_User { /* {{{ */
*
* @access protected
*/
var $_language;
protected $_language;
/**
* @var string preselected theme of user
*
* @access protected
*/
var $_theme;
protected $_theme;
/**
* @var string comment of user
*
* @access protected
*/
var $_comment;
protected $_comment;
/**
* @var string role of user. Can be one of SeedDMS_Core_User::role_user,
@ -317,35 +317,35 @@ class SeedDMS_Core_User { /* {{{ */
*
* @access protected
*/
var $_role;
protected $_role;
/**
* @var boolean true if user shall be hidden
*
* @access protected
*/
var $_isHidden;
protected $_isHidden;
/**
* @var boolean true if user is disabled
*
* @access protected
*/
var $_isDisabled;
protected $_isDisabled;
/**
* @var int number of login failures
*
* @access protected
*/
var $_loginFailures;
protected $_loginFailures;
/**
* @var SeedDMS_Core_Folder home folder
*
* @access protected
*/
var $_homeFolder;
protected $_homeFolder;
/**
* @var array list of users this user can substitute
@ -366,17 +366,21 @@ class SeedDMS_Core_User { /* {{{ */
*
* @access protected
*/
var $_dms;
protected $_dms;
/**
* @var int
*
* @access protected
*/
private $_quota;
protected $_quota;
/**
* @var bool
*
* @access protected
*/
private $_hasImage;
protected $_hasImage;
const role_user = '0';
const role_admin = '1';
@ -411,8 +415,8 @@ class SeedDMS_Core_User { /* {{{ */
$this->_theme = $theme;
$this->_comment = $comment;
$this->_role = $role;
$this->_isHidden = $isHidden;
$this->_isDisabled = $isDisabled;
$this->_isHidden = (bool) $isHidden;
$this->_isDisabled = (bool) $isDisabled;
$this->_pwdExpiration = $pwdExpiration;
$this->_loginFailures = $loginFailures;
$this->_quota = $quota;
@ -535,6 +539,10 @@ class SeedDMS_Core_User { /* {{{ */
* @return bool
*/
function setLogin($newLogin) { /* {{{ */
$newLogin = trim($newLogin);
if(!$newLogin)
return false;
$db = $this->_dms->getDB();
$queryStr = "UPDATE `tblUsers` SET `login` =".$db->qstr($newLogin)." WHERE `id` = " . $this->_id;
@ -620,9 +628,10 @@ class SeedDMS_Core_User { /* {{{ */
function setPwdExpiration($newPwdExpiration) { /* {{{ */
$db = $this->_dms->getDB();
if(trim($newPwdExpiration) == '' || trim($newPwdExpiration) == 'never')
if(trim($newPwdExpiration) == '' || trim($newPwdExpiration) == 'never') {
$newPwdExpiration = null;
$queryStr = "UPDATE `tblUsers` SET `pwdExpiration` = NULL WHERE `id` = " . $this->_id;
elseif(trim($newPwdExpiration) == 'now')
} elseif(trim($newPwdExpiration) == 'now')
$queryStr = "UPDATE `tblUsers` SET `pwdExpiration` =".$db->qstr(date('Y-m-d H:i:s'))." WHERE `id` = " . $this->_id;
else
$queryStr = "UPDATE `tblUsers` SET `pwdExpiration` =".$db->qstr($newPwdExpiration)." WHERE `id` = " . $this->_id;
@ -780,7 +789,7 @@ class SeedDMS_Core_User { /* {{{ */
} /* }}} */
/**
* @return bool|int
* @return bool
*/
function isHidden() { return $this->_isHidden; }
@ -792,11 +801,11 @@ class SeedDMS_Core_User { /* {{{ */
$db = $this->_dms->getDB();
$isHidden = ($isHidden) ? "1" : "0";
$queryStr = "UPDATE `tblUsers` SET `hidden` = " . $isHidden . " WHERE `id` = " . $this->_id;
$queryStr = "UPDATE `tblUsers` SET `hidden` = " . intval($isHidden) . " WHERE `id` = " . $this->_id;
if (!$db->getResult($queryStr))
return false;
$this->_isHidden = $isHidden;
$this->_isHidden = (bool) $isHidden;
return true;
} /* }}} */
@ -813,11 +822,11 @@ class SeedDMS_Core_User { /* {{{ */
$db = $this->_dms->getDB();
$isDisabled = ($isDisabled) ? "1" : "0";
$queryStr = "UPDATE `tblUsers` SET `disabled` = " . $isDisabled . " WHERE `id` = " . $this->_id;
$queryStr = "UPDATE `tblUsers` SET `disabled` = " . intval($isDisabled) . " WHERE `id` = " . $this->_id;
if (!$db->getResult($queryStr))
return false;
$this->_isDisabled = $isDisabled;
$this->_isDisabled = (bool) $isDisabled;
return true;
} /* }}} */
@ -878,6 +887,11 @@ class SeedDMS_Core_User { /* {{{ */
* @return bool
*/
function setQuota($quota) { /* {{{ */
if (!is_numeric($quota))
return false;
if($quota < 0)
return false;
$db = $this->_dms->getDB();
$quota = intval($quota);
@ -1465,7 +1479,8 @@ class SeedDMS_Core_User { /* {{{ */
/**
* Get the image from the users profile
*
* @return array|bool image data
* @return string|null|bool image data as a string or null if no image is set or
* false in case of an error
*/
function getImage() { /* {{{ */
$db = $this->_dms->getDB();
@ -1476,8 +1491,9 @@ class SeedDMS_Core_User { /* {{{ */
return false;
if($resArr)
$resArr = $resArr[0];
return $resArr;
return $resArr[0];
else
return null;
} /* }}} */
/**

View File

@ -1,317 +0,0 @@
<?php
/**
* Implementation of database access
*
* @category DMS
* @package SeedDMS_Core
* @license GPL 2
* @version @version@
* @author Uwe Steinmann <uwe@steinmann.cx>
* @copyright Copyright (C) 2002-2005 Markus Westphal, 2006-2008 Malcolm Cowe,
* 2010 Matteo Lucarelli, 2010 Uwe Steinmann
* @version Release: @package_version@
*/
/**
* Include the adodb database abstraction
*/
require_once "adodb/adodb.inc.php";
/** @noinspection PhpUndefinedClassInspection */
/**
* Class to represent the database access for the document management
*
* @category DMS
* @package SeedDMS_Core
* @author Markus Westphal, Malcolm Cowe, Matteo Lucarelli, Uwe Steinmann <uwe@steinmann.cx>
* @copyright Copyright (C) 2002-2005 Markus Westphal, 2006-2008 Malcolm Cowe, 2010 Matteo Lucarelli, 2010 Uwe Steinmann
* @version Release: @package_version@
*/
class SeedDMS_Core_DatabaseAccess {
var $_debug;
var $_driver;
var $_hostname;
var $_database;
var $_user;
var $_passw;
var $_conn;
var $_connected;
var $_ttreviewid;
var $_ttapproveid;
var $_ttstatid;
var $_ttcontentid;
var $_intransaction;
/*
Backup functions
*/
/**
* Return list of all database tables
*
* This function is used to retrieve a list of database tables for backup
*
* @return array list of table names
*/
function TableList() {
return $this->_conn->MetaTables("TABLES");
}
/**
* Constructor of SeedDMS_Core_DatabaseAccess
*
* Sets all database parameters but does not connect.
*
* @param string $driver the database type e.g. mysql, sqlite
* @param string $hostname host of database server
* @param string $user name of user having access to database
* @param string $passw password of user
* @param bool|string $database name of database
*/
function __construct($driver, $hostname, $user, $passw, $database = false) {
$this->_driver = $driver;
$this->_hostname = $hostname;
$this->_database = $database;
$this->_user = $user;
$this->_passw = $passw;
$this->_connected = false;
$this->_intransaction = 0;
// $tt*****id is a hack to ensure that we do not try to create the
// temporary table twice during a single connection. Can be fixed by
// using Views (MySQL 5.0 onward) instead of temporary tables.
// CREATE ... IF NOT EXISTS cannot be used because it has the
// unpleasant side-effect of performing the insert again even if the
// table already exists.
//
// See createTemporaryTable() method for implementation.
$this->_ttreviewid = false;
$this->_ttapproveid = false;
$this->_ttstatid = false;
$this->_ttcontentid = false;
$this->_debug = false;
}
/**
* Connect to database
*
* @return boolean true if connection could be established, otherwise false
*/
function connect() { /* {{{ */
$this->_conn = ADONewConnection($this->_driver);
if ($this->_database)
$this->_conn->Connect($this->_hostname, $this->_user, $this->_passw, $this->_database);
else
$this->_conn->Connect($this->_hostname, $this->_user, $this->_passw);
if (!$this->_conn)
return false;
$this->_conn->SetFetchMode(ADODB_FETCH_ASSOC);
$this->_conn->Execute('SET NAMES utf8');
$this->_connected = true;
return true;
} /* }}} */
/**
* Make sure a database connection exisits
*
* This function checks for a database connection. If it does not exists
* it will reconnect.
*
* @return boolean true if connection is established, otherwise false
*/
function ensureConnected() { /* {{{ */
if (!$this->_connected) return $this->connect();
else return true;
} /* }}} */
/**
* Sanitize String used in database operations
*
* @param string $text
* @return string sanitized string
*/
function qstr($text) { /* {{{ */
return $this->_conn->qstr($text);
} /* }}} */
/**
* Execute SQL query and return result
*
* Call this function only with sql query which return data records.
*
* @param string $queryStr sql query
* @return array|boolean data if query could be executed otherwise false
*/
function getResultArray($queryStr) { /* {{{ */
/** @noinspection PhpUnusedLocalVariableInspection */
$resArr = array();
$res = $this->_conn->Execute($queryStr);
if (!$res) {
if($this->_debug)
echo "error: ".$queryStr."<br />";
return false;
}
$resArr = $res->GetArray();
$res->Close();
return $resArr;
} /* }}} */
/**
* Execute SQL query
*
* Call this function only with sql query which do not return data records.
*
* @param string $queryStr sql query
* @return bool true if query could be executed otherwise false
* @internal param bool $silent not used anymore. This was used when this method
* still issued an error message
*/
function getResult($queryStr) { /* {{{ */
$res = $this->_conn->Execute($queryStr);
if(!$res) {
if($this->_debug)
echo "error: ".$queryStr."<br />";
}
return $res;
} /* }}} */
/**
* Return the id of the last instert record
*
* @return integer id used in last autoincrement
*/
function getInsertID() { /* {{{ */
return $this->_conn->Insert_ID();
} /* }}} */
function startTransaction() { /* {{{ */
if(!$this->_intransaction) {
$this->_conn->BeginTrans();
}
$this->_intransaction++;
} /* }}} */
function rollbackTransaction() { /* {{{ */
if($this->_intransaction == 1) {
$this->_conn->RollbackTrans();
}
$this->_intransaction--;
} /* }}} */
function commitTransaction() { /* {{{ */
if($this->_intransaction == 1) {
$this->_conn->CommitTrans();
}
$this->_intransaction--;
} /* }}} */
function getErrorMsg() { /* {{{ */
return $this->_conn->ErrorMsg();
} /* }}} */
function getErrorNo() { /* {{{ */
return $this->_conn->ErrorNo();
} /* }}} */
/**
* Create various temporary tables to speed up and simplify sql queries
* @param $tableName
* @param bool $override
* @return bool
*/
function createTemporaryTable($tableName, $override=false) { /* {{{ */
if (!strcasecmp($tableName, "ttreviewid")) {
$queryStr = "CREATE TEMPORARY TABLE IF NOT EXISTS `ttreviewid` (PRIMARY KEY (`reviewID`), INDEX (`maxLogID`)) ".
"SELECT `tblDocumentReviewLog`.`reviewID`, ".
"MAX(`tblDocumentReviewLog`.`reviewLogID`) AS `maxLogID` ".
"FROM `tblDocumentReviewLog` ".
"GROUP BY `tblDocumentReviewLog`.`reviewID` ".
"ORDER BY `tblDocumentReviewLog`.`reviewLogID`";
if (!$this->_ttreviewid) {
if (!$this->getResult($queryStr))
return false;
$this->_ttreviewid=true;
}
else {
if (is_bool($override) && $override) {
if (!$this->getResult("DELETE FROM `ttreviewid`"))
return false;
if (!$this->getResult($queryStr))
return false;
}
}
return $this->_ttreviewid;
}
else if (!strcasecmp($tableName, "ttapproveid")) {
$queryStr = "CREATE TEMPORARY TABLE IF NOT EXISTS `ttapproveid` (PRIMARY KEY (`approveID`), INDEX (`maxLogID`)) ".
"SELECT `tblDocumentApproveLog`.`approveID`, ".
"MAX(`tblDocumentApproveLog`.`approveLogID`) AS `maxLogID` ".
"FROM `tblDocumentApproveLog` ".
"GROUP BY `tblDocumentApproveLog`.`approveID` ".
"ORDER BY `tblDocumentApproveLog`.`approveLogID`";
if (!$this->_ttapproveid) {
if (!$this->getResult($queryStr))
return false;
$this->_ttapproveid=true;
}
else {
if (is_bool($override) && $override) {
if (!$this->getResult("DELETE FROM `ttapproveid`"))
return false;
if (!$this->getResult($queryStr))
return false;
}
}
return $this->_ttapproveid;
}
else if (!strcasecmp($tableName, "ttstatid")) {
$queryStr = "CREATE TEMPORARY TABLE IF NOT EXISTS `ttstatid` (PRIMARY KEY (`statusID`), INDEX (`maxLogID`)) ".
"SELECT `tblDocumentStatusLog`.`statusID`, ".
"MAX(`tblDocumentStatusLog`.`statusLogID`) AS `maxLogID` ".
"FROM `tblDocumentStatusLog` ".
"GROUP BY `tblDocumentStatusLog`.`statusID` ".
"ORDER BY `tblDocumentStatusLog`.`statusLogID`";
if (!$this->_ttstatid) {
if (!$this->getResult($queryStr))
return false;
$this->_ttstatid=true;
}
else {
if (is_bool($override) && $override) {
if (!$this->getResult("DELETE FROM `ttstatid`"))
return false;
if (!$this->getResult($queryStr))
return false;
}
}
return $this->_ttstatid;
}
else if (!strcasecmp($tableName, "ttcontentid")) {
$queryStr = "CREATE TEMPORARY TABLE `ttcontentid` (PRIMARY KEY (`document`), INDEX (`maxVersion`)) ".
"SELECT `tblDocumentContent`.`document`, ".
"MAX(`tblDocumentContent`.`version`) AS `maxVersion` ".
"FROM `tblDocumentContent` ".
"GROUP BY `tblDocumentContent`.`document` ".
"ORDER BY `tblDocumentContent`.`document`";
if (!$this->_ttcontentid) {
if (!$this->getResult($queryStr))
return false;
$this->_ttcontentid=true;
}
else {
if (is_bool($override) && $override) {
if (!$this->getResult("DELETE FROM `ttcontentid`"))
return false;
if (!$this->getResult($queryStr))
return false;
}
}
return $this->_ttcontentid;
}
return false;
} /* }}} */
}

View File

@ -1096,4 +1096,33 @@ class SeedDMS_Core_DatabaseAccess {
}
return $field;
} /* }}} */
/**
* Create an sql dump of the complete database
*
* @param resource $fp name of dump file
* @return bool
*/
function createDump($fp) { /* {{{ */
$tables = $this->TableList('TABLES');
foreach($tables as $table) {
$query = "SELECT * FROM `".$table."`";
$records = $this->getResultArray($query);
fwrite($fp,"\n-- TABLE: ".$table."--\n\n");
foreach($records as $record) {
$values="";
$i = 1;
foreach ($record as $column) {
if (is_numeric($column)) $values .= $column;
else $values .= $this->qstr($column);
if ($i<(count($record))) $values .= ",";
$i++;
}
fwrite($fp, "INSERT INTO `".$table."` VALUES (".$values.");\n");
}
}
return true;
} /* }}} */
}

View File

@ -12,7 +12,7 @@
<email>uwe@steinmann.cx</email>
<active>yes</active>
</lead>
<date>2021-09-09</date>
<date>2021-09-22</date>
<time>13:44:55</time>
<version>
<release>6.0.17</release>
@ -24,7 +24,7 @@
</stability>
<license uri="http://opensource.org/licenses/gpl-license">GPL License</license>
<notes>
???
- all changes from 5.1.24
</notes>
<contents>
<dir baseinstalldir="SeedDMS" name="/">
@ -1928,6 +1928,17 @@ add method SeedDMS_Core_DatabaseAccess::setLogFp()
<license uri="http://opensource.org/licenses/gpl-license">GPL License</license>
<notes>
- in SeedDMS_Core_DocumentContent::removeWorkflow() remove records from tblWorklflowLog before tblDWorkflowDocumentContent
- make all class variables of SeedDMS_Core_User protected
- fix various errors in SeedDMS_Core_AttributeDefinition::validate()
- add lots of unit tests
- replace incorrect use of array_search() by in_array()
- move method SeedDMS_Core_DMS::createDump() into SeedDMS_Core_DatabaseAccess
- lots of parameter checking when calling methods()
- make sure callbacks are callable
- SeedDMS_Core_Folder::getParent() returns null if there is no parent (used to be false)
- SeedDMS_Core_DMS::search() will not find document without an expiration date anymore, if the search is limited by an expiration end date but no start date
- add method SeedDMS_Core_Folder::getFoldersMinMax()
- init internal cache variables of SeedDMS_Core_Folder and add method clearCache()
</notes>
</release>
<release>

View File

@ -115,16 +115,16 @@
- restricted: Restricted access: only allow users to log in if they have an entry in the local database (irrespective of successful authentication with LDAP).
- enableUserImage: enable users images
- disableSelfEdit: if true user cannot edit his own profile
- passwordStrength: XXX
- passwordStrengthAlgorithm: XXX
- passwordExpiration: XXX
- passwordHistory: XXX
- loginFailure: XXX
- autoLoginUser: XXX
- quota: XXX
- undelUserIds: XXX
- encryptionKey: XXX
- cookieLifetime: XXX
- passwordStrength: minimum strength of password, set to 0 to disable
- passwordStrengthAlgorithm: algorithm used to calculate password strenght (simple or advanced)
- passwordExpiration: number of days after password expires
- passwordHistory: number of remembered passwords
- loginFailure: maximum allowed login failures before an account is disabled
- autoLoginUser: id of user used if auto login is turned on
- quota: maximum allowed space on disc for each user
- undelUserIds: ids of users which cannot be deleted
- encryptionKey: arbitrary string used for creating form tokens
- cookieLifetime: lifetime of cookie in seconds, set to 0 for session cookies
-->
<authentication
enableGuestLogin = "false"
@ -188,7 +188,6 @@
</connectors>
</authentication>
<!--
- ADOdbPath: Path to adodb. This is the directory containing the adodb directory
- dbDriver: DB-Driver used by adodb (see adodb-readme)
- dbHostname: DB-Server
- dbDatabase: database where the tables for seeddms are stored (optional - see adodb-readme)
@ -197,7 +196,6 @@
- doNotCheckVersion: Whether or not to check the database schema for its correct version.
-->
<database
ADOdbPath = ""
dbDriver = "_DBC_DBTYPE_"
dbHostname = "_DBC_DBSERVER_"
dbDatabase = "_DBC_DBNAME_"
@ -209,8 +207,8 @@
- smtpServer: SMTP Server hostname
- smtpPort: SMTP Server port
- smtpSendFrom: Send from
- smtpUser: XXX
- smtpPassword: XXX
- smtpUser: user name used for authenticating against smtp server
- smtpPassword: password used for authenticating against smtp server
-->
<smtp
smtpServer = "localhost"
@ -224,7 +222,7 @@
<!--
-siteDefaultPage: Default page on login. Defaults to out/out.ViewFolder.php
- rootFolderID: ID of root-folder (mostly no need to change)
- showMissingTranslations: XXX
- showMissingTranslations: set true if missing translation shall be listed at end of page
-->
<display
siteDefaultPage = ""
@ -247,10 +245,10 @@
- enableVersionModification: allow to modify versions after approval
- enableDuplicateDocNames: allow duplicate names in a folder
- enableDuplicateSubFolderNames: allow duplicate names in a folder
- enableOwnerRevApp: XXX
- enableSelfRevApp: XXX
- presetExpirationDate: XXX
- overrideMimeType: XXX
- enableOwnerRevApp: allow owner of a document to review and approve
- enableSelfRevApp: allow the user current logged in to add herself as a reviewer or approver
- presetExpirationDate: set to time period if each document shall expire
- overrideMimeType: set to true if the mimetype of a document version is determined by the server
-->
<edition
enableAdminRevApp = "false"
@ -275,9 +273,9 @@
- be any number or string that does not already exist within $_contentDir.
- maxDirID: Maximum number of sub-directories per parent directory. Default: 0.
- updateNotifyTime: users are notified about document-changes that took place within the last "updateNotifyTime" seconds
- extraPath: XXX
- maxExecutionTime: XXX
- cmdTimeout: XXX
- extraPath: additional path which is added to php's include path
- maxExecutionTime: maximum script execution time, this cannot be larger than the value set in php.ini
- cmdTimeout: timeout in sec. for external commands
-->
<server
coreDir = ""
@ -290,9 +288,9 @@
cmdTimeout = "10"
/>
<!--
- enableNotificationAppRev: XXX
- enableNotificationAppRev: set to true if reviewers and approvers shall be informed about a pending review/approval
- enableOwnerNotification: XXX
- enableNotificationWorkflow: XXX
- enableNotificationWorkflow: set to true if the users in the workflow shall be informed
-->
<notification
enableNotificationAppRev = "true"

View File

@ -78,6 +78,7 @@ class SeedDMS_Controller_AttributeMgr extends SeedDMS_Controller_Common {
return false;
}
if (!$attrdef->setRegex($regex)) {
$this->errormsg = 'attrdef_invalid_regex';
return false;
}

View File

@ -8,13 +8,13 @@ SeedDMS is a web-based application written in PHP. It uses MySQL,
SQLite3 or PostgreSQL to manage the documents that were uploaded into
the application. Be aware that PostgreSQL is not very well tested.
Make sure you have PHP >= 7.2 and MySQL 5 or higher installed. SeedDMS
Make sure you have PHP >= 7.3 and MySQL 5 or higher installed. SeedDMS
will work with PHP running in CGI-mode as well as running as a module under
apache.
Here is a detailed list of requirements:
1. A web server with at least php 7.2
1. A web server with at least php 7.3
2. A mysql database, unless you use SQLite
3. The php installation must have support for `pdo_mysql`, `pdo_pgsql` or `pdo_sqlite`,
`php_gd2`, `php_mbstring`, `php_xml`

View File

@ -2,38 +2,52 @@
/**
* Implementation of user authentication
*
* @category DMS
* @package SeedDMS
* @license GPL 2
* @version @version@
* @author Uwe Steinmann <uwe@steinmann.cx>
* @copyright Copyright (C) 2010-2016 Uwe Steinmann
* @version Release: @package_version@
* @category DMS
* @package SeedDMS
* @author Uwe Steinmann <uwe@steinmann.cx>
* @copyright 2010-2016 Uwe Steinmann
* @license GPL 2
* @version @package_version@
* @link https://www.seeddms.org
*/
/**
* Abstract class to authenticate user
*
* @category DMS
* @package SeedDMS
* @author Uwe Steinmann <uwe@steinmann.cx>
* @copyright Copyright (C) 2010-2016 Uwe Steinmann
* @version Release: @package_version@
* @category DMS
* @package SeedDMS
* @author Uwe Steinmann <uwe@steinmann.cx>
* @copyright 2010-2016 Uwe Steinmann
* @license GPL 2
* @version Release: @package_version@
* @link https://www.seeddms.org
*/
abstract class SeedDMS_Authentication {
abstract class SeedDMS_Authentication
{
/**
* @var object $dms object of dms
* DMS object
*
* @var SeedDMS_Core_DMS
* @access protected
*/
private $dms;
protected $dms;
/**
* @var object $settings SeedDMS Settings
* DMS settings
*
* @var Settings
* @access protected
*/
private $settings;
protected $settings;
function __construct($dms, $settings) { /* {{{ */
/**
* Constructor
*
* @param SeedDMS_Core_DMS $dms DMS object
* @param Settings $settings DMS settings
*/
function __construct($dms, $settings) /* {{{ */
{
$this->dms = $dms;
$this->settings = $settings;
} /* }}} */
@ -45,9 +59,11 @@ abstract class SeedDMS_Authentication {
* the user object otherwise false must be returned. If authentication fails
* the number of failed logins should be incremented and account disabled.
*
* @param string $username
* @param string $password
* @return object|boolean user object if authentication was successful otherwise false
* @param string $username name of user to authenticate
* @param string $password password of user to authenticate
*
* @return object|false user object if authentication was successful
* otherwise false
*/
abstract function authenticate($username, $password);
}

View File

@ -23,22 +23,6 @@ require_once "inc.ClassAuthentication.php";
* @version Release: @package_version@
*/
class SeedDMS_DbAuthentication extends SeedDMS_Authentication {
/**
* @var object $dms object of dms
* @access protected
*/
private $dms;
/**
* @var object $settings SeedDMS Settings
* @access protected
*/
private $settings;
function __construct($dms, $settings) { /* {{{ */
$this->dms = $dms;
$this->settings = $settings;
} /* }}} */
/**
* Do Authentication

View File

@ -2,13 +2,13 @@
/**
* Implementation of user authentication
*
* @category DMS
* @package SeedDMS
* @license GPL 2
* @version @version@
* @author Uwe Steinmann <uwe@steinmann.cx>
* @copyright Copyright (C) 2010-2016 Uwe Steinmann
* @version Release: @package_version@
* @category DMS
* @package SeedDMS
* @author Uwe Steinmann <uwe@steinmann.cx>
* @license GPL 2
* @version @version@
* @copyright 2010-2016 Uwe Steinmann
* @version Release: @package_version@
*/
require_once "inc.ClassAuthentication.php";
@ -16,29 +16,13 @@ require_once "inc.ClassAuthentication.php";
/**
* Abstract class to authenticate user against ldap server
*
* @category DMS
* @package SeedDMS
* @author Uwe Steinmann <uwe@steinmann.cx>
* @copyright Copyright (C) 2010-2016 Uwe Steinmann
* @version Release: @package_version@
* @category DMS
* @package SeedDMS
* @author Uwe Steinmann <uwe@steinmann.cx>
* @copyright 2010-2016 Uwe Steinmann
* @version Release: @package_version@
*/
class SeedDMS_LdapAuthentication extends SeedDMS_Authentication {
/**
* @var object $dms object of dms
* @access protected
*/
private $dms;
/**
* @var object $settings SeedDMS Settings
* @access protected
*/
private $settings;
function __construct($dms, $settings) { /* {{{ */
$this->dms = $dms;
$this->settings = $settings;
} /* }}} */
/**
* Do ldap authentication
@ -53,8 +37,8 @@ class SeedDMS_LdapAuthentication extends SeedDMS_Authentication {
* authentication. If that succeeds the user is logged in. If the user doesn't
* exist in the database, it will be created.
*
* @param string $username
* @param string $password
* @param string $username name of user to authenticate
* @param string $password password of user to authenticate
* @return object|boolean user object if authentication was successful otherwise false
*/
public function authenticate($username, $password) { /* {{{ */

View File

@ -88,6 +88,9 @@ class Settings { /* {{{ */
// list of form fields which are visible by default but can be explixitly
// turn off (comment, keywords, categories, sequence, expiration, owner
var $_noDocumentFormFields = array();
// list of form fields which are visible by default but can be explixitly
// turn off (comment, keywords, categories, sequence, expiration, owner
var $_noFolderFormFields = array();
// Path to where SeedDMS is located
var $_rootDir = null;
// Path to SeedDMS_Core
@ -547,6 +550,8 @@ class Settings { /* {{{ */
$this->_inlineEditing = Settings::boolVal($tab["inlineEditing"]);
if(trim(strval($tab["noDocumentFormFields"])))
$this->_noDocumentFormFields = explode(',',strval($tab["noDocumentFormFields"]));
if(trim(strval($tab["noFolderFormFields"])))
$this->_noFolderFormFields = explode(',',strval($tab["noFolderFormFields"]));
$this->setViewOnlineFileTypesFromString(strval($tab["viewOnlineFileTypes"]));
$this->setEditOnlineFileTypesFromString(strval($tab["editOnlineFileTypes"]));
$this->_enableConverting = Settings::boolVal($tab["enableConverting"]);
@ -943,6 +948,7 @@ class Settings { /* {{{ */
$this->setXMLAttributValue($node, "strictFormCheck", $this->_strictFormCheck);
$this->setXMLAttributValue($node, "inlineEditing", $this->_inlineEditing);
$this->setXMLAttributValue($node, "noDocumentFormFields", implode(',', $this->_noDocumentFormFields));
$this->setXMLAttributValue($node, "noFolderFormFields", implode(',', $this->_noFolderFormFields));
$this->setXMLAttributValue($node, "viewOnlineFileTypes", $this->getViewOnlineFileTypesToString());
$this->setXMLAttributValue($node, "editOnlineFileTypes", $this->getEditOnlineFileTypesToString());
$this->setXMLAttributValue($node, "enableConverting", $this->_enableConverting);

View File

@ -57,9 +57,6 @@ if(!$settings->_doNotCheckDBVersion && !$dms->checkVersion()) {
$dms->setRootFolderID($settings->_rootFolderID);
$dms->setMaxDirID($settings->_maxDirID);
$dms->setEnableConverting($settings->_enableConverting);
$dms->setViewOnlineFileTypes($settings->_viewOnlineFileTypes);
//$dms->noReadForStatus = array(S_DRAFT, S_DRAFT_REV/*, S_DRAFT_APP*/);
if(isset($GLOBALS['SEEDDMS_HOOKS']['initDMS'])) {
foreach($GLOBALS['SEEDDMS_HOOKS']['initDMS'] as $hookObj) {

View File

@ -1007,7 +1007,7 @@ CREATE TABLE `tblVersion` (
INSERT INTO `tblRoles` (`id`, `name`, `role`) VALUES (1, 'Admin', 1);
INSERT INTO `tblRoles` (`id`, `name`, `role`) VALUES (2, 'Guest', 2);
INSERT INTO `tblRoles` (`id`, `name`, `role`) VALUES (3, 'User', 0);
INSERT INTO tblUsers VALUES (1, 'admin', '21232f297a57a5a743894a0e4a801fc3', '', 'Administrator', 'address@server.com', '', '', '', 1, 0, NULL, 0, 0, 0, NULL);
INSERT INTO tblUsers VALUES (1, 'admin', '21232f297a57a5a743894a0e4a801fc3', '', 'Administrator', 'info@seeddms.org', '', '', '', 1, 0, NULL, 0, 0, 0, NULL);
INSERT INTO tblUsers VALUES (2, 'guest', NULL, '', 'Guest User', NULL, '', '', '', 2, 0, NULL, 0, 0, 0, NULL);
INSERT INTO tblFolders VALUES (1, 'DMS', 0, '', 'DMS root', UNIX_TIMESTAMP(), 1, 0, 2, 0);
INSERT INTO tblVersion VALUES (NOW(), 6, 0, 0);

View File

@ -824,7 +824,7 @@ INSERT INTO "tblRoles" ("id", "name", "role") VALUES (2, 'Guest', 2);
SELECT nextval('"tblRoles_id_seq"');
INSERT INTO "tblRoles" ("id", "name", "role") VALUES (3, 'User', 0);
SELECT nextval('"tblRoles_id_seq"');
INSERT INTO "tblUsers" VALUES (1, 'admin', '21232f297a57a5a743894a0e4a801fc3', '', 'Administrator', 'address@server.com', '', '', '', 1, 0, NULL, 0, 0, 0, NULL);
INSERT INTO "tblUsers" VALUES (1, 'admin', '21232f297a57a5a743894a0e4a801fc3', 'Administrator', 'info@seeddms.org', '', '', '', 1, 0, NULL, 0, 0, 0, NULL);
SELECT nextval('"tblUsers_id_seq"');
INSERT INTO "tblUsers" VALUES (2, 'guest', NULL, '', 'Guest User', NULL, '', '', '', 2, 0, NULL, 0, 0, 0, NULL);
SELECT nextval('"tblUsers_id_seq"');

View File

@ -830,7 +830,7 @@ CREATE TABLE `tblVersion` (
INSERT INTO `tblRoles` (`id`, `name`, `role`) VALUES (1, 'Admin', 1);
INSERT INTO `tblRoles` (`id`, `name`, `role`) VALUES (2, 'Guest', 2);
INSERT INTO `tblRoles` (`id`, `name`, `role`) VALUES (3, 'User', 0);
INSERT INTO `tblUsers` VALUES (1, 'admin', '21232f297a57a5a743894a0e4a801fc3', '', 'Administrator', 'address@server.com', '', '', '', 1, 0, '', 0, 0, 0, 0);
INSERT INTO `tblUsers` VALUES (2, 'guest', NULL, '', 'Guest User', NULL, '', '', '', 2, 0, '', 0, 0, 0, 0);
INSERT INTO `tblFolders` VALUES (1, 'DMS', 0, '', 'DMS root', strftime('%s','now'), 1, 0, 2, 0);
INSERT INTO `tblUsers` (`id`, `login`, `pwd`, `fullName`, `email`, `language`, `theme`, `comment`, `role`, `hidden`, `pwdExpiration`, `loginfailures`, `disabled`, `quota`, `homefolder`) VALUES (1, 'admin', '21232f297a57a5a743894a0e4a801fc3', 'Administrator', 'info@seeddms.org', '', '', '', 1, 0, '', 0, 0, 0, NULL);
INSERT INTO `tblUsers` (`id`, `login`, `pwd`, `fullName`, `email`, `language`, `theme`, `comment`, `role`, `hidden`, `pwdExpiration`, `loginfailures`, `disabled`, `quota`, `homefolder`) VALUES (2, 'guest', NULL, 'Guest User', NULL, '', '', '', 2, 0, '', 0, 0, 0, NULL);
INSERT INTO `tblFolders` (`id`, `name`, `parent`, `folderList`, `comment`, `date`, `owner`, `inheritAccess`, `defaultAccess`, `sequence`) VALUES (1, 'DMS', NULL, '', 'DMS root', strftime('%s','now'), 1, 0, 2, 0);
INSERT INTO `tblVersion` VALUES (DATETIME(), 6, 0, 0);

View File

@ -163,7 +163,11 @@ else if ($action == "editattrdef") {
$controller->setParam('regex', $regex);
$controller->setParam('attrdef', $attrdef);
if (!$controller($_POST)) {
UI::exitError(getMLText("admin_tools"),getMLText("error_occured"));
if ($controller->getErrorMsg() != '')
$errormsg = $controller->getErrorMsg();
else
$errormsg = "error_occured";
UI::exitError(getMLText("admin_tools"),getMLText($errormsg));
}
$session->setSplashMsg(array('type'=>'success', 'msg'=>getMLText('splash_edit_attribute')));

View File

@ -37,8 +37,14 @@ if (!$settings->_backupDir) {
$v = new SeedDMS_Version;
$dump_name = addDirSep($settings->_backupDir).date('Y-m-d\TH-i-s')."_".$v->version().".sql";
if(!$dms->createDump($dump_name))
$fp = fopen($dump_name, "w");
if(!$fp)
UI::exitError(getMLText("admin_tools"),getMLText("error_occured"));
if(!$dms->getDb()->createDump($fp)) {
fclose($fp);
UI::exitError(getMLText("admin_tools"),getMLText("error_occured"));
}
fclose($fp);
if (SeedDMS_Core_File::gzcompressfile($dump_name,9)) unlink($dump_name);
else UI::exitError(getMLText("admin_tools"),getMLText("error_occured"));

View File

@ -120,6 +120,7 @@ if ($action == "saveSettings")
setBoolValue('strictFormCheck');
setBoolValue('inlineEditing');
setArrayValue('noDocumentFormFields');
setArrayValue('noFolderFormFields');
if(isset($_POST['viewOnlineFileTypes']) && !in_array('viewOnlineFileTypes', $settings->_hiddenConfFields))
$settings->setViewOnlineFileTypesFromString($_POST["viewOnlineFileTypes"]);
if(isset($_POST['editOnlineFileTypes']) && !in_array('editOnlineFileTypes', $settings->_hiddenConfFields))

View File

@ -52,7 +52,8 @@ if ($folder->getAccessMode($user) < M_READWRITE) {
if($view) {
$view->setParam('folder', $folder);
$view->setParam('strictformcheck', $settings->_strictFormCheck);
$view->setParam('defaultposition', $settings->_defaultDocPosition);
$view->setParam('nofolderformfields', $settings->_noFolderFormFields);
$view->setParam('defaultposition', $settings->_defaultFolderPosition);
$view->setParam('orderby', $settings->_sortFoldersDefault);
$view->setParam('accessobject', $accessop);
$view($_GET);

View File

@ -55,6 +55,7 @@ if($view) {
$view->setParam('folder', $folder);
$view->setParam('attrdefs', $attrdefs);
$view->setParam('strictformcheck', $settings->_strictFormCheck);
$view->setParam('nofolderformfields', $settings->_noFolderFormFields);
$view->setParam('rootfolderid', $settings->_rootFolderID);
$view->setParam('orderby', $settings->_sortFoldersDefault);
$view->setParam('accessobject', $accessop);

View File

@ -63,6 +63,7 @@ if($view) {
$view->setParam('workflowmode', $settings->_workflowMode);
$view->setParam('timeout', $settings->_cmdTimeout);
$view->setParam('accessobject', $accessop);
$view->setParam('sortusersinlist', $settings->_sortUsersInList);
$view->setParam('xsendfile', $settings->_enableXsendfile);
$view($_GET);
}

View File

@ -52,6 +52,7 @@ $(document).ready( function() {
$user = $this->params['user'];
$folder = $this->params['folder'];
$strictformcheck = $this->params['strictformcheck'];
$nofolderformfields = $this->params['nofolderformfields'];
$orderby = $this->params['orderby'];
$this->htmlAddHeader('<script type="text/javascript" src="../views/'.$this->theme.'/vendors/jquery-validation/jquery.validate.js"></script>'."\n", 'js');
@ -85,6 +86,7 @@ $(document).ready( function() {
'required'=>true
)
);
if(!$nofolderformfields || !in_array('comment', $nofolderformfields))
$this->formField(
getMLText("comment"),
array(
@ -95,7 +97,25 @@ $(document).ready( function() {
'required'=>$strictformcheck
)
);
$this->formField(getMLText("sequence"), $this->getSequenceChooser($folder->getSubFolders('s')).($orderby != 's' ? "<br />".getMLText('order_by_sequence_off') : ''));
if(!$nofolderformfields || !in_array('sequence', $nofolderformfields)) {
$this->formField(getMLText("sequence"), $this->getSequenceChooser($folder->getSubFolders('s')).($orderby != 's' ? "<br />".getMLText('order_by_sequence_off') : ''));
} else {
$minmax = $folder->getFoldersMinMax();
if($this->params['defaultposition'] == 'start') {
$seq = $minmax['min'] - 1;
} else {
$seq = $minmax['max'] + 1;
}
$this->formField(
null,
array(
'element'=>'input',
'type'=>'hidden',
'name'=>'sequence',
'value'=>(string) $seq,
)
);
}
$attrdefs = $dms->getAllAttributeDefinitions(array(SeedDMS_Core_AttributeDefinition::objtype_folder, SeedDMS_Core_AttributeDefinition::objtype_all));
if($attrdefs) {
@ -130,6 +150,9 @@ $(document).ready( function() {
}
$this->contentContainerEnd();
/* FIXME: add section for adding notifications like in AddDocument */
$this->formSubmit("<i class=\"fa fa-save\"></i> ".getMLText('add_subfolder'));
?>
</form>

View File

@ -308,6 +308,7 @@ $(document).ready( function() {
'element'=>'input',
'type'=>'text',
'name'=>'regex',
'placeholder'=>'/[0-9]+abc.-*/',
'value'=>($attrdef ? $attrdef->getRegex() : ''),
),
['help'=>getMLText('attrdef_regex_help')]

View File

@ -54,6 +54,7 @@ $(document).ready(function() {
$attrdefs = $this->params['attrdefs'];
$rootfolderid = $this->params['rootfolderid'];
$strictformcheck = $this->params['strictformcheck'];
$nofolderformfields = $this->params['nofolderformfields'];
$orderby = $this->params['orderby'];
$this->htmlAddHeader('<script type="text/javascript" src="../views/'.$this->theme.'/vendors/jquery-validation/jquery.validate.js"></script>'."\n", 'js');
@ -81,22 +82,35 @@ $(document).ready(function() {
'required'=>true
)
);
$this->formField(
getMLText("comment"),
array(
'element'=>'textarea',
'name'=>'comment',
'rows'=>4,
'cols'=>80,
'value'=>htmlspecialchars($folder->getComment()),
'required'=>$strictformcheck
)
);
$parent = ($folder->getID() == $rootfolderid) ? false : $folder->getParent();
if ($parent && $parent->getAccessMode($user) > M_READ) {
$this->formField(getMLText("sequence"), $this->getSequenceChooser($parent->getSubFolders('s'), $folder->getID()).($orderby != 's' ? "<br />".getMLText('order_by_sequence_off') : ''));
if(!$nofolderformfields || !in_array('comment', $nofolderformfields)) {
$this->formField(
getMLText("comment"),
array(
'element'=>'textarea',
'name'=>'comment',
'rows'=>4,
'cols'=>80,
'value'=>htmlspecialchars($folder->getComment()),
'required'=>$strictformcheck
)
);
} else {
$this->formField(
null,
array(
'element'=>'input',
'type'=>'hidden',
'name'=>'comment',
'value'=>htmlspecialchars($folder->getComment()),
)
);
}
$parent = ($folder->getID() == $rootfolderid) ? false : $folder->getParent();
if(!$nofolderformfields || !in_array('sequence', $nofolderformfields)) {
if ($parent && $parent->getAccessMode($user) > M_READ) {
$this->formField(getMLText("sequence"), $this->getSequenceChooser($parent->getSubFolders('s'), $folder->getID()).($orderby != 's' ? "<br />".getMLText('order_by_sequence_off') : ''));
}
}
if($attrdefs) {
foreach($attrdefs as $attrdef) {
$arr = $this->callHook('editFolderAttribute', $folder, $attrdef);

View File

@ -156,6 +156,7 @@ $(document).ready( function() {
$user = $this->params['user'];
$allUsers = $this->params['allusers'];
$groups = $this->params['allgroups'];
$sortusersinlist = $this->params['sortusersinlist'];
?>
<form class="form-horizontal" action="../op/op.GroupMgr.php" name="form_1" id="form_1" method="post">
<?php

View File

@ -337,6 +337,7 @@ $this->showStartPaneContent('site', (!$currenttab || $currenttab == 'site'));
<?php $this->showConfigCheckbox('settings_strictFormCheck', 'strictFormCheck'); ?>
<?php $this->showConfigCheckbox('settings_inlineEditing', 'inlineEditing'); ?>
<?php $this->showConfigOption('settings_noDocumentFormFields', 'noDocumentFormFields', array('comment', 'keywords', 'categories', 'sequence', 'expires', 'version', 'version_comment', 'notification'), true, true); ?>
<?php $this->showConfigOption('settings_noFolderFormFields', 'noFolderFormFields', array('comment', 'sequence', 'notification'), true, true); ?>
<?php $this->showConfigText('settings_viewOnlineFileTypes', 'viewOnlineFileTypes', 'array'); ?>
<?php $this->showConfigText('settings_editOnlineFileTypes', 'editOnlineFileTypes', 'array'); ?>
<?php $this->showConfigCheckbox('settings_enableConverting', 'enableConverting'); ?>
@ -373,6 +374,7 @@ if(($kkk = $this->callHook('getFullSearchEngine')) && is_array($kkk))
<?php $this->showConfigOption('settings_sortUsersInList', 'sortUsersInList', array(' '=>'settings_sortUsersInList_val_login', 'fullname'=>'settings_sortUsersInList_val_fullname'), false, true); ?>
<?php $this->showConfigOption('settings_sortFoldersDefault', 'sortFoldersDefault', array('u'=>'settings_sortFoldersDefault_val_unsorted', 's'=>'settings_sortFoldersDefault_val_sequence', 'n'=>'settings_sortFoldersDefault_val_name'), false, true); ?>
<?php $this->showConfigOption('settings_defaultDocPosition', 'defaultDocPosition', array('end'=>'settings_defaultDocPosition_val_end', 'start'=>'settings_defaultDocPosition_val_start'), false, true); ?>
<?php $this->showConfigOption('settings_defaultFolderPosition', 'defaultFolderPosition', array('end'=>'settings_defaultDocPosition_val_end', 'start'=>'settings_defaultDocPosition_val_start'), false, true); ?>
<?php $this->showConfigFolder('settings_libraryFolder', 'libraryFolder'); ?>
<!--

View File

@ -56,7 +56,7 @@ class SeedDMS_View_UsrView extends SeedDMS_Theme_Style {
if ($currUser->isGuest())
continue;
if ($currUser->isHidden()=="1") continue;
if ($currUser->isHidden()) continue;
echo "<tr>";
if($enableuserimage) {