diff --git a/CHANGELOG b/CHANGELOG
index 601a21d5a..3d07c996c 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,10 @@
+--------------------------------------------------------------------------------
+ Changes in version 5.0.1
+--------------------------------------------------------------------------------
+- merged changes from 4.3.24
+- fixed sending test mail
+- fixed sending password forgotten mail
+
--------------------------------------------------------------------------------
Changes in version 5.0.0
--------------------------------------------------------------------------------
@@ -6,6 +13,21 @@
- add .xml to online file types by default
- add home folder for users
+--------------------------------------------------------------------------------
+ Changes in version 4.3.24
+--------------------------------------------------------------------------------
+- fixed possible XSS attack in user substitution
+- users can have mor than one mandatory workflow, in that case the user can select one
+- completed MyDocuments page for advanced workflows
+- guest user can be automatically logged in
+- get/set custom attributes by webdav, better handling of different attribute types
+- default search method can be set (fulltext, database)
+- further pages with content security policy turned on
+- various translation updates
+- check for document expiration when showing search result and folder content
+- more rest api functions
+- do not send notification mails to disabled users
+
--------------------------------------------------------------------------------
Changes in version 4.3.23
--------------------------------------------------------------------------------
diff --git a/Makefile b/Makefile
index c1d281546..fc7467e68 100644
--- a/Makefile
+++ b/Makefile
@@ -1,5 +1,5 @@
-VERSION=5.0.0
-SRC=CHANGELOG inc conf utils index.php languages views op out controllers README.md README.Notification README.Ubuntu drop-tables-innodb.sql styles js TODO LICENSE Makefile webdav install restapi
+VERSION=5.0.1
+SRC=CHANGELOG inc conf utils index.php languages views op out controllers doc drop-tables-innodb.sql styles js TODO LICENSE Makefile webdav install restapi
# webapp
EXTENSIONS := \
diff --git a/SeedDMS_Core/Core/inc.ClassAttribute.php b/SeedDMS_Core/Core/inc.ClassAttribute.php
index 84a3f9b8b..e9578302d 100644
--- a/SeedDMS_Core/Core/inc.ClassAttribute.php
+++ b/SeedDMS_Core/Core/inc.ClassAttribute.php
@@ -117,7 +117,7 @@ class SeedDMS_Core_Attribute { /* {{{ */
/**
* Return attribute values as an array
*
- * This function returns the attribute value as an array. Such an array
+ * This function returns the attribute value as an array. The array
* has one element for non multi value attributes and n elements for
* multi value attributes.
*
@@ -133,14 +133,67 @@ class SeedDMS_Core_Attribute { /* {{{ */
/**
* Set a value of an attribute
- * The attribute is deleted completely if the value is the empty string
*
- * @param string $value value to be set
+ * The attribute is completely deleted if the value is an empty string
+ * or empty array. An array of values is only allowed if the attribute may
+ * have multiple values. If an array is passed and the attribute may
+ * have only a single value, then the first element of the array will
+ * be taken.
+ *
+ * @param string $values value as string or array to be set
* @return boolean true if operation was successfull, otherwise false
*/
- function setValue($value) { /* {{{*/
+ function setValue($values) { /* {{{*/
$db = $this->_dms->getDB();
+ if($this->_attrdef->getMultipleValues()) {
+ /* Multiple values without a value set is not allowed */
+ if(!$valuesetstr = $this->_attrdef->getValueSet())
+ return false;
+ $valueset = $this->_attrdef->getValueSetAsArray();
+
+ if(is_array($values)) {
+ if($values) {
+ $error = false;
+ foreach($values as $v) {
+ if(!in_array($v, $valueset)) { $error = true; break; }
+ }
+ if($error)
+ return false;
+ $valuesetstr = $this->_attrdef->getValueSet();
+ $value = $valuesetstr[0].implode($valuesetstr[0], $values);
+ } else {
+ $value = '';
+ }
+ } else {
+ if($values) {
+ if($valuesetstr[0] != $values[0])
+ $values = explode($valuesetstr[0], $values);
+ else
+ $values = explode($valuesetstr[0], substr($values, 1));
+
+ $error = false;
+ foreach($values as $v) {
+ if(!in_array($v, $valueset)) { $error = true; break; }
+ }
+ if($error)
+ return false;
+ $value = $valuesetstr[0].implode($valuesetstr[0], $values);
+ } else {
+ $value = $values;
+ }
+ }
+ } else {
+ if(is_array($values)) {
+ if($values)
+ $value = $values[0];
+ else
+ $value = '';
+ } else {
+ $value = $values;
+ }
+ }
+
switch(get_class($this->_obj)) {
case $this->_dms->getClassname('document'):
if(trim($value) === '')
@@ -524,6 +577,12 @@ class SeedDMS_Core_AttributeDefinition { /* {{{ */
/**
* Get the value set as saved in the database
*
+ * This is a string containing the list of valueѕ separated by a
+ * delimiter which also precedes the whole string, e.g. '|Yes|No'
+ *
+ * Use {@link SeedDMS_Core_AttributeDefinition::getValueSetAsArray()}
+ * for a list of values returned as an array.
+ *
* @return string value set
*/
function getValueSet() { /* {{{ */
@@ -540,7 +599,7 @@ class SeedDMS_Core_AttributeDefinition { /* {{{ */
if(strlen($this->_valueset) > 1)
return explode($this->_valueset[0], substr($this->_valueset, 1));
else
- return false;
+ return array();
} /* }}} */
/**
@@ -677,7 +736,7 @@ class SeedDMS_Core_AttributeDefinition { /* {{{ */
$queryStr = "SELECT count(*) c, value FROM tblDocumentAttributes WHERE attrdef=".$this->_id." GROUP BY value ORDER BY c DESC";
$resArr = $db->getResultArray($queryStr);
if($resArr) {
- $result['frequencies'] = $resArr;
+ $result['frequencies']['document'] = $resArr;
}
}
@@ -694,6 +753,11 @@ class SeedDMS_Core_AttributeDefinition { /* {{{ */
}
}
}
+ $queryStr = "SELECT count(*) c, value FROM tblFolderAttributes WHERE attrdef=".$this->_id." GROUP BY value ORDER BY c DESC";
+ $resArr = $db->getResultArray($queryStr);
+ if($resArr) {
+ $result['frequencies']['folder'] = $resArr;
+ }
}
if($this->_objtype == SeedDMS_Core_AttributeDefinition::objtype_all ||
@@ -709,6 +773,11 @@ class SeedDMS_Core_AttributeDefinition { /* {{{ */
}
}
}
+ $queryStr = "SELECT count(*) c, value FROM tblDocumentContentAttributes WHERE attrdef=".$this->_id." GROUP BY value ORDER BY c DESC";
+ $resArr = $db->getResultArray($queryStr);
+ if($resArr) {
+ $result['frequencies']['content'] = $resArr;
+ }
}
return $result;
diff --git a/SeedDMS_Core/Core/inc.ClassDMS.php b/SeedDMS_Core/Core/inc.ClassDMS.php
index c48dee62d..bd4ae8426 100644
--- a/SeedDMS_Core/Core/inc.ClassDMS.php
+++ b/SeedDMS_Core/Core/inc.ClassDMS.php
@@ -311,7 +311,7 @@ class SeedDMS_Core_DMS {
$this->classnames['group'] = 'SeedDMS_Core_Group';
$this->version = '@package_version@';
if($this->version[0] == '@')
- $this->version = '5.0.0';
+ $this->version = '5.0.1';
} /* }}} */
/**
@@ -1483,57 +1483,27 @@ class SeedDMS_Core_DMS {
/**
* Get all notifications for a group
*
+ * deprecated: User {@link SeedDMS_Core_Group::getNotifications()}
+ *
* @param object $group group for which notifications are to be retrieved
* @param integer $type type of item (T_DOCUMENT or T_FOLDER)
* @return array array of notifications
*/
function getNotificationsByGroup($group, $type=0) { /* {{{ */
- $queryStr = "SELECT `tblNotify`.* FROM `tblNotify` ".
- "WHERE `tblNotify`.`groupID` = ". $group->getID();
- if($type) {
- $queryStr .= " AND `tblNotify`.`targetType` = ". (int) $type;
- }
-
- $resArr = $this->db->getResultArray($queryStr);
- if (is_bool($resArr) && !$resArr)
- return false;
-
- $notifications = array();
- foreach ($resArr as $row) {
- $not = new SeedDMS_Core_Notification($row["target"], $row["targetType"], $row["userID"], $row["groupID"]);
- $not->setDMS($this);
- array_push($notifications, $cat);
- }
-
- return $notifications;
+ return $group->getNotifications($type);
} /* }}} */
/**
* Get all notifications for a user
*
+ * deprecated: User {@link SeedDMS_Core_User::getNotifications()}
+ *
* @param object $user user for which notifications are to be retrieved
* @param integer $type type of item (T_DOCUMENT or T_FOLDER)
* @return array array of notifications
*/
function getNotificationsByUser($user, $type=0) { /* {{{ */
- $queryStr = "SELECT `tblNotify`.* FROM `tblNotify` ".
- "WHERE `tblNotify`.`userID` = ". $user->getID();
- if($type) {
- $queryStr .= " AND `tblNotify`.`targetType` = ". (int) $type;
- }
-
- $resArr = $this->db->getResultArray($queryStr);
- if (is_bool($resArr) && !$resArr)
- return false;
-
- $notifications = array();
- foreach ($resArr as $row) {
- $not = new SeedDMS_Core_Notification($row["target"], $row["targetType"], $row["userID"], $row["groupID"]);
- $not->setDMS($this);
- array_push($notifications, $cat);
- }
-
- return $notifications;
+ return $user->getNotifications($type);
} /* }}} */
/**
diff --git a/SeedDMS_Core/Core/inc.ClassDocumentCategory.php b/SeedDMS_Core/Core/inc.ClassDocumentCategory.php
index 7bebf6f25..0c436315e 100644
--- a/SeedDMS_Core/Core/inc.ClassDocumentCategory.php
+++ b/SeedDMS_Core/Core/inc.ClassDocumentCategory.php
@@ -108,7 +108,7 @@ class SeedDMS_Core_DocumentCategory {
$documents = array();
foreach ($resArr as $row) {
- array_push($documents, $this->_dms->getDocument($row["id"]));
+ array_push($documents, $this->_dms->getDocument($row["documentID"]));
}
return $documents;
} /* }}} */
diff --git a/SeedDMS_Core/Core/inc.ClassGroup.php b/SeedDMS_Core/Core/inc.ClassGroup.php
index ea2ba666f..e38afabef 100644
--- a/SeedDMS_Core/Core/inc.ClassGroup.php
+++ b/SeedDMS_Core/Core/inc.ClassGroup.php
@@ -186,7 +186,7 @@ class SeedDMS_Core_Group {
$queryStr = "INSERT INTO tblGroupMembers (groupID, userID, manager) VALUES (".$this->_id.", ".$user->getID(). ", " . ($asManager?"1":"0") ." )";
$res = $db->getResult($queryStr);
- if ($res) return false;
+ if (!$res) return false;
unset($this->_users);
return true;
@@ -198,7 +198,7 @@ class SeedDMS_Core_Group {
$queryStr = "DELETE FROM tblGroupMembers WHERE groupID = ".$this->_id." AND userID = ".$user->getID();
$res = $db->getResult($queryStr);
- if ($res) return false;
+ if (!$res) return false;
unset($this->_users);
return true;
} /* }}} */
@@ -379,5 +379,63 @@ class SeedDMS_Core_Group {
return $status;
} /* }}} */
+
+ /**
+ * Get a list of documents with a workflow
+ *
+ * @param int $documentID optional document id for which to retrieve the
+ * reviews
+ * @param int $version optional version of the document
+ * @return array list of all workflows
+ */
+ function getWorkflowStatus($documentID=null, $version=null) { /* {{{ */
+ $db = $this->_dms->getDB();
+
+ $queryStr = 'select distinct d.*, c.groupid from tblWorkflowTransitions a left join tblWorkflows b on a.workflow=b.id left join tblWorkflowTransitionGroups c on a.id=c.transition left join tblWorkflowDocumentContent d on b.id=d.workflow where d.document is not null and a.state=d.state and c.groupid='.$this->_id;
+ if($documentID) {
+ $queryStr .= ' AND d.document='.(int) $documentID;
+ if($version)
+ $queryStr .= ' AND d.version='.(int) $version;
+ }
+ $resArr = $db->getResultArray($queryStr);
+ if (is_bool($resArr) && $resArr == false)
+ return false;
+ $result = array();
+ if (count($resArr)>0) {
+ foreach ($resArr as $res) {
+ $result[] = $res;
+ }
+ }
+ return $result;
+ } /* }}} */
+
+ /**
+ * Get all notifications of group
+ *
+ * @param integer $type type of item (T_DOCUMENT or T_FOLDER)
+ * @return array array of notifications
+ */
+ function getNotificationsByGroup($type=0) { /* {{{ */
+ $db = $this->_dms->getDB();
+ $queryStr = "SELECT `tblNotify`.* FROM `tblNotify` ".
+ "WHERE `tblNotify`.`groupID` = ". $this->_id;
+ if($type) {
+ $queryStr .= " AND `tblNotify`.`targetType` = ". (int) $type;
+ }
+
+ $resArr = $db->getResultArray($queryStr);
+ if (is_bool($resArr) && !$resArr)
+ return false;
+
+ $notifications = array();
+ foreach ($resArr as $row) {
+ $not = new SeedDMS_Core_Notification($row["target"], $row["targetType"], $row["userID"], $row["groupID"]);
+ $not->setDMS($this);
+ array_push($notifications, $not);
+ }
+
+ return $notifications;
+ } /* }}} */
+
}
?>
diff --git a/SeedDMS_Core/Core/inc.ClassObject.php b/SeedDMS_Core/Core/inc.ClassObject.php
index 36bede8a8..ff711b1ab 100644
--- a/SeedDMS_Core/Core/inc.ClassObject.php
+++ b/SeedDMS_Core/Core/inc.ClassObject.php
@@ -202,6 +202,11 @@ class SeedDMS_Core_Object { /* {{{ */
if (!$this->_attributes) {
$this->getAttributes();
}
+ switch($attrdef->getType()) {
+ case SeedDMS_Core_AttributeDefinition::type_boolean:
+ $value = ($value === true || $value != '' || $value == 1) ? 1 : 0;
+ break;
+ }
if($attrdef->getMultipleValues() && is_array($value)) {
$sep = substr($attrdef->getValueSet(), 0, 1);
$value = $sep.implode($sep, $value);
diff --git a/SeedDMS_Core/Core/inc.ClassUser.php b/SeedDMS_Core/Core/inc.ClassUser.php
index b05c74005..dd7c95810 100644
--- a/SeedDMS_Core/Core/inc.ClassUser.php
+++ b/SeedDMS_Core/Core/inc.ClassUser.php
@@ -564,7 +564,7 @@ class SeedDMS_Core_User { /* {{{ */
return false;
}
- //Evtl. von diesem Benutzer gelockte Dokumente werden freigegeben
+ // unlock documents locked by the user
$queryStr = "DELETE FROM tblDocumentLocks WHERE userID = " . $this->_id;
if (!$db->getResult($queryStr)) {
$db->rollbackTransaction();
@@ -861,7 +861,7 @@ class SeedDMS_Core_User { /* {{{ */
function getDocumentsLocked() { /* {{{ */
$db = $this->_dms->getDB();
- $queryStr = "SELECT `tblDocuments`.* ".
+ $queryStr = "SELECT `tblDocuments`.*, `tblDocumentLocks`.`userID` as `lockUser` ".
"FROM `tblDocumentLocks` LEFT JOIN `tblDocuments` ON `tblDocuments`.`id` = `tblDocumentLocks`.`document` ".
"WHERE `tblDocumentLocks`.`userID` = '".$this->_id."' ".
"ORDER BY `id` DESC";
@@ -888,7 +888,7 @@ class SeedDMS_Core_User { /* {{{ */
* same is true for the version of a document which limits the list
* further.
*
- * For a detaile description of the result array see
+ * For a detailed description of the result array see
* {link SeedDMS_Core_User::getApprovalStatus} which does the same for
* approvals.
*
@@ -1059,7 +1059,7 @@ class SeedDMS_Core_User { /* {{{ */
function getWorkflowStatus($documentID=null, $version=null) { /* {{{ */
$db = $this->_dms->getDB();
- $queryStr = 'SELECT d.*, c.userid FROM tblWorkflowTransitions a LEFT JOIN tblWorkflows b ON a.workflow=b.id LEFT JOIN tblWorkflowTransitionUsers c ON a.id=c.transition LEFT JOIN tblWorkflowDocumentContent d ON b.id=d.workflow WHERE d.document IS NOT NULL AND a.state=d.state AND c.userid='.$this->_id;
+ $queryStr = 'SELECT DISTINCT d.*, c.userid FROM tblWorkflowTransitions a LEFT JOIN tblWorkflows b ON a.workflow=b.id LEFT JOIN tblWorkflowTransitionUsers c ON a.id=c.transition LEFT JOIN tblWorkflowDocumentContent d ON b.id=d.workflow WHERE d.document IS NOT NULL AND a.state=d.state AND c.userid='.$this->_id;
if($documentID) {
$queryStr .= ' AND d.document='.(int) $documentID;
if($version)
@@ -1075,7 +1075,7 @@ class SeedDMS_Core_User { /* {{{ */
}
}
- $queryStr = 'select d.*, c.groupid from tblWorkflowTransitions a left join tblWorkflows b on a.workflow=b.id left join tblWorkflowTransitionGroups c on a.id=c.transition left join tblWorkflowDocumentContent d on b.id=d.workflow left join tblGroupMembers e on c.groupid = e.groupID where d.document is not null and a.state=d.state and e.userID='.$this->_id;
+ $queryStr = 'select distinct d.*, c.groupid from tblWorkflowTransitions a left join tblWorkflows b on a.workflow=b.id left join tblWorkflowTransitionGroups c on a.id=c.transition left join tblWorkflowDocumentContent d on b.id=d.workflow left join tblGroupMembers e on c.groupid = e.groupID where d.document is not null and a.state=d.state and e.userID='.$this->_id;
if($documentID) {
$queryStr .= ' AND d.document='.(int) $documentID;
if($version)
@@ -1151,6 +1151,32 @@ class SeedDMS_Core_User { /* {{{ */
return $workflow;
} /* }}} */
+ /**
+ * Get the mandatory workflows
+ * A user which isn't trusted completely may have assigned mandatory
+ * workflow
+ * Whenever the user inserts a new document the mandatory workflow is
+ * filled in as the workflow.
+ *
+ * @return object workflow
+ */
+ function getMandatoryWorkflows() { /* {{{ */
+ $db = $this->_dms->getDB();
+
+ $queryStr = "SELECT * FROM tblWorkflowMandatoryWorkflow WHERE userid = " . $this->_id;
+ $resArr = $db->getResultArray($queryStr);
+ if (is_bool($resArr) && !$resArr) return false;
+
+ if(!$resArr)
+ return null;
+
+ $workflows = array();
+ foreach($resArr as $res) {
+ $workflows[] = $this->_dms->getWorkflow($res['workflow']);
+ }
+ return $workflows;
+ } /* }}} */
+
/**
* Set a mandatory reviewer
* This function sets a mandatory reviewer if it isn't already set.
@@ -1237,6 +1263,36 @@ class SeedDMS_Core_User { /* {{{ */
if (is_bool($resArr) && !$resArr) return false;
} /* }}} */
+ /**
+ * Set a mandatory workflows
+ * This function sets a list of mandatory workflows.
+ *
+ * @param array $workflows list of workflow objects
+ * @return boolean true on success, otherwise false
+ */
+ function setMandatoryWorkflows($workflows) { /* {{{ */
+ $db = $this->_dms->getDB();
+
+ $db->startTransaction();
+ $queryStr = "DELETE FROM tblWorkflowMandatoryWorkflow WHERE userid = " . $this->_id;
+ if (!$db->getResult($queryStr)) {
+ $db->rollbackTransaction();
+ return false;
+ }
+
+ foreach($workflows as $workflow) {
+ $queryStr = "INSERT INTO tblWorkflowMandatoryWorkflow (userid, workflow) VALUES (" . $this->_id . ", " . $workflow->getID() .")";
+ $resArr = $db->getResult($queryStr);
+ if (is_bool($resArr) && !$resArr) {
+ $db->rollbackTransaction();
+ return false;
+ }
+ }
+
+ $db->commitTransaction();
+ return true;
+ } /* }}} */
+
/**
* Deletes all mandatory reviewers
*
@@ -1274,5 +1330,33 @@ class SeedDMS_Core_User { /* {{{ */
return true;
} /* }}} */
+ /**
+ * Get all notifications of user
+ *
+ * @param integer $type type of item (T_DOCUMENT or T_FOLDER)
+ * @return array array of notifications
+ */
+ function getNotifications($type=0) { /* {{{ */
+ $db = $this->_dms->getDB();
+ $queryStr = "SELECT `tblNotify`.* FROM `tblNotify` ".
+ "WHERE `tblNotify`.`userID` = ". $this->_id;
+ if($type) {
+ $queryStr .= " AND `tblNotify`.`targetType` = ". (int) $type;
+ }
+
+ $resArr = $db->getResultArray($queryStr);
+ if (is_bool($resArr) && !$resArr)
+ return false;
+
+ $notifications = array();
+ foreach ($resArr as $row) {
+ $not = new SeedDMS_Core_Notification($row["target"], $row["targetType"], $row["userID"], $row["groupID"]);
+ $not->setDMS($this);
+ array_push($notifications, $not);
+ }
+
+ return $notifications;
+ } /* }}} */
+
} /* }}} */
?>
diff --git a/SeedDMS_Core/package.xml b/SeedDMS_Core/package.xml
index 7e99e9d3c..4d76ff05a 100644
--- a/SeedDMS_Core/package.xml
+++ b/SeedDMS_Core/package.xml
@@ -13,10 +13,10 @@
yes2016-01-22
-
+
- 5.0.0
- 5.0.0
+ 5.0.1
+ 5.0.1stable
@@ -24,8 +24,7 @@
GPL License
-- classes can be overloaded
-- clean workflow log when a document version was deleted
+- all changes from 4.3.24 merged
@@ -943,5 +942,46 @@ by a group or user right
- minor improvements int SeedDMS_Core_Document::getReadAccessList()
+
+ 2016-01-22
+
+
+ 4.3.24
+ 4.3.24
+
+
+ stable
+ stable
+
+ GPL License
+
+- make sure boolean attribute is saved as 0/1
+- add SeedDMS_Core_User::[g|s]etMandatoryWorkflows()
+- add SeedDMS_Core_User::getNotifications()
+- add SeedDMS_Core_Group::getNotifications()
+- SeedDMS_Core_DMS::getNotificationsByGroup() and
+SeedDMS_Core_DMS::getNotificationsByUser() are deprecated
+- SeedDMS_Core_DocumentCategory::getDocumentsByCategory() now returns the documents
+- add SeedDMS_Core_Group::getWorkflowStatus()
+- SeedDMS_Core_User::getDocumentsLocked() sets locking user propperly
+
+
+
+ 2016-01-22
+
+
+ 5.0.0
+ 5.0.0
+
+
+ stable
+ stable
+
+ GPL License
+
+- classes can be overloaded
+- clean workflow log when a document version was deleted
+
+
diff --git a/SeedDMS_Lucene/Lucene/IndexedDocument.php b/SeedDMS_Lucene/Lucene/IndexedDocument.php
index 82e1df9b7..c9d5c6a1e 100644
--- a/SeedDMS_Lucene/Lucene/IndexedDocument.php
+++ b/SeedDMS_Lucene/Lucene/IndexedDocument.php
@@ -64,6 +64,7 @@ class SeedDMS_Lucene_IndexedDocument extends Zend_Search_Lucene_Document {
public function __construct($dms, $document, $convcmd=null, $nocontent=false, $timeout=5) {
$_convcmd = array(
'application/pdf' => 'pdftotext -enc UTF-8 -nopgbrk %s - |sed -e \'s/ [a-zA-Z0-9.]\{1\} / /g\' -e \'s/[0-9.]//g\'',
+ 'application/postscript' => 'ps2pdf14 %s - | pdftotext -enc UTF-8 -nopgbrk - - | sed -e \'s/ [a-zA-Z0-9.]\{1\} / /g\' -e \'s/[0-9.]//g\'',
'application/msword' => 'catdoc %s',
'application/vnd.ms-excel' => 'ssconvert -T Gnumeric_stf:stf_csv -S %s fd://1',
'audio/mp3' => "id3 -l -R %s | egrep '(Title|Artist|Album)' | sed 's/^[^:]*: //g'",
diff --git a/SeedDMS_Lucene/package.xml b/SeedDMS_Lucene/package.xml
index 1b6f36d80..b7dee2403 100644
--- a/SeedDMS_Lucene/package.xml
+++ b/SeedDMS_Lucene/package.xml
@@ -11,11 +11,11 @@
uwe@steinmann.cxyes
- 2015-08-05
-
+ 2016-02-01
+
- 1.1.6
- 1.1.6
+ 1.1.7
+ 1.1.7stable
@@ -23,7 +23,7 @@
GPL License
-run external commands with a timeout
+add command for indexing postѕcript files
@@ -186,5 +186,21 @@ field for original filename is treated as utf-8
declare SeeDMS_Lucene_Indexer::open() static
+
+ 2015-08-05
+
+
+ 1.1.6
+ 1.1.6
+
+
+ stable
+ stable
+
+ GPL License
+
+run external commands with a timeout
+
+
diff --git a/SeedDMS_Preview/Preview/Previewer.php b/SeedDMS_Preview/Preview/Previewer.php
index a1a5d47e8..067b104b2 100644
--- a/SeedDMS_Preview/Preview/Previewer.php
+++ b/SeedDMS_Preview/Preview/Previewer.php
@@ -37,7 +37,13 @@ class SeedDMS_Preview_Previewer {
*/
protected $width;
- function __construct($previewDir, $width=40) {
+ /**
+ * @var integer $timeout maximum time for execution of external commands
+ * @access protected
+ */
+ protected $timeout;
+
+ function __construct($previewDir, $width=40, $timeout=5) {
if(!is_dir($previewDir)) {
if (!SeedDMS_Core_File::makeDir($previewDir)) {
$this->previewDir = '';
@@ -48,9 +54,10 @@ class SeedDMS_Preview_Previewer {
$this->previewDir = $previewDir;
}
$this->width = intval($width);
+ $this->timeout = intval($timeout);
}
- static function execWithTimeout($cmd, $timeout=2) { /* {{{ */
+ static function execWithTimeout($cmd, $timeout=5) { /* {{{ */
$descriptorspec = array(
0 => array("pipe", "r"),
1 => array("pipe", "w"),
@@ -155,7 +162,7 @@ class SeedDMS_Preview_Previewer {
if($cmd) {
//exec($cmd);
try {
- self::execWithTimeout($cmd);
+ self::execWithTimeout($cmd, $this->timeout);
} catch(Exception $e) {
}
}
@@ -216,7 +223,7 @@ class SeedDMS_Preview_Previewer {
if($cmd) {
//exec($cmd);
try {
- self::execWithTimeout($cmd);
+ self::execWithTimeout($cmd, $this->timeout);
} catch(Exception $e) {
}
}
@@ -282,6 +289,21 @@ class SeedDMS_Preview_Previewer {
}
} /* }}} */
+ public function getFilesize($object, $width=0) { /* {{{ */
+ if($width == 0)
+ $width = $this->width;
+ else
+ $width = intval($width);
+ $target = $this->getFileName($object, $width);
+ if($target && file_exists($target.'.png')) {
+ return(filesize($target.'.png'));
+ } else {
+ return false;
+ }
+
+ } /* }}} */
+
+
public function deletePreview($document, $object, $width=0) { /* {{{ */
if($width == 0)
$width = $this->width;
diff --git a/SeedDMS_Preview/package.xml b/SeedDMS_Preview/package.xml
index e4a75a82f..256ab3c75 100644
--- a/SeedDMS_Preview/package.xml
+++ b/SeedDMS_Preview/package.xml
@@ -11,11 +11,11 @@
uwe@steinmann.cxyes
- 2015-08-08
+ 2016-02-11
- 1.1.4
- 1.1.0
+ 1.1.5
+ 1.1.5stable
@@ -23,7 +23,8 @@
GPL License
-command for creating the preview will be called with a given timeout
+add method getFilesize()
+timeout for external commands can be passed to contructor of SeedDMS_Preview_Previewer
@@ -131,5 +132,21 @@ create fixed width image with proportional height
preview images will also be recreated if the object this image belongs is of newer date than the image itself. This happens if versions are being deleted and than a new version is uploaded. Because the new version will get the version number of the old version, it will also take over the old preview image.Comparing the creation date of the image with the object detects this case.
+
+ 2015-08-08
+
+
+ 1.1.4
+ 1.1.0
+
+
+ stable
+ stable
+
+ GPL License
+
+command for creating the preview will be called with a given timeout
+
+
diff --git a/SeedDMS_SQLiteFTS/SQLiteFTS/IndexedDocument.php b/SeedDMS_SQLiteFTS/SQLiteFTS/IndexedDocument.php
index 3ad771513..d28e254d0 100644
--- a/SeedDMS_SQLiteFTS/SQLiteFTS/IndexedDocument.php
+++ b/SeedDMS_SQLiteFTS/SQLiteFTS/IndexedDocument.php
@@ -69,6 +69,7 @@ class SeedDMS_SQLiteFTS_IndexedDocument extends SeedDMS_SQLiteFTS_Document {
public function __construct($dms, $document, $convcmd=null, $nocontent=false, $timeout=5) {
$_convcmd = array(
'application/pdf' => 'pdftotext -enc UTF-8 -nopgbrk %s - |sed -e \'s/ [a-zA-Z0-9.]\{1\} / /g\' -e \'s/[0-9.]//g\'',
+ 'application/postscript' => 'ps2pdf14 %s - | pdftotext -enc UTF-8 -nopgbrk - - | sed -e \'s/ [a-zA-Z0-9.]\{1\} / /g\' -e \'s/[0-9.]//g\'',
'application/msword' => 'catdoc %s',
'application/vnd.ms-excel' => 'ssconvert -T Gnumeric_stf:stf_csv -S %s fd://1',
'audio/mp3' => "id3 -l -R %s | egrep '(Title|Artist|Album)' | sed 's/^[^:]*: //g'",
diff --git a/SeedDMS_SQLiteFTS/package.xml b/SeedDMS_SQLiteFTS/package.xml
index 1a8b927ca..87d9735d9 100644
--- a/SeedDMS_SQLiteFTS/package.xml
+++ b/SeedDMS_SQLiteFTS/package.xml
@@ -11,10 +11,10 @@
uwe@steinmann.cxyes
- 2016-01-10
-
+ 2016-02-01
+
- 1.0.2
+ 1.0.31.0.1
@@ -23,7 +23,7 @@
GPL License
-check if index exists before removing it when creating a new one
+add command for indexing postѕcript files
@@ -98,5 +98,21 @@ initial release
add __get() to SQLiteFTS_Document because class.IndexInfo.php access class variable title which doesn't exists
+
+ 2016-01-10
+
+
+ 1.0.2
+ 1.0.1
+
+
+ stable
+ stable
+
+ GPL License
+
+check if index exists before removing it when creating a new one
+
+
diff --git a/conf/settings.xml.template b/conf/settings.xml.template
index fb40821a0..32afc7468 100644
--- a/conf/settings.xml.template
+++ b/conf/settings.xml.template
@@ -1,23 +1,28 @@
-
-
-
+ - enableDropUpload: XXX
+ - enableRecursiveCount: XXX
+ - maxRecursiveCount: XXX
+ - enableThemeSelector: XXX
+ - fullSearchEngine: Either "lucene" or "sqlitefts"
+ - sortFoldersDefault: XXX
+ -->
-
-
+ -->
-
+ />
-
-
@@ -86,23 +102,41 @@
partitionSize = "2000000"
dropFolderDir = ""
cacheDir = ""
- >
-
-
-
+ - passwordStrength: XXX
+ - passwordStrengthAlgorithm: XXX
+ - passwordExpiration: XXX
+ - passwordHistory: XXX
+ - loginFailure: XXX
+ - autoLoginUser: XXX
+ - quota: XXX
+ - undelUserIds: XXX
+ - encryptionKey: XXX
+ - cookieLifetime: XXX
+ -->
+ passwordStrength = "0"
+ passwordStrengthAlgorithm = "simple"
+ passwordExpiration = "0"
+ passwordHistory = "0"
+ loginFailure = "0"
+ autoLoginUser = "0"
+ quota = "0"
+ undelUserIds = ""
+ encryptionKey = "b8c75fa53c0c7a18a84adb6ca815bd94"
+ cookieLifetime = "0">
+ -->
-
+ bindDN = ""
+ bindPw = ""
+ filter = ""
+ />
+ - bindDN: XXX
+ - bindPw: XXX
+ -->
-
+ bindDN = ""
+ bindPw = ""
+ />
-
+ - doNotCheckVersion: Whether or not to check the database schema for its correct version.
+ -->
-
-
-
+
+ smtpUser = ""
+ smtpPassword = ""
+ />
-
-
-
+ - showMissingTranslations: XXX
+ -->
-
-
+ -->
-
+ adminIP = ""
+ />
+ - enableOwnerRevApp: XXX
+ - enableSelfRevApp: XXX
+ - presetExpirationDate: XXX
+ - overrideMimeType: XXX
+ -->
-
-
-
-
+ extraPath = ""
+ maxExecutionTime = "30"
+ cmdTimeout = "1"
+ />
+
+
-
+
diff --git a/controllers/class.Download.php b/controllers/class.Download.php
index 749fb04a1..95f9ba737 100644
--- a/controllers/class.Download.php
+++ b/controllers/class.Download.php
@@ -31,14 +31,16 @@ class SeedDMS_Controller_Download extends SeedDMS_Controller_Common {
case "version":
if(!$this->callHook('version')) {
- header("Content-Transfer-Encoding: binary");
- header("Content-Length: " . filesize($dms->contentDir . $content->getPath() ));
- $efilename = rawurlencode($content->getOriginalFileName());
- header("Content-Disposition: attachment; filename=\"" . $efilename . "\"; filename*=UTF-8''".$efilename);
- header("Content-Type: " . $content->getMimeType());
- header("Cache-Control: must-revalidate");
+ if(file_exists($dms->contentDir . $content->getPath())) {
+ header("Content-Transfer-Encoding: binary");
+ header("Content-Length: " . filesize($dms->contentDir . $content->getPath() ));
+ $efilename = rawurlencode($content->getOriginalFileName());
+ header("Content-Disposition: attachment; filename=\"" . $efilename . "\"; filename*=UTF-8''".$efilename);
+ header("Content-Type: " . $content->getMimeType());
+ header("Cache-Control: must-revalidate");
- readfile($dms->contentDir . $content->getPath());
+ readfile($dms->contentDir . $content->getPath());
+ }
}
break;
}
diff --git a/README.md b/doc/README.Install.md
similarity index 99%
rename from README.md
rename to doc/README.Install.md
index aad302f08..1dfe92bb8 100644
--- a/README.md
+++ b/doc/README.Install.md
@@ -64,6 +64,8 @@ Here is a detailed list of requirements:
6. The Zend Framework (version 1) (optional, only needed for fulltext search)
7. The pear Log package
8. The pear HTTP_WebDAV_Server package (optional, only need for webdav)
+9. SLIM RestApi
+10. FeedWriter from https://github.com/mibe/FeedWriter
BEFORE YOU START
diff --git a/README.Notification b/doc/README.Notification
similarity index 100%
rename from README.Notification
rename to doc/README.Notification
diff --git a/doc/README.ReviewApproval.md b/doc/README.ReviewApproval.md
new file mode 100644
index 000000000..d900899c4
--- /dev/null
+++ b/doc/README.ReviewApproval.md
@@ -0,0 +1,39 @@
+Review/Approval
+------------------
+
+The traditional Review/Approval process has been around for a long time
+already and is still available, though the new workflow engine has been
+introduced.
+
+Review/Approval is a very simple, but in many cases sufficient, workflow
+to review and approve document versions. Review and approval is done by users
+in behalf of themself or the group they belong to. A document version
+is reviewed or approved if all users and groups in charge of it, have
+found the document version to be ready and worth for release. If a single
+user rejects it, it will not change its status to 'released' but to 'rejected'.
+
+Review is always done before approval, but a document version may not have
+to run through both processes.
+A version can use just the approval process without a review before,
+and it can also skip the approval process and just run through review. In
+the second case the document will be released immidiately after successful
+review.
+
+If a group is in charge for reviewing/approving a document, it will be
+sufficient if one member of that group takes action.
+
+Internally SeedDMS keeps a record of all approval/review actions done on
+a document version. When a document version is uploaded with both processes
+in place, then for each user/group a list of log entries is created. Any
+action on the document will add a new entry to the log. Those entries
+contain the action (release/reject), a user comment and the current date.
+Each entry will also trigger an internal function which checks, whether
+the last action causes a document state change. Such a state change happens
+when all reviews or approvals are done, or if a review/approval is rejected.
+If a user or a group is deleted and some documents are still waiting for
+a review/approval, this will also be logged and the review/approval will
+no longer be needed to release the document.
+
+Before a document leaves the approval or review state any review/approval
+or reject can be changed. So if a user initially approves a document and
+later changes her/his mind, he/she can still reject the document.
diff --git a/doc/README.Synology.txt b/doc/README.Synology.txt
new file mode 100644
index 000000000..0326d4504
--- /dev/null
+++ b/doc/README.Synology.txt
@@ -0,0 +1,109 @@
+*********************************************
+How to set up SeedDMS Preview on Synology NAS
+*********************************************
+
+Introduction
+############
+SeedDMS provides a function creating a preview of each document which is displayed on the document page.
+
+Synology stations do not support the creation of the previews by default due to a missing Ghostscript implementation. Therefore
+loading of a document page can use a lot of time because SeedDMS tries to create the missing preview images each time the document
+page is being loaded.
+
+Prerequisites
+#############
+In order to complete the steps outlined below, you must be able to carry out the following tasks:
+
+* Use the command line and know essential commands
+* Install a 3rd party package system and install packages using this system
+
+To complete the installation, the following prerequisites on your Synology must be met:
+
+* IPKG or OPKG (OPKG preferred) installed
+* Pear Package SeedDMS_Preview already installed
+
+Installation and configuration
+##############################
+
+In the following steps, you will first install the required packages, followed by doing the neccesary configurations. These steps
+must be done on the terminal.
+
+Install Ghostscript
+***************************
+
+The first step is to install Ghostscript to make ImageMagick capable of converting PDF files to images. Use IPKG or OPKG to complete this
+step.
+
+Make Ghostscript available to PHP
+*****************************************
+
+To check where Ghostscript is installed run *which gs* to get the installation path. Now check if this path is visible to PHP. To check this,
+use phpinfo and find **_SERVER["PATH"]**. If you can't find /opt inside, PHP can't see applications installed there. You can now either try to
+update the paths or just make a symlink.
+To create the symlink, cd to /usr/bin and type *ln -s /opt/bin/gs gs*. Verify the created symlink.
+
+Fix Ghostscript package bug
+****************************************
+
+Unfortunately the version delivered by OPKG has a bug, making Ghostscript failing to work properly. The bug requries fixing at the time
+of the writing are the following:
+
+* Resource path pointing to a wrong version (9.10 instead of 9.16)
+
+First, fix the resource path. Go to /opt/bin and find **gs** in there. Open the file with VI. Change the GS_LIB path from */opt/share/ghostscript/9.10/Resource*
+to */opt/share/ghostscript/9.16/Resource*. This will now allow Ghostscript to find it's files in the proper path.
+
+Fix ImageMagick
+********************
+
+Not only Ghostscript is affected by bugs, the default configuration files are missing. Unfortunately some work is required here as well.
+
+To check where ImageMagick looks for it's files, invoke the command *convert -debug configure logo: null:*. You will see some paths shown, these
+are the paths where ImageMagic tries to locate it's configuration files. The first path shown will point to */usr/share/ImageMagick-6* followed by the
+name of an XML file. At the very end of the output you will see which configuration file has been loaded, in the default setting there will be an error.
+
+Point to */usr/share* and check if you can find the **ImageMagick-6** directory. If is not present, create it. Cd into the directory.
+
+Next step is to fill the directory with files. Use the following list to download the files (credit goes to Thibault, http://blog.taillandier.name/2010/08/04/mediawiki-sur-son-nas-synology/).
+
+* wget http://www.imagemagick.org/source/coder.xml
+* wget http://www.imagemagick.org/source/colors.xml
+* wget http://www.imagemagick.org/source/configure.xml
+* wget http://www.imagemagick.org/source/delegates.xml
+* wget http://www.imagemagick.org/source/english.xml
+* wget http://www.imagemagick.org/source/francais.xml
+* wget http://www.imagemagick.org/source/locale.xml
+* wget http://www.imagemagick.org/source/log.xml
+* wget http://www.imagemagick.org/source/magic.xml
+* wget http://www.imagemagick.org/source/mime.xml
+* wget http://www.imagemagick.org/source/policy.xml
+* wget http://www.imagemagick.org/source/thresholds.xml
+* wget http://www.imagemagick.org/source/type-ghostscript.xml
+* wget http://www.imagemagick.org/source/type-windows.xml
+* wget http://www.imagemagick.org/source/type.xml
+
+Testing
+*************
+
+Now you should be ready to test. Put a PDF file in a directory, cd into this directory.
+
+To test convert directly, invoke the following command (replace file.pdf with your filename, replace output.png with your desired name):
+
+**convert file.pdf output.png**
+
+If everything goes well you should now receive a png file which can be opened. There may be a warning message about iCCP which can be ignored.
+
+If you want to test Ghostcript as well, invoke the follwing command:
+
+**gs -sDEVICE=pngalpha -sOutputFile=output.png -r144 file.pdf**
+
+This command should go through without any errors and as well output a png file.
+
+If the tests above are successful, you are ready to use SeedDMS Preview. Go to your SeedDMS Installation and open a folder. For the first test you
+may take a folder with less files in it. Be patient while the previews are generated. You may check the process using *top* on the terminal.
+
+At the end your document page should show the previews like shown below:
+
+.. figure:: preview.png
+ :alt: Document previews
+ :scale: 75%
diff --git a/README.Ubuntu b/doc/README.Ubuntu
similarity index 100%
rename from README.Ubuntu
rename to doc/README.Ubuntu
diff --git a/doc/README.WebDAV b/doc/README.WebDAV
new file mode 100644
index 000000000..4211bae73
--- /dev/null
+++ b/doc/README.WebDAV
@@ -0,0 +1,53 @@
+WebDAV
+-----------------------------------------------
+
+SeedDMS has support for WebDAV which allows to easily add, delete,
+move, copy and modify documents. All operating systems have support
+for WebDAV as well, but the implemtations and their behaviour varys
+and consequently you may run into various problems. If this happens
+just file a bug report at https://sourceforge.net/projects/seeddms
+
+The folder structure in SeedDMS is similar to a regular file system
+but it is not identical. SeedDMS distinguishes between a document
+and its content, while a file system knows just files.
+In SeedDMS a document is uniquely identified
+by its document id and not neccessarily by its name. A filesystem
+requires a unique paths for each file. Two identical files in the
+same folder are not possible. SeedDMS can handle identifcally named
+documents in one folder. In order to prevent any problems arising from
+this, you should always disallow identical document names in the
+settings. By definition a file in WebDAV is mapped on the latest
+version of a document in SeedDMS. There is no way to access previous
+versions of a document via WebDAV. Whenever you modify a file,
+a new version will be created. Unfortunately, this has some very
+nasty side effects when you often save a file, because any save
+operation will create a new version. This is because the WebDAV
+server replaces the content of document instead of creating a new
+version if a document is saved again.
+
+Various programms have differnt strategies to save files to disk and
+prevent data lost under all circumstances. Those strategies often don't
+work very well an a WebDAV-Server. The following will list some of those
+strategies.
+
+VIM
+=========================
+
+vim does a lot more than just reading and writing the file you want
+to edit. It creates swap and backup files for data recovery if vim crashes
+or is being kill unexpectivly. On a low bandwidth connection this can
+slow down the editing. For that reason you should either not create the
+swap file at all or create it outside the WebDAV server. A second problem
+arises from how vim modifіes the file you are editing. Before a file
+is saved a backup is created and the new content is written into a new
+file with the name of the original file. On a file system you
+won't see a difference between the file before and after saveing, though
+is actually a new one. In SeedDMS you won't notice a difference either
+if just looking at the document name. It's still the same, but the
+document id has changed. So saving a document will delete the
+old document and create a new one instead of creating a new version of
+the old document. If you don't want this behaviour, then tell vim
+to not create the backup. Creating the backup file in a directory
+outside of WebDAV doesn't help in this case.
+
+vi "+set nobackup" "+set nobackuwrite" -n test.txt
diff --git a/README.Workflow b/doc/README.Workflow
similarity index 100%
rename from README.Workflow
rename to doc/README.Workflow
diff --git a/doc/preview.png b/doc/preview.png
new file mode 100644
index 000000000..47676ee22
Binary files /dev/null and b/doc/preview.png differ
diff --git a/inc/inc.Authentication.php b/inc/inc.Authentication.php
index cdef1aa93..6896d83ac 100644
--- a/inc/inc.Authentication.php
+++ b/inc/inc.Authentication.php
@@ -12,19 +12,27 @@
* @version Release: @package_version@
*/
+require_once("inc.Utils.php");
+require_once("inc.ClassEmailNotify.php");
+require_once("inc.ClassSession.php");
+
$refer = $_SERVER["REQUEST_URI"];
if (!strncmp("/op", $refer, 3)) {
$refer="";
} else {
$refer = urlencode($refer);
}
-
-require_once("inc.Utils.php");
-require_once("inc.ClassEmailNotify.php");
-require_once("inc.ClassSession.php");
-
if (!isset($_COOKIE["mydms_session"])) {
- if($settings->_autoLoginUser) {
+ if($settings->_enableGuestLogin && $settings->_enableGuestAutoLogin) {
+ require_once("../inc/inc.ClassSession.php");
+ $session = new SeedDMS_Session($db);
+ if(!$dms_session = $session->create(array('userid'=>$settings->_guestID, 'theme'=>$settings->_theme, 'lang'=>$settings->_language))) {
+ header("Location: " . $settings->_httpRoot . "out/out.Login.php?referuri=".$refer);
+ exit;
+ }
+ $resArr = $session->load($dms_session);
+ } elseif($settings->_autoLoginUser) {
+ require_once("../inc/inc.ClassSession.php");
if(!($user = $dms->getUser($settings->_autoLoginUser))/* || !$user->isGuest()*/) {
header("Location: " . $settings->_httpRoot . "out/out.Login.php?referuri=".$refer);
exit;
@@ -40,17 +48,11 @@ if (!isset($_COOKIE["mydms_session"])) {
$user->setLanguage($lang);
}
$session = new SeedDMS_Session($db);
- if(!$id = $session->create(array('userid'=>$user->getID(), 'theme'=>$theme, 'lang'=>$lang))) {
+ if(!$dms_session = $session->create(array('userid'=>$user->getID(), 'theme'=>$theme, 'lang'=>$lang))) {
header("Location: " . $settings->_httpRoot . "out/out.Login.php?referuri=".$refer);
exit;
}
- /*
- if($settings->_cookieLifetime)
- $lifetime = time() + intval($settings->_cookieLifetime);
- else
- $lifetime = 0;
- setcookie("mydms_session", $id, $lifetime, $settings->_httpRoot, null, null, !$settings->_enableLargeFileUpload);
- */
+ $resArr = $session->load($dms_session);
} else {
header("Location: " . $settings->_httpRoot . "out/out.Login.php?referuri=".$refer);
exit;
@@ -64,28 +66,29 @@ if (!isset($_COOKIE["mydms_session"])) {
header("Location: " . $settings->_httpRoot . "out/out.Login.php?referuri=".$refer);
exit;
}
- /* Update last access time */
- $session->updateAccess($dms_session);
- /* Load user data */
-
- $user = $dms->getUser($resArr["userID"]);
- if (!is_object($user)) {
- setcookie("mydms_session", $dms_session, time()-3600, $settings->_httpRoot); //delete cookie
- header("Location: " . $settings->_httpRoot . "out/out.Login.php?referuri=".$refer);
- exit;
- }
-
- if($user->isAdmin()) {
- if($resArr["su"]) {
- $user = $dms->getUser($resArr["su"]);
- } else {
- $session->resetSu();
- }
- }
- $theme = $resArr["theme"];
- $lang = $resArr["language"];
}
+/* Update last access time */
+$session->updateAccess($dms_session);
+
+/* Load user data */
+$user = $dms->getUser($resArr["userID"]);
+if (!is_object($user)) {
+ setcookie("mydms_session", $dms_session, time()-3600, $settings->_httpRoot); //delete cookie
+ header("Location: " . $settings->_httpRoot . "out/out.Login.php?referuri=".$refer);
+ exit;
+}
+
+if($user->isAdmin()) {
+ if($resArr["su"]) {
+ $user = $dms->getUser($resArr["su"]);
+ } else {
+ $session->resetSu();
+ }
+}
+$theme = $resArr["theme"];
+$lang = $resArr["language"];
+
$dms->setUser($user);
if($settings->_enableEmail) {
$notifier = new SeedDMS_EmailNotify($settings->_smtpSendFrom, $settings->_smtpServer, $settings->_smtpPort, $settings->_smtpUser, $settings->_smtpPassword);
diff --git a/inc/inc.ClassEmailNotify.php b/inc/inc.ClassEmailNotify.php
index 2123aabe3..9423dbc94 100644
--- a/inc/inc.ClassEmailNotify.php
+++ b/inc/inc.ClassEmailNotify.php
@@ -74,11 +74,18 @@ class SeedDMS_EmailNotify extends SeedDMS_Notify {
*/
function toIndividual($sender, $recipient, $subject, $message, $params=array()) { /* {{{ */
global $settings;
- if ($recipient->getEmail()=="") return 0;
+ if ($recipient->isDisabled() || $recipient->getEmail()=="") return 0;
- if (!is_object($recipient) && strcasecmp(get_class($recipient), "SeedDMS_Core_User")) {
+ if(!is_object($recipient) && strcasecmp(get_class($recipient), "SeedDMS_Core_User")) {
return -1;
}
+ if (is_object($sender) && !strcasecmp(get_class($sender), "SeedDMS_Core_User")) {
+ $from = $sender->getFullName() ." <". $sender->getEmail() .">";
+ } elseif(is_string($sender) && trim($sender) != "") {
+ $from = $sender;
+ } else
+ return -1;
+
if(is_object($sender) && strcasecmp(get_class($sender), "SeedDMS_Core_User")) {
$from = $sender->getFullName() ." <". $sender->getEmail() .">";
@@ -127,9 +134,7 @@ class SeedDMS_EmailNotify extends SeedDMS_Notify {
$headers = array();
$headers[] = "MIME-Version: 1.0";
$headers[] = "Content-type: text/plain; charset=utf-8";
- //$headers[] = "From: ". $sender->getFullName() ." <". $sender->getEmail() .">";
- $headers[] = "From: ". $settings->_smtpSendFrom;
- $headers[] = "Reply-To: ". $sender->getFullName() ." <". $sender->getEmail() .">";
+ $headers[] = "From: ". $from;
$lang = $recipient->getLanguage();
$message = getMLText("email_header", array(), "", $lang)."\r\n\r\n".getMLText($message, $params, "", $lang);
diff --git a/inc/inc.ClassSettings.php b/inc/inc.ClassSettings.php
index 8b702eaec..18422d0f4 100644
--- a/inc/inc.ClassSettings.php
+++ b/inc/inc.ClassSettings.php
@@ -38,6 +38,8 @@ class Settings { /* {{{ */
var $_rootFolderID = 1;
// If you want anybody to login as guest, set the following line to true
var $_enableGuestLogin = false;
+ // If you even want guest to be logged in automatically, set the following to true
+ var $_enableGuestAutoLogin = false;
// Allow users to reset their password
var $_enablePasswordForgotten = false;
// Minimum password strength (0 - x, 0 means no check)
@@ -91,6 +93,8 @@ class Settings { /* {{{ */
var $_enableFullSearch = true;
// fulltext search engine
var $_fullSearchEngine = 'lucene';
+ // default search method
+ var $_defaultSearchMethod = 'database'; // or 'fulltext'
// contentOffsetDirTo
var $_contentOffsetDir = "1048576";
// Maximum number of sub-directories per parent directory
@@ -166,6 +170,8 @@ class Settings { /* {{{ */
var $_enableRecursiveCount = false;
// maximum number of documents or folders when counted recursively
var $_maxRecursiveCount = 10000;
+ // enable/disable help
+ var $_enableHelp = true;
// enable/disable language selection menu
var $_enableLanguageSelector = true;
// enable/disable theme selector
@@ -354,10 +360,12 @@ class Settings { /* {{{ */
$this->_enableFolderTree = Settings::boolVal($tab["enableFolderTree"]);
$this->_enableRecursiveCount = Settings::boolVal($tab["enableRecursiveCount"]);
$this->_maxRecursiveCount = intval($tab["maxRecursiveCount"]);
+ $this->_enableHelp = Settings::boolVal($tab["enableHelp"]);
$this->_enableLanguageSelector = Settings::boolVal($tab["enableLanguageSelector"]);
$this->_enableThemeSelector = Settings::boolVal($tab["enableThemeSelector"]);
$this->_enableFullSearch = Settings::boolVal($tab["enableFullSearch"]);
$this->_fullSearchEngine = strval($tab["fullSearchEngine"]);
+ $this->_defaultSearchMethod = strval($tab["defaultSearchMethod"]);
$this->_stopWordsFile = strval($tab["stopWordsFile"]);
$this->_sortUsersInList = strval($tab["sortUsersInList"]);
$this->_sortFoldersDefault = strval($tab["sortFoldersDefault"]);
@@ -389,6 +397,7 @@ class Settings { /* {{{ */
$node = $xml->xpath('/configuration/system/authentication');
$tab = $node[0]->attributes();
$this->_enableGuestLogin = Settings::boolVal($tab["enableGuestLogin"]);
+ $this->_enableGuestAutoLogin = Settings::boolVal($tab["enableGuestAutoLogin"]);
$this->_enablePasswordForgotten = Settings::boolVal($tab["enablePasswordForgotten"]);
$this->_passwordStrength = intval($tab["passwordStrength"]);
$this->_passwordStrengthAlgorithm = strval($tab["passwordStrengthAlgorithm"]);
@@ -646,10 +655,12 @@ class Settings { /* {{{ */
$this->setXMLAttributValue($node, "enableFolderTree", $this->_enableFolderTree);
$this->setXMLAttributValue($node, "enableRecursiveCount", $this->_enableRecursiveCount);
$this->setXMLAttributValue($node, "maxRecursiveCount", $this->_maxRecursiveCount);
+ $this->setXMLAttributValue($node, "enableHelp", $this->_enableHelp);
$this->setXMLAttributValue($node, "enableLanguageSelector", $this->_enableLanguageSelector);
$this->setXMLAttributValue($node, "enableThemeSelector", $this->_enableThemeSelector);
$this->setXMLAttributValue($node, "enableFullSearch", $this->_enableFullSearch);
$this->setXMLAttributValue($node, "fullSearchEngine", $this->_fullSearchEngine);
+ $this->setXMLAttributValue($node, "defaultSearchMethod", $this->_defaultSearchMethod);
$this->setXMLAttributValue($node, "expandFolderTree", $this->_expandFolderTree);
$this->setXMLAttributValue($node, "stopWordsFile", $this->_stopWordsFile);
$this->setXMLAttributValue($node, "sortUsersInList", $this->_sortUsersInList);
@@ -679,6 +690,7 @@ class Settings { /* {{{ */
// XML Path: /configuration/system/authentication
$node = $this->getXMLNode($xml, '/configuration/system', 'authentication');
$this->setXMLAttributValue($node, "enableGuestLogin", $this->_enableGuestLogin);
+ $this->setXMLAttributValue($node, "enableGuestAutoLogin", $this->_enableGuestAutoLogin);
$this->setXMLAttributValue($node, "enablePasswordForgotten", $this->_enablePasswordForgotten);
$this->setXMLAttributValue($node, "passwordStrength", $this->_passwordStrength);
$this->setXMLAttributValue($node, "passwordStrengthAlgorithm", $this->_passwordStrengthAlgorithm);
diff --git a/inc/inc.ClassUI.php b/inc/inc.ClassUI.php
index 238a1e227..8cd1f5eb0 100644
--- a/inc/inc.ClassUI.php
+++ b/inc/inc.ClassUI.php
@@ -91,6 +91,7 @@ class UI extends UI_Default {
$view->setParam('enablecalendar', $settings->_enableCalendar);
$view->setParam('calendardefaultview', $settings->_calendarDefaultView);
$view->setParam('enablefullsearch', $settings->_enableFullSearch);
+ $view->setParam('enablehelp', $settings->_enableHelp);
$view->setParam('enablelargefileupload', $settings->_enableLargeFileUpload);
$view->setParam('printdisclaimer', $settings->_printDisclaimer);
$view->setParam('footnote', $settings->_footNote);
@@ -102,6 +103,7 @@ class UI extends UI_Default {
$view->setParam('workflowmode', $settings->_workflowMode);
$view->setParam('partitionsize', $settings->_partitionSize);
$view->setParam('showmissingtranslations', $settings->_showMissingTranslations);
+ $view->setParam('defaultsearchmethod', $settings->_defaultSearchMethod);
return $view;
}
return null;
diff --git a/inc/inc.ClassUI_Default.php b/inc/inc.ClassUI_Default.php
index 2718eea58..b38abc689 100644
--- a/inc/inc.ClassUI_Default.php
+++ b/inc/inc.ClassUI_Default.php
@@ -27,7 +27,7 @@ class UI_Default {
$this->theme = $theme;
}
- static function getStyles() { /* {{{ */
+ static function __getStyles() { /* {{{ */
global $settings;
$themes = array();
@@ -52,12 +52,14 @@ class UI_Default {
} else {
echo "\n";
- echo "\n\n";
+ echo "\n\n";
echo "\n";
- echo "\n";
- echo "\n";
+ echo "\n";
+ echo "\n";
+ echo "\n";
echo "\n";
- echo "\n";
+ echo "\n";
+ echo "\n";
echo "".(strlen($settings->_siteName)>0 ? $settings->_siteName : "SeedDMS").(strlen($title)>0 ? ": " : "").htmlspecialchars($title)."\n";
echo "\n";
echo "0 ? " class=\"".$bodyClass."\"" : "").">\n";
@@ -78,6 +80,9 @@ class UI_Default {
function footNote() { /* {{{ */
global $settings;
+ echo '
'."\n";
+ echo '
'."\n";
+ echo '
'."\n";
if ($settings->_printDisclaimer){
echo "
".getMLText("disclaimer")."
";
}
@@ -85,31 +90,38 @@ class UI_Default {
if (isset($settings->_footNote) && strlen((string)$settings->_footNote)>0) {
echo "