3 require_once
'base/Ego_Search_Elastic.php';
4 require_once
'base/Ego_User_Search_Factory.php';
5 require_once(
'composer/vendor/autoload.php');
16 if (!$this->client->indices()->exists([
'index' => $this->config[
'index']])) {
19 'index' => $this->config[
'index'],
20 'include_type_name' =>
true,
23 'number_of_shards' => $GLOBALS[
'egotec_conf'][
'elastic'][
'number_of_shards'],
24 'number_of_replicas' => $GLOBALS[
'egotec_conf'][
'elastic'][
'number_of_replicas'] ?: 0,
25 'index.mapping.ignore_malformed' =>
true,
29 'case_insensitive' => [
30 'filter' =>
'lowercase'
38 'user_id' => [
'type' =>
'text'],
44 'ignore_above' => 256,
45 'normalizer' =>
'case_insensitive'
54 'ignore_above' => 256,
55 'normalizer' =>
'case_insensitive'
59 'username_char' => [
'type' =>
'keyword'],
62 'format' =>
'epoch_second'
66 'format' =>
'epoch_second'
73 'ignore_above' => 256,
74 'normalizer' =>
'case_insensitive'
78 'anrede' => [
'type' =>
'text'],
84 'ignore_above' => 256,
85 'normalizer' =>
'case_insensitive'
94 'ignore_above' => 256,
95 'normalizer' =>
'case_insensitive'
99 'strasse' => [
'type' =>
'text'],
100 'plz' => [
'type' =>
'text'],
101 'ort' => [
'type' =>
'text'],
102 'land' => [
'type' =>
'text'],
103 'branche' => [
'type' =>
'text'],
104 'abteilung' => [
'type' =>
'text'],
105 'firma' => [
'type' =>
'text'],
106 'telefon' => [
'type' =>
'text'],
107 'mobil' => [
'type' =>
'text'],
108 'multiple_login' => [
'type' =>
'integer'],
109 'liveserver' => [
'type' =>
'integer'],
110 'user_inactive' => [
'type' =>
'integer'],
111 'user_deleted' => [
'type' =>
'integer'],
112 'no_admin' => [
'type' =>
'integer'],
113 'no_singlesignon' => [
'type' =>
'integer'],
114 'no_relation' => [
'type' =>
'integer'],
115 'auth_persist_token' => [
'type' =>
'text'],
116 'auth_persist_expire' => [
'type' =>
'integer'],
117 'tfa_secret' => [
'type' =>
'text']
126 $this->client->indices()->create($index_params);
127 }
catch (Exception $e) {
128 if (strpos($e->getMessage(),
'resource_already_exists_exception') ===
false) {
129 throw new Exception($e->getMessage(), $e->getCode());
148 'index' => $this->config[
'index'],
150 'body' => $this->getUserBody($user),
157 $this->client->index($params);
158 }
catch (Exception $e) {
159 Ego_Action::add(Ego_Action::USER_UPDATE_INDEX, [
175 public function updateUserBulk(User_Iterator $users,
bool $verbose =
false, $new_line =
"\n"): void {
182 Ego_System::flush(
"Start update for user search index{$new_line}Collect user data to update");
185 while ($user = $users->nextUser()) {
186 $params[
'body'][] = [
188 '_index' => $this->config[
'index'],
189 '_id' => $user->field[
'user_id']
193 $params[
'body'][] = $this->getUserBody($user);
199 if (floor(
sizeof($params[
'body']) / 2) == $max) {
204 $this->client->bulk($params);
210 $params[
'body'] = [];
218 if (!empty($params[
'body'])) {
219 $num = floor(
sizeof($params[
'body']) / 2);
225 $this->client->bulk($params);
252 public function searchUsers(array $search,
int $limit = -1,
string $type =
'',
bool $checkRights =
true,
bool $filterSearch =
true,
bool $sortResult =
true,
int $from = 0,
bool $returnTotal =
false, array $sort_order = [],
string $rights =
''): array {
254 unset($search[
'show_norelation']);
259 foreach ($search as $key => $value) {
260 if (is_string($value)) {
261 $search[$key] = mb_strtolower($value);
273 return $returnTotal ? [
'users' => [],
'hits' => 0] : [];
277 $group_role = $search[
'group_role'];
278 unset($search[
'group_role']);
279 unset($search[
'group_role_tmp']);
282 $search_params = $this->getSearchParams($search, $group_role ? -1 : $limit, $type, $sortResult, $from, $sort_order);
286 $search_result = $this->client->search($search_params);
287 }
catch (Exception $e) {
288 egotec_error_log(
'<hr>Uncaught exception: ' . $e->getMessage() .
"\n" . $e->getTraceAsString(), -1);
289 return $returnTotal ? [
'users' => [],
'hits' => 0] : [];
293 if ($search_result) {
296 foreach ($search_result[
'hits'][
'hits'] as $user) {
297 $user_ids[] = $user[
'_source'][
'user_id'];
300 $all_users =
new User_Iterator($user_ids);
302 foreach ($all_users as $user_sql) {
303 $group_role_rel =
null;
307 function_exists(
'user_search_fields')
308 ||
Ego_System::file_exists($user_search_fields = ($GLOBALS[
'egotec_conf'][
'var_dir'] .
'lib/admin/user_search_fields.php'))
310 if (isset($user_search_fields)) {
311 require_once $user_search_fields;
313 if (function_exists(
'user_search_fields') && !user_search_fields($user_sql, $search)) {
319 if ($type ===
'admin' && empty($group_role_rel = $user_sql->getGroupRoleRelations())) {
323 $checked_rights =
false;
324 $checked_group_role =
false;
328 $checked_rights =
true;
333 $checked_group_role =
true;
336 if ($rights !==
'') {
337 foreach (explode(
';', $rights) as $group_role) {
338 [$group, $role] = explode(
',', $group_role);
340 if (!$user_sql->hasGroupRoleRelation($group, $role)) {
346 if ($checked_rights && $checked_group_role) {
350 if ($from > 0 && $n <= $from) {
353 if (
sizeof($users) == $limit) {
358 $users[] = $user_sql;
363 return $returnTotal ? [
365 'hits' =>
sizeof($users)
381 'index' => $this->config[
'index'],
384 'username_chars' => [
386 'username_chars' => [
388 'field' =>
'username_char',
403 $search_params[
'body'][
'aggs'][
'username_chars'][
'filter'] = [
424 'lte' => strtotime(
'now')
440 'gte' => strtotime(
'now')
456 $search_params[
'body'][
'aggs'][
'username_chars'][
'filter'] = [
473 'lte' => strtotime(
'now')
489 'gte' => strtotime(
'now')
505 $search_params[
'body'][
'aggs'][
'username_chars'][
'filter'] = [
522 'lte' => strtotime(
'now')
538 'gte' => strtotime(
'now')
554 $search_params[
'body'][
'aggs'][
'username_chars'][
'filter'] = [
566 'gte' => strtotime(
'now')
581 'lte' => strtotime(
'now')
598 'minimum_should_match' => 1
605 $results = $this->client->search($search_params)[
'aggregations'][
'username_chars'][
'username_chars'][
'buckets'];
609 usort($results,
function($a, $b) {
610 return strcasecmp($a[
'key'], $b[
'key']);
614 foreach ($results as $bucket) {
616 'char' => $bucket[
'key'],
617 'number' => $bucket[
'doc_count']
621 return $return_array;
631 private function getUserBody(User_SQL $user): array {
633 if (!$user->getAllGroups()) {
642 'user_id' => $user->field[
'user_id'],
643 'username' => mb_strtolower($user->field[
'username']),
644 'categories' => $user->extra[
'categories'],
645 'username_char' => mb_strtoupper(mb_substr($user->field[
'username'], 0, 1)),
646 'release_from' => ($user->field[
'release_from'] ==
'0000-00-00 00:00:00' || !$user->field[
'release_from']) ? 0 : strtotime($user->field[
'release_from']),
647 'release_until' => ($user->field[
'release_until'] ==
'0000-00-00 00:00:00' || !$user->field[
'release_until']) ? 0 : strtotime($user->field[
'release_until']),
648 'email' => mb_strtolower(trim((
string) $user->field[
'email'])),
649 'anrede' => mb_strtolower(trim((
string) $user->extra[
'anrede'])),
650 'name' => mb_strtolower(trim((
string) $user->extra[
'name'])),
651 'vorname' => mb_strtolower(trim((
string) $user->extra[
'vorname'])),
652 'strasse' => mb_strtolower(trim((
string) $user->extra[
'strasse'])),
653 'plz' => mb_strtolower(trim((
string) $user->extra[
'plz'])),
654 'ort' => mb_strtolower(trim((
string) $user->extra[
'ort'])),
655 'land' => mb_strtolower(trim((
string) $user->extra[
'land'])),
656 'branche' => mb_strtolower(trim((
string) $user->extra[
'branche'])),
657 'abteilung' => mb_strtolower(trim((
string) $user->extra[
'abteilung'])),
658 'position' => mb_strtolower(trim((
string) $user->extra[
'position'])),
659 'firma' => mb_strtolower(trim((
string) $user->extra[
'firma'])),
660 'telefon' => mb_strtolower(trim((
string) $user->extra[
'telefon'])),
661 'mobil' => mb_strtolower(trim((
string) $user->extra[
'mobil'])),
662 'multiple_login' => $user->field[
'multiple_login'] ? 1 : 0,
663 'liveserver' => $user->extra[
'liveserver'] ? 1 : 0,
664 'user_inactive' => $user->extra[
'user_inactive'] ? 1 : 0,
665 'user_deleted' => $user->field[
'deleted'] ? 1 : 0,
666 'no_admin' => $user->field[
'no_admin'] ? 1 : 0,
667 'no_singlesignon' => $user->extra[
'no_singlesignon'] ? 1 : 0,
668 'no_relation' => $no_relation,
669 'auth_persist_token' => (string) $user->extra[
'auth_persist_token'],
670 'auth_persist_expire' => (
int) $user->extra[
'auth_persist_expire'],
671 'tfa_secret' => (string) $user->extra[
'tfa_secret']
675 if ($GLOBALS[
'egotec_conf'][
'user_search_fields']) {
676 foreach ($GLOBALS[
'egotec_conf'][
'user_search_fields'] as $name => $type) {
677 $fields[$name] = $type ==
'boolean' ? ((int) $user->extra[$name]) : mb_strtolower(trim((
string) $user->extra[$name]));
698 private function getSearchParams(array $search,
int $limit = -1,
string $type =
'',
bool $sortResult =
true,
int $from = 0, array $sort_order = []): array {
699 $search_deleted = $search[
'search_deleted'];
700 unset($search[
'search_deleted']);
706 $search[
'no_admin'] = 0;
707 $search[
'user_inactive'] = 0;
711 $search[
'no_admin'] = 1;
712 $search[
'no_relation'] = 0;
713 $search[
'user_deleted'] = 0;
714 $search[
'user_inactive'] = 0;
718 $search[
'no_relation'] = 1;
719 $search[
'user_deleted'] = 0;
720 $search[
'user_inactive'] = 0;
724 $search[
'user_inactive'] = 1;
725 $search[
'user_deleted'] = 0;
728 $search[
'user_deleted'] = 1;
732 if ($limit == -1 && ($max_results = intval($GLOBALS[
'egotec_conf'][
'elastic'][
'max_results']))) {
733 $limit = $max_results;
739 'index' => $this->config[
'index'],
745 'minimum_should_match' => 0
755 $field =
'username.keyword';
758 if ($sort_order && $sort_order[
'field'] && $sort_order[
'field'] !==
'') {
759 $field = $sort_order[
'field'];
762 if ($sort_order && $sort_order[
'order'] && $sort_order[
'order'] !==
'') {
763 $order = $sort_order[
'order'];
766 $search_params[
'body'][
'sort'] = [
769 'unmapped_type' =>
'keyword'
776 $minimum_should_match = 0;
779 if ($search[
'user_inactive'] === 0) {
796 'lte' => strtotime(
'now')
815 'gte' => strtotime(
'now')
826 }
else if ($search[
'user_inactive'] === 1) {
842 'gte' => strtotime(
'now')
860 'lte' => strtotime(
'now')
873 $minimum_should_match = 1;
876 unset($search[
'user_inactive']);
879 $match_exact = [
'no_admin',
'no_relation',
'user_inactive',
'user_deleted',
'username_char'];
881 $search_lower = [
'username',
'email',
'vorname',
'name',
'categories'];
884 if ($GLOBALS[
'egotec_conf'][
'user_search_fields']) {
887 $search = array_diff_key($search, $GLOBALS[
'egotec_conf'][
'user_search_fields']);
889 foreach ($GLOBALS[
'egotec_conf'][
'user_search_fields'] as $name => $type) {
890 if ($type ==
'boolean') {
891 $match_exact[] = $name;
898 foreach ($search as $key => $value) {
900 if (($value !==
'' && $value !==
false && $value !==
null) || $key ===
'username') {
901 if (in_array($key, $match_exact)) {
910 if (in_array($key, [
'username',
'vorname',
'name'])) {
911 $key =
"$key.keyword";
917 $key => $value && !in_array($key, [
'tfa_secret'])
918 ?
'*' . (in_array($key, $search_lower) ? mb_strtolower($value) : $value) .
'*'
926 $search_params[
'body'][
'query'][
'bool'][
'must'] = $must;
927 $search_params[
'body'][
'query'][
'bool'][
'should'] = $should;
928 $search_params[
'body'][
'query'][
'bool'][
'minimum_should_match'] = $minimum_should_match;
930 return $search_params;
static file_exists($file)
searchUsers(array $search, int $limit=-1, string $type='', bool $checkRights=true, bool $filterSearch=true, bool $sortResult=true, int $from=0, bool $returnTotal=false, array $sort_order=[], string $rights='')
updateUserIndex(string $id, User_SQL $user)
updateUserBulk(User_Iterator $users, bool $verbose=false, $new_line="\n")
static isAcceptedUser(User_SQL $user, array $group_role_rel=null)
static filterSearch(array $search)
static checkSearchFilter(string $type, array $search)
static checkRightsFilter(string $rightsFilter, User_SQL $user, array $group_role_rel=null)