From 82d24098aa36f8d1f979733e3b419d738ae490c9 Mon Sep 17 00:00:00 2001 From: Uwe Steinmann Date: Fri, 18 Jul 2025 10:14:12 +0200 Subject: [PATCH 01/10] better formating, more info for AD --- doc/README.Ldap | 82 ++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 67 insertions(+), 15 deletions(-) diff --git a/doc/README.Ldap b/doc/README.Ldap index 3d73d57af..7c354646d 100644 --- a/doc/README.Ldap +++ b/doc/README.Ldap @@ -10,25 +10,27 @@ regular ldap server, e.g. openldap The location of the ldap server is specified in two parameters: `host` and `port`. `host` can be either a plain hostname or an ldap URI, including the -protocol, the host and optionally the port, e.g. ldap://localhost:389. In case +protocol, the host and optionally the port, e.g. `ldap://localhost:389`. In case of an URI the port in the configuration must remain empty. The authentication itself is a two step process which differs, depending on how -to bind to the server. If the configuration sets 'bindDN' and 'bindPW', those +to bind to the server. If the configuration sets `bindDN` and `bindPW`, those values will be used for a initial non anonymous bind to the ldap server otherwise an anonymous bind is executed. -After the initial bind, a ldap search for either 'uid=' (ldap) or -'sAMAccountName=' (AD) below basedn is done. The purpose of this +After the initial bind, a ldap search for either `uid=` (ldap) or +`sAMAccountName=` (AD) below basedn is done. The purpose of this search is to retrieve a working bindDN which is then used to actually -authenticate the user. In case of an anonymous first bind the search will -likely fail and the bindDN for the second bind will be either -'uid=,' (ldap) or '@' (AD). If -the search succeeds the bindDN will be taken from the user's data in the ldap +authenticate the user. In case of a successful anonymous first bind but a +failed search (this seems to be the case when connecting to an AD), a second +non anonymous bind is tried. The bindDN for that second bind will be either +`uid=,` (ldap) or `@` (AD). +If the search after the first anonymous bind succeeds, the bindDN will be +taken from the user's data in the ldap server. This bindDN will be used for a second bind using the users password. -If the second bind succeeds the user could be successfully authenticated. +If the second bind succeeds the user is successfully authenticated. -The data from the ldap server can be used to create an account in SeedDMS +The data from the ldap server can be used to create or update an account in SeedDMS if the user trying to login does not exist yet, but was able to authenticate. This will only be done if 'authentication->restricted' in the configuration is set to false. In that case the common name (cn) and email address is taken @@ -41,12 +43,37 @@ can be set with the attribute `mailField`. If it is not set it defaults to `mail Since version 5.1.34 and 6.0.27 the groups of a user stored in the ldap directory can be synchronised with the groups in SeedDMS. The ldap field storing the groups can be configured with the attribute `mailField`. This will add -new groups in SeedDMS and aѕsign them to the user. +new groups in SeedDMS and assign them to the user. + +Using email address for authentication +--------------------------------------- + +Since version 5.1.34 and 6.0.27 the email can be used for authentication +(requires `enableLoginByEmail` to be set in the configuration). +This only works if the search after the first bind succeeds, which is usually +only the case if it is a none anonymous bind. + +Notes on connecting to an AD +----------------------------- + +The ldap authentication was originally implemented for classic LDAP servers +like openldap. Before doing the actual authentication the user was searched +by combining the user's login name and the configured baseDN. This search was +preceded an anonymous or non anonymous bind (depending on wether bindDN and +bindPWD are set). The only purpose of that search was to retrieve the +distinguished name of the user, which was used in a second non anonymous bind +for authenticating the user. If that search fails or didn't return a record +(which seems to be always the case for an anonymous bind to an AD) +a second non anonymous bind with the user's credentials is tried. That bind +uses a dn which is quite different for classic ldap and AD (see examples +below). The dn for an AD is of the form '@'. '' is +the string configured in the parameter `accountDomainName`. Examples --------- -Anonymous bind to openldap on localhost, port 389 +### Anonymous bind to openldap on localhost, port 389 + - type = "ldap" - baseDN = "ou=users,dc=mycompany,dc=de" - host = "ldap://localhost" @@ -55,12 +82,37 @@ During authentication as user 'admin' the following steps are executed 1. connect to ldap server at localhost:389 2. do an anonymous bind -3. search for 'uid=admin' below basedn +3.1 if the bind succeeds, search for `uid=admin` below basedn +3.2 if the bind fails use `uid=admin,` as dn and continue with step 5 4.1. if search succeeds use the dn from the user -4.2. if search fails use 'uid=admin,' as dn +4.2. if search fails use `uid=admin,` as dn 5. do a non anonymous bind with dn and password entered by user -6. if step 5. succeeds the use is authenticated +6. if step 5. succeeds the user is authenticated +7. if `restricted` in the settings is *not* set another ldap search for the + user is executed to retrieve the full name, and the email and if +8.1 the user doesn't exist in SeedDMS, the user will be created or +8.2 the user exists in SeedDMS, the use will be updated If bindDN and bindPW are specified in the configuration, the second step will be a non anonymous bind. +### Connecting to an AD + +- type = "AD" +- baseDN = "ou=users,dc=mycompany,dc=de" +- accountDomainName=mycompany +- host = "ldap://localhost" + +During authentication as user 'admin' the following steps are executed + +1. connect to AD server at localhost:389 +2. do an anonymous bind (which usually succeeds) +3. search for `uid=admin` below basedn (which usually returns an empty record) +4. if search returns no data use `admin@` as dn +5. do a non anonymous bind with dn and password entered by user +6. if step 5. succeeds the user is authenticated +7. if `restricted` in the settings is *not* set another ldap search for the + user is executed to retrieve the full name, and the email and if +8.1 the user doesn't exist in SeedDMS, the user will be created or +8.2 the user exists in SeedDMS, the use will be updated + From 45eda343d93ccd121d86beefc09d8900646a8fe2 Mon Sep 17 00:00:00 2001 From: Uwe Steinmann Date: Fri, 18 Jul 2025 10:14:31 +0200 Subject: [PATCH 02/10] fix typo --- inc/inc.ClassLdapAuthentication.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inc/inc.ClassLdapAuthentication.php b/inc/inc.ClassLdapAuthentication.php index 7ca786a1b..9ac1944dc 100644 --- a/inc/inc.ClassLdapAuthentication.php +++ b/inc/inc.ClassLdapAuthentication.php @@ -233,7 +233,7 @@ class SeedDMS_LdapAuthentication extends SeedDMS_Authentication { } /* Check if user already exists in the database. Return with an error - * only if the sql statements fails, but not if no user was found. + * only if the sql statements fails, but not if the user wasn't found. * The username may not be the one passed to this function anymore. It * could have been overwritten by uid (or sAMAccountName) derived from * the above ldap search. From f96966935604f23471e2efbb799dca112d78fff8 Mon Sep 17 00:00:00 2001 From: Uwe Steinmann Date: Fri, 18 Jul 2025 16:50:32 +0200 Subject: [PATCH 03/10] no php warning if company of author isn't set in conf.php --- views/bootstrap/class.ExtensionMgr.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/views/bootstrap/class.ExtensionMgr.php b/views/bootstrap/class.ExtensionMgr.php index 079bf6597..2a3e6aacb 100644 --- a/views/bootstrap/class.ExtensionMgr.php +++ b/views/bootstrap/class.ExtensionMgr.php @@ -251,7 +251,7 @@ class SeedDMS_View_ExtensionMgr extends SeedDMS_Theme_Style { echo ""; echo "".$extconf['title']; echo "
".$extconf['description'].""; - echo "
".getMLText('author').": ".$extconf['author']['name'].", ".$extconf['author']['company'].""; + echo "
".getMLText('author').": ".$extconf['author']['name'].", ".(!empty($extconf['author']['company']) ? $extconf['author']['company'] : '').""; if($errmsgs) echo "
getImgPath("attention.gif")."\"> ".implode('
', $errmsgs)."
"; echo ""; From 30880c0539a19a9f199c40463c2df3c9f1866d27 Mon Sep 17 00:00:00 2001 From: Uwe Steinmann Date: Wed, 23 Jul 2025 20:05:57 +0200 Subject: [PATCH 04/10] move sending notification into sendChangedVersionAttributesMail() --- inc/inc.ClassNotificationService.php | 58 ++++++++++++++++++++++++++++ op/op.EditAttributes.php | 57 +-------------------------- 2 files changed, 60 insertions(+), 55 deletions(-) diff --git a/inc/inc.ClassNotificationService.php b/inc/inc.ClassNotificationService.php index aed192af5..edb301018 100644 --- a/inc/inc.ClassNotificationService.php +++ b/inc/inc.ClassNotificationService.php @@ -683,6 +683,64 @@ class SeedDMS_NotificationService { } } /* }}} */ + public function sendChangedVersionAttributesMail($version, $user, $oldattributes) { /* {{{ */ + $document = $version->getDocument(); + $dms = $document->getDMS(); + $folder = $document->getFolder(); + $notifyList = $document->getNotifyList(); + + $newattributes = $version->getAttributes(); + if($oldattributes) { + foreach($oldattributes as $attrdefid=>$attribute) { + if(!isset($newattributes[$attrdefid]) || $newattributes[$attrdefid]->getValueAsArray() !== $oldattributes[$attrdefid]->getValueAsArray()) { + $subject = "attribute_changed_email_subject"; + $message = "attribute_changed_email_body"; + $params = array(); + $params['name'] = $document->getName(); + $params['version'] = $version->getVersion(); + $params['attribute_name'] = $attribute->getAttributeDefinition()->getName(); + $params['attribute_old_value'] = $oldattributes[$attrdefid]->getValue(); + $params['attribute_new_value'] = isset($newattributes[$attrdefid]) ? $newattributes[$attrdefid]->getValue() : ''; + $params['folder_path'] = $folder->getFolderPathPlain(); + $params['username'] = $user->getFullName(); + $params['url'] = getBaseUrl().$this->settings->_httpRoot."out/out.ViewDocument.php?documentid=".$document->getID(); + $params['sitename'] = $this->settings->_siteName; + $params['http_root'] = $this->settings->_httpRoot; + + $this->toList($user, $notifyList["users"], $subject, $message, $params, SeedDMS_NotificationService::RECV_NOTIFICATION); + foreach ($notifyList["groups"] as $grp) { + $this->toGroup($user, $grp, $subject, $message, $params, SeedDMS_NotificationService::RECV_NOTIFICATION); + } + } + } + } + /* Check for new attributes which didn't have a value before */ + if($newattributes) { + foreach($newattributes as $attrdefid=>$attribute) { + if(!isset($oldattributes[$attrdefid]) && $attribute) { + $subject = "attribute_changed_email_subject"; + $message = "attribute_changed_email_body"; + $params = array(); + $params['name'] = $document->getName(); + $params['version'] = $version->getVersion(); + $params['attribute_name'] = $dms->getAttributeDefinition($attrdefid)->getName(); + $params['attribute_old_value'] = ''; + $params['attribute_new_value'] = $attribute->getValue(); + $params['folder_path'] = $folder->getFolderPathPlain(); + $params['username'] = $user->getFullName(); + $params['url'] = getBaseUrl().$this->settings->_httpRoot."out/out.ViewDocument.php?documentid=".$document->getID(); + $params['sitename'] = $this->settings->_siteName; + $params['http_root'] = $this->settings->_httpRoot; + + $this->toList($user, $notifyList["users"], $subject, $message, $params, SeedDMS_NotificationService::RECV_NOTIFICATION); + foreach ($notifyList["groups"] as $grp) { + $this->toGroup($user, $grp, $subject, $message, $params, SeedDMS_NotificationService::RECV_NOTIFICATION); + } + } + } + } + } /* }}} */ + public function sendChangedFolderAttributesMail($folder, $user, $oldattributes) { /* {{{ */ $dms = $folder->getDMS(); $notifyList = $folder->getNotifyList(); diff --git a/op/op.EditAttributes.php b/op/op.EditAttributes.php index 7476c68d8..40cbf9c5a 100644 --- a/op/op.EditAttributes.php +++ b/op/op.EditAttributes.php @@ -123,61 +123,8 @@ if($attributes) { } } -$newattributes = $version->getAttributes(); -if($oldattributes) { - foreach($oldattributes as $attrdefid=>$attribute) { - if(!isset($newattributes[$attrdefid]) || $newattributes[$attrdefid]->getValueAsArray() !== $oldattributes[$attrdefid]->getValueAsArray()) { - if($notifier) { - $notifyList = $document->getNotifyList(); - $subject = "attribute_changed_email_subject"; - $message = "attribute_changed_email_body"; - $params = array(); - $params['name'] = $document->getName(); - $params['version'] = $version->getVersion(); - $params['attribute_name'] = $attribute->getAttributeDefinition()->getName(); - $params['attribute_old_value'] = $oldattributes[$attrdefid]->getValue(); - $params['attribute_new_value'] = isset($newattributes[$attrdefid]) ? $newattributes[$attrdefid]->getValue() : ''; - $params['folder_path'] = $folder->getFolderPathPlain(); - $params['username'] = $user->getFullName(); - $params['url'] = getBaseUrl().$settings->_httpRoot."out/out.ViewDocument.php?documentid=".$document->getID(); - $params['sitename'] = $settings->_siteName; - $params['http_root'] = $settings->_httpRoot; - - $notifier->toList($user, $notifyList["users"], $subject, $message, $params, SeedDMS_NotificationService::RECV_NOTIFICATION); - foreach ($notifyList["groups"] as $grp) { - $notifier->toGroup($user, $grp, $subject, $message, $params, SeedDMS_NotificationService::RECV_NOTIFICATION); - } - } - } - } -} -/* Check for new attributes which didn't have a value before */ -if($newattributes) { - foreach($newattributes as $attrdefid=>$attribute) { - if(!isset($oldattributes[$attrdefid]) && $attribute) { - if($notifier) { - $notifyList = $document->getNotifyList(); - $subject = "attribute_changed_email_subject"; - $message = "attribute_changed_email_body"; - $params = array(); - $params['name'] = $document->getName(); - $params['version'] = ''; - $params['attribute_name'] = $dms->getAttributeDefinition($attrdefid)->getName(); - $params['attribute_old_value'] = ''; - $params['attribute_new_value'] = $attribute->getValue(); - $params['folder_path'] = $folder->getFolderPathPlain(); - $params['username'] = $user->getFullName(); - $params['url'] = getBaseUrl().$settings->_httpRoot."out/out.ViewDocument.php?documentid=".$document->getID(); - $params['sitename'] = $settings->_siteName; - $params['http_root'] = $settings->_httpRoot; - - $notifier->toList($user, $notifyList["users"], $subject, $message, $params, SeedDMS_NotificationService::RECV_NOTIFICATION); - foreach ($notifyList["groups"] as $grp) { - $notifier->toGroup($user, $grp, $subject, $message, $params, SeedDMS_NotificationService::RECV_NOTIFICATION); - } - } - } - } +if($notifier) { + $notifier->sendChangedVersionAttributesMail($version, $user, $oldattributes); } add_log_line("?documentid=".$documentid); From 593c6f5f952c828ebdabe9d8bfde3df1356660a3 Mon Sep 17 00:00:00 2001 From: Uwe Steinmann Date: Wed, 23 Jul 2025 20:06:34 +0200 Subject: [PATCH 05/10] check if attr definition exists when building a search query from an url --- inc/inc.Utils.php | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/inc/inc.Utils.php b/inc/inc.Utils.php index 9f5841388..9e644f8c1 100644 --- a/inc/inc.Utils.php +++ b/inc/inc.Utils.php @@ -1822,16 +1822,17 @@ class SeedDMS_Search { /* {{{ */ $attributes = array(); foreach($attributes as $attrdefid=>$attribute) { - $attrdef = $this->dms->getAttributeDefinition($attrdefid); if($attribute) { - if($attrdef->getType() == SeedDMS_Core_AttributeDefinition::type_date) { - if(is_array($attribute)) { - if(!empty($attributes[$attrdefid]['from'])) - $attributes[$attrdefid]['from'] = date('Y-m-d', makeTsFromDate($attribute['from'])); - if(!empty($attributes[$attrdefid]['to'])) - $attributes[$attrdefid]['to'] = date('Y-m-d', makeTsFromDate($attribute['to'])); - } else { - $attributes[$attrdefid] = date('Y-m-d', makeTsFromDate($attribute)); + if($attrdef = $this->dms->getAttributeDefinition($attrdefid)) { + if($attrdef->getType() == SeedDMS_Core_AttributeDefinition::type_date) { + if(is_array($attribute)) { + if(!empty($attributes[$attrdefid]['from'])) + $attributes[$attrdefid]['from'] = date('Y-m-d', makeTsFromDate($attribute['from'])); + if(!empty($attributes[$attrdefid]['to'])) + $attributes[$attrdefid]['to'] = date('Y-m-d', makeTsFromDate($attribute['to'])); + } else { + $attributes[$attrdefid] = date('Y-m-d', makeTsFromDate($attribute)); + } } } } From 00a5f59bc3e471b87da919ed01b23996143e6708 Mon Sep 17 00:00:00 2001 From: Uwe Steinmann Date: Wed, 23 Jul 2025 20:07:35 +0200 Subject: [PATCH 06/10] check if attr definition exists when building a search query --- out/out.Search.php | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/out/out.Search.php b/out/out.Search.php index 3aaf8df99..d2de6d74c 100644 --- a/out/out.Search.php +++ b/out/out.Search.php @@ -535,16 +535,17 @@ if($fullsearch) { $attributes = array(); foreach($attributes as $attrdefid=>$attribute) { - $attrdef = $dms->getAttributeDefinition($attrdefid); if($attribute) { - if($attrdef->getType() == SeedDMS_Core_AttributeDefinition::type_date) { - if(is_array($attribute)) { - if(!empty($attributes[$attrdefid]['from'])) - $attributes[$attrdefid]['from'] = date('Y-m-d', makeTsFromDate($attribute['from'])); - if(!empty($attributes[$attrdefid]['to'])) - $attributes[$attrdefid]['to'] = date('Y-m-d', makeTsFromDate($attribute['to'])); - } else { - $attributes[$attrdefid] = date('Y-m-d', makeTsFromDate($attribute)); + if($attrdef = $dms->getAttributeDefinition($attrdefid)) { + if($attrdef->getType() == SeedDMS_Core_AttributeDefinition::type_date) { + if(is_array($attribute)) { + if(!empty($attributes[$attrdefid]['from'])) + $attributes[$attrdefid]['from'] = date('Y-m-d', makeTsFromDate($attribute['from'])); + if(!empty($attributes[$attrdefid]['to'])) + $attributes[$attrdefid]['to'] = date('Y-m-d', makeTsFromDate($attribute['to'])); + } else { + $attributes[$attrdefid] = date('Y-m-d', makeTsFromDate($attribute)); + } } } } From ae635fba1add51123b59c8a088a39fe7acea58cf Mon Sep 17 00:00:00 2001 From: Uwe Steinmann Date: Wed, 23 Jul 2025 20:08:21 +0200 Subject: [PATCH 07/10] fix setting path to document below title --- views/bootstrap/class.AttributeMgr.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/views/bootstrap/class.AttributeMgr.php b/views/bootstrap/class.AttributeMgr.php index a026a9d96..9dbf982f3 100644 --- a/views/bootstrap/class.AttributeMgr.php +++ b/views/bootstrap/class.AttributeMgr.php @@ -182,7 +182,7 @@ $(document).ready( function() { foreach($res['contents'] as $content) { $document = $content->getDocument(); $extracontent = array(); - $extracontent['below_title'] = $this->getListRowPath($doc); + $extracontent['below_title'] = $this->getListRowPath($document); $txt = $this->callHook('documentListItem', $document, $previewer, false, 'attributemgr', $extracontent); if(is_string($txt)) echo $txt; From 04df8835825c4c81a00877476fa7e0cc71771090 Mon Sep 17 00:00:00 2001 From: Uwe Steinmann Date: Wed, 23 Jul 2025 20:09:30 +0200 Subject: [PATCH 08/10] add changes for 5.1.41 --- CHANGELOG | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG b/CHANGELOG index 062d77592..3a9bbbf91 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -4,6 +4,7 @@ - action when clicking on a thumbnail can be set (download or view online) - major update of polish translation - fix getting access rights in getMandatoryApprovers() and getMandatoryReviewers() +- better checking for attribute definition when build a search query -------------------------------------------------------------------------------- Changes in version 5.1.40 From 5c717cf6ba558e99788825ebbc15b75bfdb3beb9 Mon Sep 17 00:00:00 2001 From: Uwe Steinmann Date: Wed, 23 Jul 2025 22:52:23 +0200 Subject: [PATCH 09/10] remove old code --- op/op.EditDocument.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/op/op.EditDocument.php b/op/op.EditDocument.php index a9e630dba..270bdaf40 100644 --- a/op/op.EditDocument.php +++ b/op/op.EditDocument.php @@ -49,7 +49,6 @@ if (!is_object($document)) { } $folder = $document->getFolder(); -$docPathHTML = getFolderPathHTML($folder, true). " / ".$document->getName().""; if ($document->getAccessMode($user, 'editDocument') < M_READWRITE) { UI::exitError(getMLText("document_title", array("documentname" => $document->getName())),getMLText("access_denied")); @@ -125,7 +124,6 @@ $oldexpires = $document->getExpires(); $oldattributes = array(); foreach($document->getAttributes() as $ai=>$aa) $oldattributes[$ai] = clone $aa; -//$oldattributes = $document->getAttributes(); $controller->setParam('fulltextservice', $fulltextservice); $controller->setParam('document', $document); From 5bce2fa6fdfe9c05b119099229d3580495c77558 Mon Sep 17 00:00:00 2001 From: Uwe Steinmann Date: Wed, 23 Jul 2025 22:53:27 +0200 Subject: [PATCH 10/10] move code into controller --- controllers/class.EditAttributes.php | 123 +++++++++++++++++++++++++++ op/op.EditAttributes.php | 71 ++++------------ 2 files changed, 139 insertions(+), 55 deletions(-) create mode 100644 controllers/class.EditAttributes.php diff --git a/controllers/class.EditAttributes.php b/controllers/class.EditAttributes.php new file mode 100644 index 000000000..1df2c91e6 --- /dev/null +++ b/controllers/class.EditAttributes.php @@ -0,0 +1,123 @@ + + * @copyright Copyright (C) 2010-2013 Uwe Steinmann + * @version Release: @package_version@ + */ + +/** + * Class which does the busines logic for editing the version attributes + * + * @category DMS + * @package SeedDMS + * @author Uwe Steinmann + * @copyright Copyright (C) 2010-2025 Uwe Steinmann + * @version Release: @package_version@ + */ +class SeedDMS_Controller_EditAttributes extends SeedDMS_Controller_Common { + + public function run() { + $dms = $this->params['dms']; + $user = $this->params['user']; + $settings = $this->params['settings']; + $document = $this->params['document']; + $version = $this->params['version']; + + if(false === $this->callHook('preEditAttributes')) { + if(empty($this->errormsg)) + $this->errormsg = 'hook_preEditAttributes_failed'; + return null; + } + + $result = $this->callHook('editAttributes', $version); + if($result === null) { + $attributes = $this->params['attributes']; + $oldattributes = $version->getAttributes(); + if($attributes) { + foreach($attributes as $attrdefid=>$attribute) { + if($attrdef = $dms->getAttributeDefinition($attrdefid)) { + if(null === ($ret = $this->callHook('validateAttribute', $attrdef, $attribute))) { + if($attribute) { + switch($attrdef->getType()) { + case SeedDMS_Core_AttributeDefinition::type_date: + if(is_array($attribute)) + $attribute = array_map(fn($value): string => date('Y-m-d', makeTsFromDate($value)), $attribute); + else + $attribute = date('Y-m-d', makeTsFromDate($attribute)); + break; + case SeedDMS_Core_AttributeDefinition::type_folder: + if(is_array($attribute)) + $attribute = array_map(fn($value): object => $dms->getFolder((int) $value), $attribute); + else + $attribute = $dms->getFolder((int) $attribute); + break; + case SeedDMS_Core_AttributeDefinition::type_document: + if(is_array($attribute)) + $attribute = array_map(fn($value): object => $dms->getDocument((int) $value), $attribute); + else + $attribute = $dms->getDocument((int) $attribute); + break; + case SeedDMS_Core_AttributeDefinition::type_user: + if(is_array($attribute)) + $attribute = array_map(fn($value): object => $dms->getUser((int) $value), $attribute); + else + $attribute = $dms->getUser((int) $attribute); + break; + case SeedDMS_Core_AttributeDefinition::type_group: + if(is_array($attribute)) + $attribute = array_map(fn($value): object => $dms->getGroup((int) $value), $attribute); + else + $attribute = $dms->getGroup((int) $attribute); + break; + } + if(!$attrdef->validate($attribute, $version, false)) { + $this->errormsg = getAttributeValidationText($attrdef->getValidationError(), $attrdef->getName(), $attribute); + return false; + } + + if(!isset($oldattributes[$attrdefid]) || $attribute != $oldattributes[$attrdefid]->getValue()) { + if(!$version->setAttributeValue($dms->getAttributeDefinition($attrdefid), $attribute)) { + //UI::exitError(getMLText("document_title", array("documentname" => $document->getName())),getMLText("error_occured")); + return false; + } + } + } elseif($attrdef->getMinValues() > 0) { + $this->errormsg = array("attr_min_values", array("attrname"=>$attrdef->getName())); + return false; + } elseif(isset($oldattributes[$attrdefid])) { + if(!$version->removeAttribute($dms->getAttributeDefinition($attrdefid))) + // UI::exitError(getMLText("document_title", array("documentname" => $folder->getName())),getMLText("error_occured")); + return false; + } + } else { + if($ret === false) + return false; + } + } + } + } + foreach($oldattributes as $attrdefid=>$oldattribute) { + if(!isset($attributes[$attrdefid])) { + if(!$version->removeAttribute($dms->getAttributeDefinition($attrdefid))) + return false; + } + } + + } elseif($result === false) { + if(empty($this->errormsg)) + $this->errormsg = 'hook_editAttributes_failed'; + return false; + } + + if(false === $this->callHook('postEditAttributes')) { + } + + return true; + } +} diff --git a/op/op.EditAttributes.php b/op/op.EditAttributes.php index 40cbf9c5a..a91000555 100644 --- a/op/op.EditAttributes.php +++ b/op/op.EditAttributes.php @@ -27,8 +27,12 @@ include("../inc/inc.Init.php"); include("../inc/inc.Extension.php"); include("../inc/inc.DBInit.php"); include("../inc/inc.ClassUI.php"); +include("../inc/inc.ClassController.php"); include("../inc/inc.Authentication.php"); +$tmp = explode('.', basename($_SERVER['SCRIPT_FILENAME'])); +$controller = Controller::factory($tmp[1], array('dms'=>$dms, 'user'=>$user)); + /* Check if the form data comes from a trusted request */ if(!checkFormKey('editattributes')) { UI::exitError(getMLText("document_title", array("documentname" => getMLText("invalid_request_token"))),getMLText("invalid_request_token")); @@ -46,7 +50,6 @@ if (!is_object($document)) { } $folder = $document->getFolder(); -$docPathHTML = getFolderPathHTML($folder, true). " / ".$document->getName().""; if ($document->getAccessMode($user, 'editDocumentContentAttributes') < M_READWRITE) { UI::exitError(getMLText("document_title", array("documentname" => $document->getName())),getMLText("access_denied")); @@ -68,59 +71,19 @@ foreach($version->getAttributes() as $ai=>$aa) $oldattributes[$ai] = clone $aa; $attributes = $_POST["attributes"]; -if($attributes) { - foreach($attributes as $attrdefid=>$attribute) { - if($attrdef = $dms->getAttributeDefinition($attrdefid)) { - if($attribute) { - switch($attrdef->getType()) { - case SeedDMS_Core_AttributeDefinition::type_date: - if(is_array($attribute)) - $attribute = array_map(fn($value): string => date('Y-m-d', makeTsFromDate($value)), $attribute); - else - $attribute = date('Y-m-d', makeTsFromDate($attribute)); - break; - case SeedDMS_Core_AttributeDefinition::type_folder: - if(is_array($attribute)) - $attribute = array_map(fn($value): object => $dms->getFolder((int) $value), $attribute); - else - $attribute = $dms->getFolder((int) $attribute); - break; - case SeedDMS_Core_AttributeDefinition::type_document: - if(is_array($attribute)) - $attribute = array_map(fn($value): object => $dms->getDocument((int) $value), $attribute); - else - $attribute = $dms->getDocument((int) $attribute); - break; - case SeedDMS_Core_AttributeDefinition::type_user: - if(is_array($attribute)) - $attribute = array_map(fn($value): object => $dms->getUser((int) $value), $attribute); - else - $attribute = $dms->getUser((int) $attribute); - break; - case SeedDMS_Core_AttributeDefinition::type_group: - if(is_array($attribute)) - $attribute = array_map(fn($value): object => $dms->getGroup((int) $value), $attribute); - else - $attribute = $dms->getGroup((int) $attribute); - break; - } - if(!$attrdef->validate($attribute, $version, false)) { - $errmsg = getAttributeValidationText($attrdef->getValidationError(), $attrdef->getName(), $attribute); - UI::exitError(getMLText("document_title", array("documentname" => $document->getName())), $errmsg); - } - if(!isset($oldattributes[$attrdefid]) || $attribute != $oldattributes[$attrdefid]->getValue()) { - if(!$version->setAttributeValue($dms->getAttributeDefinition($attrdefid), $attribute)) { - UI::exitError(getMLText("document_title", array("documentname" => $document->getName())),getMLText("error_occured")); - } - } - } elseif($attrdef->getMinValues() > 0) { - UI::exitError(getMLText("document_title", array("documentname" => $document->getName())),getMLText("attr_min_values", array("attrname"=>$attrdef->getName()))); - } elseif(isset($oldattributes[$attrdefid])) { - if(!$version->removeAttribute($dms->getAttributeDefinition($attrdefid))) - UI::exitError(getMLText("document_title", array("documentname" => $folder->getName())),getMLText("error_occured")); - } - } +$controller->setParam('document', $document); +$controller->setParam('version', $version); +$controller->setParam('attributes', $attributes); +if(!$controller()) { + $err = $controller->getErrorMsg(); + if(is_string($err)) + $errmsg = getMLText($err); + elseif(is_array($err)) { + $errmsg = getMLText($err[0], $err[1]); + } else { + $errmsg = $err; } + UI::exitError(getMLText("document_title", array("documentname" => $document->getName())), $errmsg); } if($notifier) { @@ -130,5 +93,3 @@ if($notifier) { add_log_line("?documentid=".$documentid); header("Location:../out/out.DocumentVersionDetail.php?documentid=".$documentid."&version=".$versionid); - -?>