From 0a3159d502d5321b4609ddf4d8bb91c576bdea7c Mon Sep 17 00:00:00 2001 From: Carsten Rose <carsten.rose@math.uzh.ch> Date: Wed, 15 Mar 2017 20:29:26 +0100 Subject: [PATCH] KeyValueStringParser.php: Function removeSourroundingQuotes() renamed to quoteUnwrap(). Ldap.php: New function printfPrepare(). Recode parsing and preparation of later sprintf statements. Fix problem with ldap_search 'Size Limit reached'. Skip empty entries. OnArray.php: new function arrayValueToLower(). --- .../qfq/qfq/helper/KeyValueStringParser.php | 4 +- extension/qfq/qfq/helper/Ldap.php | 85 +++++++++++++------ extension/qfq/qfq/helper/OnArray.php | 11 ++- 3 files changed, 69 insertions(+), 31 deletions(-) diff --git a/extension/qfq/qfq/helper/KeyValueStringParser.php b/extension/qfq/qfq/helper/KeyValueStringParser.php index c940cd6ff..35c0f5fc7 100644 --- a/extension/qfq/qfq/helper/KeyValueStringParser.php +++ b/extension/qfq/qfq/helper/KeyValueStringParser.php @@ -123,7 +123,7 @@ class KeyValueStringParser { if (count($keyValueArray) === 2) { // "a:1", "a:" - $returnValue[$key] = self::removeSourroundingQuotes(trim($keyValueArray[1])); + $returnValue[$key] = self::quoteUnwrap(trim($keyValueArray[1])); } else { // no Value given: "a" $returnValue[$key] = ($valueMode === KVP_VALUE_GIVEN) ? "" : $key; @@ -137,7 +137,7 @@ class KeyValueStringParser { * @param $string * @return string */ - private static function removeSourroundingQuotes($string) { + public static function quoteUnwrap($string) { $quotes = ['\'', '"']; if ($string === "" || strlen($string) === 1) { diff --git a/extension/qfq/qfq/helper/Ldap.php b/extension/qfq/qfq/helper/Ldap.php index c5c1ef046..ced53b734 100644 --- a/extension/qfq/qfq/helper/Ldap.php +++ b/extension/qfq/qfq/helper/Ldap.php @@ -11,6 +11,7 @@ namespace qfq; use qfq; require_once(__DIR__ . '/KeyValueStringParser.php'); +require_once(__DIR__ . '/OnArray.php'); class Ldap { @@ -33,14 +34,29 @@ class Ldap { throw new UserFormException("Unable to connect to LDAP server: $ldapServer", ERROR_LDAP_CONNECT); } -// $sr = ldap_search($ds, $ldapBaseDn, $ldapSearch, null, null, $ldapLimit); - $sr = ldap_search($ds, $ldapBaseDn, $ldapSearch); + $keyArr = $this->printfPrepare($config[FE_TYPEAHEAD_LDAP_KEY_PRINTF], $keyFormat); + $valueArr = $this->printfPrepare($config[FE_TYPEAHEAD_LDAP_VALUE_PRINTF], $valueFormat); + + $attr = array_values(array_unique(array_merge($keyArr, $valueArr))); + + // 'Size Limit errors' are reported, even if it is not a real problem. + // Fake all errors at the moment. + // TODO: just drop the 'Size Limit errors' and report all others + set_error_handler(function () { /* ignore errors */ + }); + $sr = ldap_search($ds, $ldapBaseDn, $ldapSearch, $attr, 0, $ldapLimit); + restore_error_handler(); + $info = ldap_get_entries($ds, $sr); for ($i = 0; $i < $info["count"]; $i++) { - $key = $this->printfResult($config[FE_TYPEAHEAD_LDAP_KEY_PRINTF], $info[$i]); - $value = $this->printfResult($config[FE_TYPEAHEAD_LDAP_VALUE_PRINTF], $info[$i]); + $key = $this->printfResult($keyFormat, $keyArr, $info[$i]); + $value = $this->printfResult($valueFormat, $valueArr, $info[$i]); + + if ($key == '' || $value == '') { + continue; // if $key or $value is empty: skip + } $arr[] = [API_TYPEAHEAD_KEY => $key, API_TYPEAHEAD_VALUE => $value]; } @@ -51,7 +67,38 @@ class Ldap { } /** - * Collects values from $inforElelement and sprintf them as described in $format. + * Very specific function to prepare the later 'printfResult()'. + * + * @param $fmtComplete + * @param $fmtFirst + * @return mixed + * @throws CodeException + * @throws UserFormException + */ + private function printfPrepare($fmtComplete, &$fmtFirst) { + + // Typical $fmtComplete: "'%s / %s / %s', cn, mail. telephonenumber" + $arr = KeyValueStringParser::explodeWrapped(',', $fmtComplete); + + if (count($arr) < 2) { + throw new UserFormException("Expect a sprintf compatible format string with a least one argument. Got: '" . $fmtComplete . "'", ERROR_MISSING_PRINTF_ARGUMENTS); + } + + // unquote and return the part printf-'formatString' + $fmtFirst = trim($arr[0], SINGLE_TICK . DOUBLE_TICK); + + array_shift($arr); // remove first entry: + + $arr = OnArray::trimArray($arr); // remove any leading/trailing spaces + + // toLower is important, cause the LDAP attribute names are all lowercase in PHP - if the user specifies in CamelHook , the vars are not found. + return OnArray::arrayValueToLower($arr); + + } + + /** + * Plays sprintf with supplied arguments. Collect the values of the arguments in the array + * $keyArr to pass them via 'call_user_func_array' to sprintf. * * @param $format * @param $infoElement @@ -59,31 +106,13 @@ class Ldap { * @throws CodeException * @throws UserFormException */ - private function printfResult($format, $infoElement) { - - // $format: "'%s / %s / %s', cn, mail, telephonenumber". - // keyArr[0]: printf format string - // keyArr[1..x]: columnnames - $keyArr = KeyValueStringParser::explodeWrapped(',', $format); - if (count($keyArr) < 2) { - throw new UserFormException("Expect a sprintf compatible format string with a least one argument. Got: '" . $format . "'", ERROR_MISSING_PRINTF_ARGUMENTS); - } + private function printfResult($format, array $keyArr, $infoElement) { - $args = array(); - $args[] = $keyArr[0]; - array_shift($keyArr); - foreach ($keyArr as $arg) { - $keyName = trim($arg); - $args[] = $infoElement[$keyName][0]; - } + $args = array($format); -// if(isset($info[$i]["mail"][0])) { -// $key = $info[$i]["mail"][0]; -// if($key===false || $key===null || $key=='') { -// continue; -// } -// $arr[] = [ 'key' => $info[$i]["mail"][0], 'value' => $info[$i]["cn"][0] . ' / ' . $info[$i]["mail"][0] . ' / ' . $info[$i]["telephonenumber"][0]]; -// } + foreach ($keyArr as $key) { + $args[] = (isset($infoElement[$key][0])) ? $infoElement[$key][0] : ''; + } return call_user_func_array('sprintf', $args); } diff --git a/extension/qfq/qfq/helper/OnArray.php b/extension/qfq/qfq/helper/OnArray.php index 0da2d0565..7e2806b92 100644 --- a/extension/qfq/qfq/helper/OnArray.php +++ b/extension/qfq/qfq/helper/OnArray.php @@ -74,7 +74,7 @@ class OnArray { * @param string $character_mask * @return array */ - public static function trimArray(array $arr, $character_mask) { + public static function trimArray(array $arr, $character_mask = " \t\n\r\0\x0B") { foreach ($arr as $key => $item) { $arr[$key] = trim($item, $character_mask); } @@ -168,4 +168,13 @@ class OnArray { return $new; } + + public static function arrayValueToLower(array $arr) { + $new = array(); + + foreach ($arr as $key => $value) { + $new[$key] = strtolower($value); + } + return $new; + } } \ No newline at end of file -- GitLab