diff --git a/CHANGELOG b/CHANGELOG index 227d2a0f7..5393789c0 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -3,6 +3,11 @@ -------------------------------------------------------------------------------- - translation updates - password expiration can be set to 'never' +- fixed saving multi value attributes +- do not close browser window anymore when keywords are chosen (Bug #141) +- fix almost unrestricted fast upload (Bug #175) +- no more php warning on Workflow summary page (Bug #177) +- various bug fixes in saving and searching for multi value attributes -------------------------------------------------------------------------------- Changes in version 4.3.10 diff --git a/Makefile b/Makefile index 0b6cb1182..ecb71b020 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -VERSION=4.3.10 +VERSION=4.3.11 SRC=CHANGELOG inc conf utils index.php languages views op out controllers README.md README.Notification README.Ubuntu drop-tables-innodb.sql styles js TODO LICENSE Makefile webdav install restapi # webapp diff --git a/SeedDMS_Core/Core/inc.ClassAttribute.php b/SeedDMS_Core/Core/inc.ClassAttribute.php index 9fc49eb6f..bbce8671b 100644 --- a/SeedDMS_Core/Core/inc.ClassAttribute.php +++ b/SeedDMS_Core/Core/inc.ClassAttribute.php @@ -91,8 +91,33 @@ class SeedDMS_Core_Attribute { /* {{{ */ function getID() { return $this->_id; } + /** + * Return attribute value as stored in database + * + * This function will return the value of multi value attributes + * including the separator char. + * + * @return string the attribute value as it is stored in the database. + */ function getValue() { return $this->_value; } + /** + * Return attribute values as an array + * + * This function returns the attribute value as an array. Such an array + * has one element for non multi value attributes and n elements for + * multi value attributes. + * + * @return array the attribute values + */ + function getValueAsArray() { /* {{{ */ + if($this->_attrdef->getMultipleValues()) { + return explode($this->_value[0], substr($this->_value, 1)); + } else { + return array($this->_value); + } + } /* }}} */ + /** * Set a value of an attribute * The attribute is deleted completely if the value is the empty string diff --git a/SeedDMS_Core/Core/inc.ClassDMS.php b/SeedDMS_Core/Core/inc.ClassDMS.php index 618b0ca8b..9f841007b 100644 --- a/SeedDMS_Core/Core/inc.ClassDMS.php +++ b/SeedDMS_Core/Core/inc.ClassDMS.php @@ -243,7 +243,7 @@ class SeedDMS_Core_DMS { $this->convertFileTypes = array(); $this->version = '@package_version@'; if($this->version[0] == '@') - $this->version = '4.3.10'; + $this->version = '4.3.11'; } /* }}} */ function getDB() { /* {{{ */ @@ -550,7 +550,9 @@ class SeedDMS_Core_DMS { * @param modificationstartdate array search for documents modified after this date * @param modificationenddate array search for documents modified before this date * @param categories array list of categories the documents must have assigned - * @param attributes array list of attributes + * @param attributes array list of attributes. The key of this array is the + * attribute definition id. The value of the array is the value of the + * attribute. If the attribute may have multiple values it must be an array. * @param mode int decide whether to search for documents/folders * 0x1 = documents only * 0x2 = folders only @@ -623,10 +625,13 @@ class SeedDMS_Core_DMS { foreach($attributes as $attrdefid=>$attribute) { if($attribute) { $attrdef = $this->getAttributeDefinition($attrdefid); - if($attrdef->getObjType() == SeedDMS_Core_AttributeDefinition::objtype_folder) { - if($attrdef->getValueSet()) - $searchAttributes[] = "`tblFolderAttributes`.`attrdef`=".$attrdefid." AND `tblFolderAttributes`.`value`='".$attribute."'"; - else + if($attrdef->getObjType() == SeedDMS_Core_AttributeDefinition::objtype_folder || $attrdef->getObjType() == SeedDMS_Core_AttributeDefinition::objtype_all) { + if($valueset = $attrdef->getValueSet()) { + if($attrdef->getMultipleValues()) { + $searchAttributes[] = "`tblFolderAttributes`.`attrdef`=".$attrdefid." AND (`tblFolderAttributes`.`value` like '".$valueset[0].implode("%' OR `tblFolderAttributes`.`value` like '".$valueset[0], $attribute)."%')"; + } else + $searchAttributes[] = "`tblFolderAttributes`.`attrdef`=".$attrdefid." AND `tblDocumentAttributes`.`value`='".$attribute."'"; + } else $searchAttributes[] = "`tblFolderAttributes`.`attrdef`=".$attrdefid." AND `tblFolderAttributes`.`value` like '%".$attribute."%'"; } } @@ -783,10 +788,13 @@ class SeedDMS_Core_DMS { foreach($attributes as $attrdefid=>$attribute) { if($attribute) { $attrdef = $this->getAttributeDefinition($attrdefid); - if($attrdef->getObjType() == SeedDMS_Core_AttributeDefinition::objtype_document) { - if($attrdef->getValueSet()) - $searchAttributes[] = "`tblDocumentAttributes`.`attrdef`=".$attrdefid." AND `tblDocumentAttributes`.`value`='".$attribute."'"; - else + if($attrdef->getObjType() == SeedDMS_Core_AttributeDefinition::objtype_document || $attrdef->getObjType() == SeedDMS_Core_AttributeDefinition::objtype_all) { + if($valueset = $attrdef->getValueSet()) { + if($attrdef->getMultipleValues()) { + $searchAttributes[] = "`tblDocumentAttributes`.`attrdef`=".$attrdefid." AND (`tblDocumentAttributes`.`value` like '".$valueset[0].implode("%' OR `tblDocumentAttributes`.`value` like '".$valueset[0], $attribute)."%')"; + } else + $searchAttributes[] = "`tblDocumentAttributes`.`attrdef`=".$attrdefid." AND `tblDocumentAttributes`.`value`='".$attribute."'"; + } else $searchAttributes[] = "`tblDocumentAttributes`.`attrdef`=".$attrdefid." AND `tblDocumentAttributes`.`value` like '%".$attribute."%'"; } elseif($attrdef->getObjType() == SeedDMS_Core_AttributeDefinition::objtype_documentcontent) { if($attrdef->getValueSet()) diff --git a/SeedDMS_Core/Core/inc.ClassFolder.php b/SeedDMS_Core/Core/inc.ClassFolder.php index a4ede97ae..d69eeb697 100644 --- a/SeedDMS_Core/Core/inc.ClassFolder.php +++ b/SeedDMS_Core/Core/inc.ClassFolder.php @@ -451,7 +451,7 @@ class SeedDMS_Core_Folder extends SeedDMS_Core_Object { if($attributes) { foreach($attributes as $attrdefid=>$attribute) { - if(trim($attribute)) + if($attribute) if(!$newFolder->setAttributeValue($this->_dms->getAttributeDefinition($attrdefid), $attribute)) { $db->rollbackTransaction(); return false; @@ -750,7 +750,8 @@ class SeedDMS_Core_Folder extends SeedDMS_Core_Object { if($attributes) { foreach($attributes as $attrdefid=>$attribute) { - if(trim($attribute)) + /* $attribute can be a string or an array */ + if($attribute) if(!$document->setAttributeValue($this->_dms->getAttributeDefinition($attrdefid), $attribute)) { $document->remove(); $db->rollbackTransaction(); diff --git a/SeedDMS_Core/package.xml b/SeedDMS_Core/package.xml index fbf53e2bf..77464e2a9 100644 --- a/SeedDMS_Core/package.xml +++ b/SeedDMS_Core/package.xml @@ -12,11 +12,11 @@ uwe@steinmann.cx yes - 2014-10-22 - + 2014-11-13 + - 4.3.10 - 4.3.10 + 4.3.11 + 4.3.11 stable @@ -24,7 +24,8 @@ GPL License -new release +- fixed saving multivalue attributes +- add method SeedDMS_Core_Attribute::getValueAsArray() @@ -700,5 +701,21 @@ no changes - SeedDMS_Core_DMS::addUser() doesn't throw an error if sql_mode is set to STRICT_TRANS_TABLES and pwdexpiration is not set to a valid date. + + 2014-10-22 + + + 4.3.10 + 4.3.10 + + + stable + stable + + GPL License + +new release + + diff --git a/inc/inc.Version.php b/inc/inc.Version.php index c93133b05..9bc073a3a 100644 --- a/inc/inc.Version.php +++ b/inc/inc.Version.php @@ -20,7 +20,7 @@ class SeedDMS_Version { - public $_number = "4.3.10"; + public $_number = "4.3.11"; private $_string = "SeedDMS"; function SeedDMS_Version() { diff --git a/install/install.php b/install/install.php index 5b2bdbbdc..cf35141c9 100644 --- a/install/install.php +++ b/install/install.php @@ -116,7 +116,7 @@ function fileExistsInIncludePath($file) { /* {{{ */ * Load default settings + set */ define("SEEDDMS_INSTALL", "on"); -define("SEEDDMS_VERSION", "4.3.10"); +define("SEEDDMS_VERSION", "4.3.11"); require_once('../inc/inc.ClassSettings.php'); diff --git a/op/op.Ajax.php b/op/op.Ajax.php index 766e647b1..4040e26ec 100644 --- a/op/op.Ajax.php +++ b/op/op.Ajax.php @@ -462,6 +462,20 @@ switch($command) { echo json_encode(array('success'=>false, 'message'=>getMLText("invalid_folder_id"))); exit; } + + if ($folder->getAccessMode($user) < M_READWRITE) { + echo json_encode(array('success'=>false, 'message'=>getMLText("access_denied"))); + exit; + } + + if($settings->_quota > 0) { + $remain = checkQuota($user); + if ($remain < 0) { + echo json_encode(array('success'=>false, 'message'=>getMLText("quota_exceeded", array('bytes'=>SeedDMS_Core_File::format_filesize(abs($remain)))))); + exit; + } + } + if (!is_uploaded_file($_FILES["userfile"]["tmp_name"]) || $_FILES['userfile']['error']!=0){ header('Content-Type', 'application/json'); echo json_encode(array('success'=>false, 'message'=>getMLText("uploading_failed"))); diff --git a/op/op.Search.php b/op/op.Search.php index 23fd2a6c4..637cc3cc7 100644 --- a/op/op.Search.php +++ b/op/op.Search.php @@ -437,7 +437,7 @@ if(count($entries) == 1 && ($resArr['totalDocs'] + $resArr['totalFolders']) == 1 $view->setParam('status', isset($status) ? $status : array()); $view->setParam('categories', isset($categories) ? $categories : ''); $view->setParam('attributes', isset($attributes) ? $attributes : ''); - $attrdefs = $dms->getAllAttributeDefinitions(array(SeedDMS_Core_AttributeDefinition::objtype_document, SeedDMS_Core_AttributeDefinition::objtype_documentcontent, SeedDMS_Core_AttributeDefinition::objtype_folder/*, SeedDMS_Core_AttributeDefinition::objtype_all*/)); + $attrdefs = $dms->getAllAttributeDefinitions(array(SeedDMS_Core_AttributeDefinition::objtype_document, SeedDMS_Core_AttributeDefinition::objtype_documentcontent, SeedDMS_Core_AttributeDefinition::objtype_folder, SeedDMS_Core_AttributeDefinition::objtype_all)); $view->setParam('attrdefs', $attrdefs); $allCats = $dms->getDocumentCategories(); $view->setParam('allcategories', $allCats); diff --git a/out/out.RewindWorkflow.php b/out/out.RewindWorkflow.php index d34bc1bdd..da77424ff 100644 --- a/out/out.RewindWorkflow.php +++ b/out/out.RewindWorkflow.php @@ -23,6 +23,7 @@ include("../inc/inc.Utils.php"); include("../inc/inc.DBInit.php"); include("../inc/inc.Language.php"); include("../inc/inc.ClassUI.php"); +include("../inc/inc.ClassAccessOperation.php"); include("../inc/inc.Authentication.php"); if (!$user->isAdmin()) { @@ -56,9 +57,13 @@ if (!is_object($workflow)) { $folder = $document->getFolder(); +/* Create object for checking access to certain operations */ +$accessop = new SeedDMS_AccessOperation($document, $user, $settings); + $tmp = explode('.', basename($_SERVER['SCRIPT_FILENAME'])); $view = UI::factory($theme, $tmp[1], array('dms'=>$dms, 'user'=>$user, 'folder'=>$folder, 'document'=>$document, 'version'=>$version)); if($view) { + $view->setParam('accessobject', $accessop); $view->show(); exit; } diff --git a/out/out.RunSubWorkflow.php b/out/out.RunSubWorkflow.php index c644ecfab..52d5d0618 100644 --- a/out/out.RunSubWorkflow.php +++ b/out/out.RunSubWorkflow.php @@ -23,6 +23,7 @@ include("../inc/inc.Utils.php"); include("../inc/inc.DBInit.php"); include("../inc/inc.Language.php"); include("../inc/inc.ClassUI.php"); +include("../inc/inc.ClassAccessOperation.php"); include("../inc/inc.Authentication.php"); if (!isset($_POST["documentid"]) || !is_numeric($_POST["documentid"]) || intval($_POST["documentid"])<1) { @@ -61,9 +62,13 @@ if (!is_object($subworkflow)) { $folder = $document->getFolder(); +/* Create object for checking access to certain operations */ +$accessop = new SeedDMS_AccessOperation($document, $user, $settings); + $tmp = explode('.', basename($_SERVER['SCRIPT_FILENAME'])); $view = UI::factory($theme, $tmp[1], array('dms'=>$dms, 'user'=>$user, 'folder'=>$folder, 'document'=>$document, 'version'=>$version, 'subworkflow'=>$subworkflow)); if($view) { + $view->setParam('accessobject', $accessop); $view->show(); exit; } diff --git a/out/out.WorkflowSummary.php b/out/out.WorkflowSummary.php index 2fc76f127..c45889051 100644 --- a/out/out.WorkflowSummary.php +++ b/out/out.WorkflowSummary.php @@ -35,7 +35,7 @@ if ($user->isGuest()) { } $tmp = explode('.', basename($_SERVER['SCRIPT_FILENAME'])); -$view = UI::factory($theme, $tmp[1], array('dms'=>$dms, 'user'=>$user, 'cachedir'=>$settings->_cacheDir, 'workflowmode'=>$settings->_workflowMode, 'previewwidthlist'=>$settings->_previewWidthList)); +$view = UI::factory($theme, $tmp[1], array('dms'=>$dms, 'user'=>$user, 'cachedir'=>$settings->_cacheDir, 'workflowmode'=>$settings->_workflowMode, 'previewWidthList'=>$settings->_previewWidthList)); if($view) { $view->show(); exit; diff --git a/views/bootstrap/class.Bootstrap.php b/views/bootstrap/class.Bootstrap.php index a53c6480d..24702cd8c 100644 --- a/views/bootstrap/class.Bootstrap.php +++ b/views/bootstrap/class.Bootstrap.php @@ -77,7 +77,8 @@ background-image: linear-gradient(to bottom, #882222, #111111);; ".(strlen($this->params['sitename'])>0 ? $this->params['sitename'] : "SeedDMS").(strlen($title)>0 ? ": " : "").htmlspecialchars($title)."\n"; + $sitename = trim(strip_tags($this->params['sitename'])); + echo "".(strlen($sitename)>0 ? $sitename : "SeedDMS").(strlen($title)>0 ? ": " : "").htmlspecialchars($title)."\n"; echo "\n"; echo "0 ? " class=\"".$bodyClass."\"" : "").">\n"; if($this->params['session'] && $flashmsg = $this->params['session']->getSplashMsg()) { diff --git a/views/bootstrap/class.DocumentVersionDetail.php b/views/bootstrap/class.DocumentVersionDetail.php index 86b6a8d5d..cb8cdb3e9 100644 --- a/views/bootstrap/class.DocumentVersionDetail.php +++ b/views/bootstrap/class.DocumentVersionDetail.php @@ -120,7 +120,7 @@ class SeedDMS_View_DocumentVersionDetail extends SeedDMS_Bootstrap_Style { ?> getName()); ?>: - getValue()); ?> + getValueAsArray())); ?> + +getObjType() == SeedDMS_Core_AttributeDefinition::objtype_all) { +?> + + getName()); ?>: + printAttributeEditField($attrdef, isset($attributes[$attrdef->getID()]) ? $attributes[$attrdef->getID()] : '') ?> + + + + @@ -462,7 +480,7 @@ class SeedDMS_View_Search extends SeedDMS_Bootstrap_Style { if($lcattributes) { foreach($lcattributes as $lcattribute) { $attrdef = $lcattribute->getAttributeDefinition(); - print "
  • ".htmlspecialchars($attrdef->getName()).": ".htmlspecialchars($lcattribute->getValue())."
  • \n"; + print "
  • ".htmlspecialchars($attrdef->getName()).": ".htmlspecialchars(implode(', ', $lcattribute->getValueAsArray()))."
  • \n"; } } print "\n"; @@ -471,7 +489,7 @@ class SeedDMS_View_Search extends SeedDMS_Bootstrap_Style { if($docttributes) { foreach($docttributes as $docttribute) { $attrdef = $docttribute->getAttributeDefinition(); - print "
  • ".htmlspecialchars($attrdef->getName()).": ".htmlspecialchars($docttribute->getValue())."
  • \n"; + print "
  • ".htmlspecialchars($attrdef->getName()).": ".htmlspecialchars(implode(', ', $docttribute->getValueAsArray()))."
  • \n"; } } print "\n"; @@ -537,7 +555,7 @@ class SeedDMS_View_Search extends SeedDMS_Bootstrap_Style { if($folderattributes) { foreach($folderattributes as $folderattribute) { $attrdef = $folderattribute->getAttributeDefinition(); - print "
  • ".htmlspecialchars($attrdef->getName()).": ".htmlspecialchars($folderattribute->getValue())."
  • \n"; + print "
  • ".htmlspecialchars($attrdef->getName()).": ".htmlspecialchars(implode(', ', $folderattribute->getValueAsArray()))."
  • \n"; } } print ""; diff --git a/views/bootstrap/class.ViewDocument.php b/views/bootstrap/class.ViewDocument.php index f25fc40e7..9c5958ac9 100644 --- a/views/bootstrap/class.ViewDocument.php +++ b/views/bootstrap/class.ViewDocument.php @@ -242,7 +242,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { ?> getName()); ?>: - getValue()); ?> + getValueAsArray())); ?> getAttributeDefinition(); - print "
  • ".htmlspecialchars($attrdef->getName()).": ".htmlspecialchars($attribute->getValue())."
  • \n"; + print "
  • ".htmlspecialchars($attrdef->getName()).": ".htmlspecialchars(implode(', ', $attribute->getValueAsArray()))."
  • \n"; } } print "\n"; @@ -710,7 +710,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { if(SeedDMS_Core_DMS::checkIfEqual($workflow->getInitState(), $latestContent->getWorkflowState())) { print "
    ".createHiddenFieldWithKey('removeworkflowfromdocument')."getVersion()."\" />
    "; } else { - print "
    ".createHiddenFieldWithKey('rewindworkflow')."getVersion()."\" />
    "; + print "
    ".createHiddenFieldWithKey('rewindworkflow')."getVersion()."\" />
    "; } } @@ -934,7 +934,7 @@ class SeedDMS_View_ViewDocument extends SeedDMS_Bootstrap_Style { if($attributes) { foreach($attributes as $attribute) { $attrdef = $attribute->getAttributeDefinition(); - print "
  • ".htmlspecialchars($attrdef->getName()).": ".htmlspecialchars($attribute->getValue())."
  • \n"; + print "
  • ".htmlspecialchars($attrdef->getName()).": ".htmlspecialchars(implode(', ', $attribute->getValueAsArray()))."
  • \n"; } } print "\n"; diff --git a/views/bootstrap/class.ViewFolder.php b/views/bootstrap/class.ViewFolder.php index 8b032a960..03b8997f3 100644 --- a/views/bootstrap/class.ViewFolder.php +++ b/views/bootstrap/class.ViewFolder.php @@ -146,7 +146,7 @@ class SeedDMS_View_ViewFolder extends SeedDMS_Bootstrap_Style { } echo "
    \n"; - if ($enableDropUpload) { + if ($enableDropUpload && $folder->getAccessMode($user) >= M_READWRITE) { echo "
    "; echo "
    "; } @@ -203,7 +203,7 @@ class SeedDMS_View_ViewFolder extends SeedDMS_Bootstrap_Style { ?> getName()); ?>: - getValue()); ?> + getValueAsArray())); ?> \n"; $this->contentContainerEnd(); } - if ($enableDropUpload) { + if ($enableDropUpload && $folder->getAccessMode($user) >= M_READWRITE) { echo "
    "; echo "
    "; $this->contentHeading(getMLText("dropupload"), true);