diff --git a/ajax/getldapvalues.php b/ajax/getldapvalues.php new file mode 100644 index 000000000..da1fc687e --- /dev/null +++ b/ajax/getldapvalues.php @@ -0,0 +1,47 @@ +. + * --------------------------------------------------------------------- + * @copyright Copyright © 2011 - 2021 Teclib' + * @license http://www.gnu.org/licenses/gpl.txt GPLv3+ + * @link https://github.com/pluginsGLPI/formcreator/ + * @link https://pluginsglpi.github.io/formcreator/ + * @link http://plugins.glpi-project.org/#/plugin/formcreator + * --------------------------------------------------------------------- + */ + +include ('../../../inc/includes.php'); + +if (!defined('GLPI_ROOT')) { + die("Sorry. You can't access this file directly"); +} + +header('Content-Type: application/json; charset=UTF-8'); +Html::header_nocache(); + +// Check if plugin is activated... +if (!Plugin::isPluginActive('formcreator')) { + Html::displayNotFoundError(); +} + +Session::checkLoginUser(); +echo PluginFormcreatorLdapDropdown::getDropdownValue($_POST); \ No newline at end of file diff --git a/ajax/gettranslationsvalues.php b/ajax/gettranslationsvalues.php index ac2d223a3..4e8dcfbee 100644 --- a/ajax/gettranslationsvalues.php +++ b/ajax/gettranslationsvalues.php @@ -33,7 +33,6 @@ // Direct access to file if (strpos($_SERVER['PHP_SELF'], 'gettranslationsvalues.php')) { - include ('../../../inc/includes.php'); header('Content-Type: application/json; charset=UTF-8'); Html::header_nocache(); } else if (!defined('GLPI_ROOT')) { diff --git a/inc/field/ldapselectfield.class.php b/inc/field/ldapselectfield.class.php index 27670a5d1..469cb443f 100644 --- a/inc/field/ldapselectfield.class.php +++ b/inc/field/ldapselectfield.class.php @@ -33,12 +33,13 @@ namespace GlpiPlugin\Formcreator\Field; use AuthLDAP; -use Exception; use Html; use Session; use RuleRightParameter; +use PluginFormcreatorQuestion; use Glpi\Application\View\TemplateRenderer; use PluginFormcreatorAbstractField; +use PluginFormcreatorLdapDropdown; class LdapselectField extends SelectField { @@ -67,17 +68,19 @@ public function getRenderedHtml($domain, $canEdit = true): string { $id = $this->question->getID(); $rand = mt_rand(); $fieldName = 'formcreator_field_' . $id; - $values = $this->getAvailableValues(); if (!empty($this->question->fields['values'])) { - $html .= Dropdown::showFromArray($fieldName, $values, [ - 'display_emptychoice' => $this->question->fields['show_empty'] == 1, + $options = [ + 'name' => $fieldName, 'value' => $this->value, - 'values' => [], 'rand' => $rand, 'multiple' => false, 'display' => false, - ]); + 'condition' => [ + PluginFormcreatorQuestion::getForeignKeyField() => $this->question->getID() + ] + ]; + $html .= PluginFormcreatorLdapDropdown::dropdown($options); } $html .= PHP_EOL; $html .= Html::scriptBlock("$(function() { @@ -87,77 +90,6 @@ public function getRenderedHtml($domain, $canEdit = true): string { return $html; } - public function getAvailableValues() { - if (empty($this->question->fields['values'])) { - return []; - } - - $ldap_values = json_decode($this->question->fields['values'], JSON_OBJECT_AS_ARRAY); - $ldap_dropdown = new RuleRightParameter(); - if (!$ldap_dropdown->getFromDB($ldap_values['ldap_attribute'])) { - return []; - } - $attribute = [$ldap_dropdown->fields['value']]; - - $config_ldap = new AuthLDAP(); - if (!$config_ldap->getFromDB($ldap_values['ldap_auth'])) { - return []; - } - - set_error_handler([self::class, 'ldapErrorHandler'], E_WARNING); - - $tab_values = []; - try { - $cookie = ''; - $ds = $config_ldap->connect(); - ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3); - do { - if (AuthLDAP::isLdapPageSizeAvailable($config_ldap)) { - $controls = [ - [ - 'oid' => LDAP_CONTROL_PAGEDRESULTS, - 'iscritical' => true, - 'value' => [ - 'size' => $config_ldap->fields['pagesize'], - 'cookie' => $cookie - ] - ] - ]; - $result = ldap_search($ds, $config_ldap->fields['basedn'], $ldap_values['ldap_filter'], $attribute, 0, -1, -1, LDAP_DEREF_NEVER, $controls); - ldap_parse_result($ds, $result, $errcode, $matcheddn, $errmsg, $referrals, $controls); - $cookie = $controls[LDAP_CONTROL_PAGEDRESULTS]['value']['cookie'] ?? ''; - } else { - $result = ldap_search($ds, $config_ldap->fields['basedn'], $ldap_values['ldap_filter'], $attribute); - } - - $entries = ldap_get_entries($ds, $result); - // openldap return 4 for Size limit exceeded - $limitexceeded = in_array(ldap_errno($ds), [4, 11]); - - if ($limitexceeded) { - Session::addMessageAfterRedirect(__('LDAP size limit exceeded', 'formcreator'), true, WARNING); - } - array_shift($entries); - - $id = 0; - foreach ($entries as $attr) { - if (!isset($attr[$attribute[0]]) || in_array($attr[$attribute[0]][0], $tab_values)) { - continue; - } - $tab_values[$id] = $attr[$attribute[0]][0]; - $id++; - } - } while ($cookie !== null && $cookie != ''); - } catch (Exception $e) { - restore_error_handler(); - trigger_error($e->getMessage(), E_USER_WARNING); - } - - restore_error_handler(); - asort($tab_values); - return $tab_values; - } - public static function getName(): string { return __('LDAP Select', 'formcreator'); } @@ -305,11 +237,4 @@ public function isVisibleField(): bool { public function isEditableField(): bool { return true; } - - public static function ldapErrorHandler($errno, $errstr, $errfile, $errline) { - if (0 === error_reporting()) { - return false; - } - throw new \ErrorException($errstr, 0, $errno, $errfile, $errline); - } } diff --git a/inc/ldapdropdown.class.php b/inc/ldapdropdown.class.php new file mode 100644 index 000000000..00ed90539 --- /dev/null +++ b/inc/ldapdropdown.class.php @@ -0,0 +1,195 @@ +. + * --------------------------------------------------------------------- + * @copyright Copyright © 2011 - 2020 Teclib' + * @license http://www.gnu.org/licenses/gpl.txt GPLv3+ + * @link https://github.com/pluginsGLPI/formcreator/ + * @link https://pluginsglpi.github.io/formcreator/ + * @link http://plugins.glpi-project.org/#/plugin/formcreator + * --------------------------------------------------------------------- + */ + +use Glpi\Toolbox\Sanitizer; + +if (!defined('GLPI_ROOT')) { + die("Sorry. You can't access this file directly"); +} + +class PluginFormcreatorLdapDropdown extends CommonGLPI +{ + public static function getTable() { + return ''; + } + + public function getForeignKeyField() { + return ''; + } + + public function isField() { + return false; + } + + public static function dropdown($options = []) { + $options['display'] = $options['display'] ?? false; + $options['url'] = Plugin::getWebDir('formcreator') . '/ajax/getldapvalues.php'; + + $out = Dropdown::show(self::class, $options); + if (!$options['display']) { + return $out; + } + echo $out; + } + + public static function getDropdownValue($post, $json = true) { + // Count real items returned + $count = 0; + + if (isset($post['condition']) && !empty($post['condition']) && !is_array($post['condition'])) { + // Retreive conditions from SESSION using its key + $key = $post['condition']; + $post['condition'] = []; + if (isset($_SESSION['glpicondition']) && isset($_SESSION['glpicondition'][$key])) { + $post['condition'] = $_SESSION['glpicondition'][$key]; + } + } + + $questionId = $post['condition'][PluginFormcreatorQuestion::getForeignKeyField()]; + $question = PluginFormcreatorQuestion::getById($questionId); + if (!is_object($question)) { + return []; + } + + $form = PluginFormcreatorCommon::getForm(); + $form = $form::getByItem($question); + if (!$form->canViewForRequest()) { + return []; + } + $post['searchText'] = $post['searchText'] ?? ''; + + // Search values + $ldap_values = json_decode($question->fields['values'], JSON_OBJECT_AS_ARRAY); + $ldap_dropdown = new RuleRightParameter(); + if (!$ldap_dropdown->getFromDB($ldap_values['ldap_attribute'])) { + return []; + } + $attribute = [$ldap_dropdown->fields['value']]; + + $config_ldap = new AuthLDAP(); + if (!$config_ldap->getFromDB($ldap_values['ldap_auth'])) { + return []; + } + + set_error_handler([self::class, 'ldapErrorHandler'], E_WARNING); + + if ($post['searchText'] != '') { + $ldap_values['ldap_filter'] = sprintf( + "(& %s (%s))", + $ldap_values['ldap_filter'], + $attribute[0] . '=*' . $post['searchText'] . '*' + ); + } + + $tab_values = []; + try { + $cookie = ''; + $ds = $config_ldap->connect(); + ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3); + $foundCount = 0; + do { + if (AuthLDAP::isLdapPageSizeAvailable($config_ldap)) { + $controls = [ + [ + 'oid' => LDAP_CONTROL_PAGEDRESULTS, + 'iscritical' => true, + 'value' => [ + 'size' => $config_ldap->fields['pagesize'], + 'cookie' => $cookie + ] + ] + ]; + $result = ldap_search($ds, $config_ldap->fields['basedn'], $ldap_values['ldap_filter'], $attribute, 0, -1, -1, LDAP_DEREF_NEVER, $controls); + ldap_parse_result($ds, $result, $errcode, $matcheddn, $errmsg, $referrals, $controls); + $cookie = $controls[LDAP_CONTROL_PAGEDRESULTS]['value']['cookie'] ?? ''; + } else { + $result = ldap_search($ds, $config_ldap->fields['basedn'], $ldap_values['ldap_filter'], $attribute); + } + + $entries = ldap_get_entries($ds, $result); + // openldap return 4 for Size limit exceeded + $limitexceeded = in_array(ldap_errno($ds), [4, 11]); + + if ($limitexceeded) { + Session::addMessageAfterRedirect(__('LDAP size limit exceeded', 'formcreator'), true, WARNING); + } + + unset($entries['count']); + + foreach ($entries as $attr) { + if (!isset($attr[$attribute[0]]) || in_array($attr[$attribute[0]][0], $tab_values)) { + continue; + } + + $foundCount++; + if ($foundCount < ((int) $post['page'] - 1) * (int) $post['page_limit'] + 1) { + // before the requested page + continue; + } + if ($foundCount > ((int) $post['page']) * (int) $post['page_limit']) { + // after the requested page + break; + } + + $tab_values[] = [ + 'id' => $attr[$attribute[0]][0], + 'text' => $attr[$attribute[0]][0], + ]; + $count++; + if ($count >= $post['page_limit']) { + break; + } + } + } while ($cookie !== null && $cookie != '' && $count < $post['page_limit']); + } catch (Exception $e) { + restore_error_handler(); + trigger_error($e->getMessage(), E_USER_WARNING); + } + + restore_error_handler(); + + $tab_values = Sanitizer::unsanitize($tab_values); + usort($tab_values, function($a, $b) { + return strnatcmp($a['text'], $b['text']); + }); + $ret['results'] = $tab_values; + $ret['count'] = $count; + + return ($json === true) ? json_encode($ret) : $ret; + } + + public static function ldapErrorHandler($errno, $errstr, $errfile, $errline) { + if (0 === error_reporting()) { + return false; + } + throw new \ErrorException($errstr, 0, $errno, $errfile, $errline); + } +} \ No newline at end of file diff --git a/inc/translation.class.php b/inc/translation.class.php index 29c0e5359..7ac264f46 100644 --- a/inc/translation.class.php +++ b/inc/translation.class.php @@ -29,6 +29,8 @@ * --------------------------------------------------------------------- */ +use Glpi\Toolbox\Sanitizer; + if (!defined('GLPI_ROOT')) { die("Sorry. You can't access this file directly"); } @@ -88,9 +90,7 @@ public static function getDropdownValue($post, $json = true) { if (!$formLanguage->getFromDB($formLanguageId)) { return []; } - if (!isset($post['searchText'])) { - $post['searchText'] = ''; - } + $post['searchText'] = $post['searchText'] ?? ''; $form = PluginFormcreatorCommon::getForm(); $form->getFromDB($formLanguage->fields['plugin_formcreator_forms_id']); @@ -125,7 +125,7 @@ public static function getDropdownValue($post, $json = true) { } } - $data = \Glpi\Toolbox\Sanitizer::unsanitize($data); + $data = Sanitizer::unsanitize($data); $ret['results'] = $data; $ret['count'] = $count;