diff --git a/include/class_pluglist.inc b/include/class_pluglist.inc index dc019fba5dedd9de3800b9fb317aafbbc0213007..8504665ca3f4cd5d0b398747ee1ad2f9752d3490 100644 --- a/include/class_pluglist.inc +++ b/include/class_pluglist.inc @@ -42,6 +42,11 @@ class pluglist { */ var $info = array(); + /*! + * \brief Foreign references on DNs + */ + var $dnForeignRefs = array(); + /*! * \brief Using the plugin index as a key, the class of the plugin. */ @@ -123,6 +128,9 @@ class pluglist { $foreign_refs[$class][$field] = array(); } $foreign_refs[$class][$field][] = array($cname, $ofield, $filter); + if ($field == 'dn') { + $this->dnForeignRefs[] = array($cname, $ofield, $filter, (isset($pfk[3]) ? $pfk[3] : "$ofield=*%oldvalue%")); + } } unset($pfk); } diff --git a/include/simpleplugin/attributes/class_SetAttribute.inc b/include/simpleplugin/attributes/class_SetAttribute.inc index 7871fcf64e2405af8995f0e441292e0d4dd73efb..f27f3c5df3c2590ebae0c11c6b4c30b8bd4d58c1 100644 --- a/include/simpleplugin/attributes/class_SetAttribute.inc +++ b/include/simpleplugin/attributes/class_SetAttribute.inc @@ -317,7 +317,15 @@ class SetAttribute extends Attribute function foreignKeyUpdate($oldvalue, $newvalue, $source) { foreach ($this->value as $key => &$value) { - if ($value == $oldvalue) { + if (($source['FIELD'] == 'dn') && ($source['MODE'] == 'move')) { + if ($newvalue === NULL) { + if (preg_match('/'.preg_quote($oldvalue, '/').'$/', $value)) { + unset($this->value[$key]); + } + } else { + $value = preg_replace('/'.preg_quote($oldvalue, '/').'$/', $newvalue, $value); + } + } elseif ($value == $oldvalue) { if ($newvalue === NULL) { unset($this->value[$key]); } elseif ($source['MODE'] == 'copy') { diff --git a/include/simpleplugin/class_Attribute.inc b/include/simpleplugin/class_Attribute.inc index 65b24789163b186909fcf31268ced3f92fb9f3e2..730b2a82a87e2a486090e3073ac032004b09810c 100644 --- a/include/simpleplugin/class_Attribute.inc +++ b/include/simpleplugin/class_Attribute.inc @@ -710,7 +710,13 @@ class Attribute function foreignKeyUpdate($oldvalue, $newvalue, $source) { if ($source['MODE'] == 'move') { - if ($this->getValue() == $oldvalue) { + if ($source['FIELD'] == 'dn') { + $value = $this->getValue(); + $value = preg_replace('/'.preg_quote($oldvalue, '/').'$/', $newvalue, $value, -1, $count); + if ($count > 0) { + $this->setValue($value); + } + } elseif ($this->getValue() == $oldvalue) { $this->setValue($newvalue); } } diff --git a/include/simpleplugin/class_dialogAttributes.inc b/include/simpleplugin/class_dialogAttributes.inc index d09bf46f76859207d198ef268af4102f3e5aa340..6e7b47a533719657b05e3fdf9ec9f06ab5d6a50b 100644 --- a/include/simpleplugin/class_dialogAttributes.inc +++ b/include/simpleplugin/class_dialogAttributes.inc @@ -446,7 +446,19 @@ class GenericDialogAttribute extends DialogAttribute function foreignKeyUpdate($oldvalue, $newvalue, $source) { foreach ($this->value as $key => &$value) { - if ($value == $oldvalue) { + if (($source['FIELD'] == 'dn') && ($source['MODE'] == 'move')) { + if ($newvalue === NULL) { + if (preg_match('/'.preg_quote($oldvalue, '/').'$/', $value)) { + $this->removeValue($key); + } + } else { + $value = preg_replace('/'.preg_quote($oldvalue, '/').'$/', $newvalue, $value, -1, $count); + if ($count > 0) { + /* Update display */ + $this->fillDisplayValue($key); + } + } + } elseif ($value == $oldvalue) { if ($newvalue === NULL) { $this->removeValue($key); } elseif ($source['MODE'] == 'copy') { diff --git a/include/simpleplugin/class_simplePlugin.inc b/include/simpleplugin/class_simplePlugin.inc index 097f6db82bc7aba0faf9f1a0ff47862fe01fbc59..450e220af375092f37c6d0e5ac4addf90e6810a3 100644 --- a/include/simpleplugin/class_simplePlugin.inc +++ b/include/simpleplugin/class_simplePlugin.inc @@ -1536,15 +1536,64 @@ class simplePlugin function browseForeignKeys($mode, $param1 = NULL, $param2 = NULL) { + global $plist; if (preg_match('/^handle_/', $mode)) { $olddn = $param1; $newdn = $param2; $classes = array(get_class($this)); + $subobjects = ($olddn != $newdn); //FIXME } elseif ($mode == 'references') { $classes = array_keys($this->parent->by_object); } - // We group by objetType concerned + // We group by objectType concerned $foreignRefs = array(); + if ($subobjects) { + $field = 'dn'; + /* Special treatment for foreign keys on DN when moving an object + * All references on DN are treated on subobjects */ + foreach ($plist->dnForeignRefs as $ref) { + $class = $ref[0]; + $ofield = $ref[1]; + $filter = $ref[2]; + $filtersub = $ref[3]; + if ($class == 'aclAssignment') { + /* Special case: aclAssignment foreignKey is ignored on department types as it’s handled by the aclAssignment objectType */ + $objectTypes = array('ACLASSIGNMENT'); + } elseif (is_subclass_of($class, 'simpleService')) { + $objectTypes = array('SERVER'); + } else { + $objectTypes = array(); + $cinfos = pluglist::pluginInfos($class); + foreach ($cinfos['plObjectType'] as $key => $objectType) { + if (!is_numeric($key)) { + $objectType = $key; + } + if (preg_match('/^ogroup-/i', $objectType)) { + $objectType = 'OGROUP'; + } + $objectTypes[] = $objectType; + } + $objectTypes = array_unique($objectTypes); + } + foreach ($objectTypes as $objectType) { + $oldvalue = $olddn; + $newvalue = $newdn; + + $foreignRefs[$objectType]['refs'][$class][$ofield][$field] = + array( + 'tab' => $classes[0], + 'field' => $field, + 'oldvalue' => $oldvalue, + 'newvalue' => $newvalue, + ); + $filter = templateHandling::parseString($filtersub, array('oldvalue' => $oldvalue, 'newvalue' => $newvalue), 'ldap_escape_f'); + if (!preg_match('/^\(.*\)$/', $filter)) { + $filter = '('.$filter.')'; + } + $foreignRefs[$objectType]['filters'][$filter] = $filter; + } + } + } foreach ($classes as $tabclass) { $infos = pluglist::pluginInfos($tabclass); foreach ($infos['plForeignRefs'] as $field => $refs) { diff --git a/plugins/admin/acl/class_aclAssignment.inc b/plugins/admin/acl/class_aclAssignment.inc index 19c59043b41bb47965a77e90ec8bc424ce5edad3..fd4667fca9f92d195d3cfb26a3d4ff119014ac2b 100644 --- a/plugins/admin/acl/class_aclAssignment.inc +++ b/plugins/admin/acl/class_aclAssignment.inc @@ -211,11 +211,23 @@ class ACLsAssignmentAttribute extends DialogOrderedArrayAttribute function foreignKeyUpdate($oldvalue, $newvalue, $source) { foreach ($this->value as $key => &$value) { - if (($source['CLASS'] == 'aclRole') && ($value['role'] == $oldvalue) && ($source['MODE'] != 'copy')) { + if (($source['FIELD'] == 'dn') && ($source['MODE'] == 'move')) { if ($newvalue === NULL) { - unset($this->value[$key]); + if (preg_match('/'.preg_quote($oldvalue, '/').'$/', $value['role'])) { + unset($this->value[$key]); + } + foreach ($value['members'] as $member_key => $member) { + if (preg_match('/'.preg_quote($oldvalue, '/').'$/', $member)) { + unset($value['members'][$member_key]); + } + } + unset($member); } else { - $value['role'] = $newvalue; + $value['role'] = preg_replace('/'.preg_quote($oldvalue, '/').'$/', $newvalue, $value['role']); + foreach ($value['members'] as &$member) { + $member = preg_replace('/'.preg_quote($oldvalue, '/').'$/', $newvalue, $member); + } + unset($member); } } elseif (in_array($source['CLASS'], array('user','posixGroup','roleGeneric')) && (($member_key = array_search($oldvalue, $value['members'])) !== FALSE)) { if ($newvalue === NULL) { @@ -275,10 +287,10 @@ class aclAssignment extends simplePlugin 'plObjectType' => $oc, 'plForeignKeys' => array( 'gosaAclEntry' => array( - array('aclRole', 'dn', 'gosaAclEntry=*:*:%b|oldvalue%:*'), - array('user', 'dn', 'gosaAclEntry=*:*:*:*%b|oldvalue%*'), - array('posixGroup', 'dn', 'gosaAclEntry=*:*:*:*%b|oldvalue%*'), - array('roleGeneric', 'dn', 'gosaAclEntry=*:*:*:*%b|oldvalue%*'), + array('aclRole', 'dn', 'gosaAclEntry=*:*:%b|oldvalue%:*', 'gosaAclEntry=*'), + array('user', 'dn', 'gosaAclEntry=*:*:*:*%b|oldvalue%*', 'gosaAclEntry=*'), + array('posixGroup', 'dn', 'gosaAclEntry=*:*:*:*%b|oldvalue%*', 'gosaAclEntry=*'), + array('roleGeneric', 'dn', 'gosaAclEntry=*:*:*:*%b|oldvalue%*', 'gosaAclEntry=*'), ) ),