EGOCMS  24.0
EGOTEC Content-Managament-System
Ego_User_Elastic.php
gehe zur Dokumentation dieser Datei
1 <?php
2 
3 require_once 'base/Ego_Search_Elastic.php';
4 require_once 'base/Ego_User_Search_Factory.php';
5 require_once('composer/vendor/autoload.php');
6 
14  public function indexCreate(): bool {
15  // Prüfen ob der angegebene Index bereits existiert
16  if (!$this->client->indices()->exists(['index' => $this->config['index']])) {
17  // Index existiert nicht -> Index erstellen
18  $index_params = [
19  'index' => $this->config['index'],
20  'include_type_name' => true,
21  'body' => [
22  'settings' => [
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,
26  'index.mapping.total_fields.limit' => $this->maxClauseCount,
27  'analysis' => [
28  'normalizer' => [
29  'case_insensitive' => [
30  'filter' => 'lowercase'
31  ]
32  ]
33  ]
34  ],
35  'mappings' => [
36  '_doc' => [
37  'properties' => [
38  'user_id' => ['type' => 'text'],
39  'username' => [
40  'type' => 'keyword', // Username muss als keyword angelegt werden, damit danach sortiert werden kann
41  'fields' => [
42  'keyword' => [
43  'type' => 'keyword',
44  'ignore_above' => 256,
45  'normalizer' => 'case_insensitive'
46  ]
47  ]
48  ],
49  'categories' => [
50  'type' => 'keyword',
51  'fields' => [
52  'keyword' => [
53  'type' => 'keyword',
54  'ignore_above' => 256,
55  'normalizer' => 'case_insensitive'
56  ]
57  ]
58  ],
59  'username_char' => ['type' => 'keyword'],
60  'release_from' => [
61  'type' => 'date',
62  'format' => 'epoch_second'
63  ],
64  'release_until' => [
65  'type' => 'date',
66  'format' => 'epoch_second'
67  ],
68  'email' => [
69  'type' => 'keyword',
70  'fields' => [
71  'keyword' => [
72  'type' => 'keyword',
73  'ignore_above' => 256,
74  'normalizer' => 'case_insensitive'
75  ]
76  ]
77  ],
78  'anrede' => ['type' => 'text'],
79  'name' => [
80  'type' => 'keyword',
81  'fields' => [
82  'keyword' => [
83  'type' => 'keyword',
84  'ignore_above' => 256,
85  'normalizer' => 'case_insensitive'
86  ]
87  ]
88  ],
89  'vorname' => [
90  'type' => 'keyword',
91  'fields' => [
92  'keyword' => [
93  'type' => 'keyword',
94  'ignore_above' => 256,
95  'normalizer' => 'case_insensitive'
96  ]
97  ]
98  ],
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']
118  ]
119  ]
120  ]
121  ]
122  ];
123 
124  // Index anlegen
125  try {
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());
130  }
131  }
132  }
133 
134  return true;
135  }
136 
145  public function updateUserIndex(string $id, User_SQL $user): bool {
146  try {
147  $params = [
148  'index' => $this->config['index'],
149  'id' => $id,
150  'body' => $this->getUserBody($user), // Informationen aus dem Benutzer auslesen
151  'client' => [
152  'ignore' => 404
153  ]
154  ];
155 
156  // Benutzer indizieren
157  $this->client->index($params);
158  } catch (Exception $e) {
159  Ego_Action::add(Ego_Action::USER_UPDATE_INDEX, [
160  'id' => $id
161  ], $e);
162  }
163 
164  return true;
165  }
166 
175  public function updateUserBulk(User_Iterator $users, bool $verbose = false, $new_line = "\n"): void {
176  $max = 500;
177  $params = [
178  'body' => []
179  ];
180 
181  if ($verbose) {
182  Ego_System::flush("Start update for user search index{$new_line}Collect user data to update");
183  }
184 
185  while ($user = $users->nextUser()) {
186  $params['body'][] = [
187  'index' => [
188  '_index' => $this->config['index'],
189  '_id' => $user->field['user_id']
190  ]
191  ];
192 
193  $params['body'][] = $this->getUserBody($user);
194 
195  if ($verbose) {
196  Ego_System::flush('. ');
197  }
198 
199  if (floor(sizeof($params['body']) / 2) == $max) {
200  if ($verbose) {
201  Ego_System::flush("updating $max users. . .");
202  }
203 
204  $this->client->bulk($params);
205 
206  if ($verbose) {
207  Ego_System::flush("done{$new_line}");
208  }
209 
210  $params['body'] = [];
211 
212  if ($verbose) {
213  Ego_System::flush("Collect user data to update");
214  }
215  }
216  }
217 
218  if (!empty($params['body'])) {
219  $num = floor(sizeof($params['body']) / 2);
220 
221  if ($verbose) {
222  Ego_System::flush("updating " . $num . " users. . .");
223  }
224 
225  $this->client->bulk($params);
226 
227  if ($verbose) {
228  Ego_System::flush("done{$new_line}");
229  }
230  }
231 
232  if ($verbose) {
233  Ego_System::flush("Update for user search index completed!");
234  }
235  }
236 
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 {
253  // Sucharray filtern und ungewünschte Werte entfernen
254  unset($search['show_norelation']);
255 
256  /* Alle Suchbegriffe klein übergeben, da diese in Elasticsearch als "keyword" hinterlegt sind,
257  * die bei einer Suche immer die Groß- und Kleinschreibung berücksichtigen. Bei der Benutzersuche
258  * soll diese aber ignoriert werden. */
259  foreach ($search as $key => $value) {
260  if (is_string($value)) {
261  $search[$key] = mb_strtolower($value);
262  }
263  }
264 
265  if ($filterSearch) {
266  $search = Ego_User_Search_Factory::filterSearch($search);
267  }
268 
269  // Rückgabe-Array
270  $users = [];
271 
272  if ($type && !Ego_User_Search_Factory::checkSearchFilter($type, $search)) {
273  return $returnTotal ? ['users' => [], 'hits' => 0] : [];
274  }
275 
276  // Gruppe/Rolle zum aussortieren nach der Suche
277  $group_role = $search['group_role'];
278  unset($search['group_role']); // Gruppen/Rollen stehen nicht im index
279  unset($search['group_role_tmp']); // Gruppen/Rollen stehen nicht im index
280 
281  // Elasticsearch Parameter vorbereiten
282  $search_params = $this->getSearchParams($search, $group_role ? -1 : $limit, $type, $sortResult, $from, $sort_order);
283 
284  try {
285  // Suche durchführen
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] : [];
290  }
291 
292  // Wenn überhaupt Ergebnisse gefunden wurden
293  if ($search_result) {
294  // Jeden gefundenen Benutzer zurückgeben
295  $user_ids = [];
296  foreach ($search_result['hits']['hits'] as $user) {
297  $user_ids[] = $user['_source']['user_id'];
298  }
299 
300  $all_users = new User_Iterator($user_ids);
301  $n = 0;
302  foreach ($all_users as $user_sql) {
303  $group_role_rel = null;
304 
305  // Kundenspezifische Filter
306  if (
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'))
309  ) {
310  if (isset($user_search_fields)) {
311  require_once $user_search_fields;
312  }
313  if (function_exists('user_search_fields') && !user_search_fields($user_sql, $search)) {
314  continue;
315  }
316  }
317 
318  // Wenn der Benutzer keine Gruppen/Rollen hat und nach Benutzern mit Backendzugang gesucht wird
319  if ($type === 'admin' && empty($group_role_rel = $user_sql->getGroupRoleRelations())) {
320  continue;
321  }
322 
323  $checked_rights = false;
324  $checked_group_role = false;
325 
326  // Rechte prüfen
327  if (!$checkRights || Ego_User_Search_Factory::isAcceptedUser($user_sql, $group_role_rel)) {
328  $checked_rights = true;
329  }
330 
331  // Wenn in der Suchmaske eine Gruppe oder Rolle ausgewählt wurde
332  if (!$group_role || Ego_User_Search_Factory::checkRightsFilter($group_role, $user_sql, $group_role_rel)) {
333  $checked_group_role = true;
334  }
335 
336  if ($rights !== '') {
337  foreach (explode(';', $rights) as $group_role) {
338  [$group, $role] = explode(',', $group_role);
339 
340  if (!$user_sql->hasGroupRoleRelation($group, $role)) {
341  continue 2;
342  }
343  }
344  }
345 
346  if ($checked_rights && $checked_group_role) {
347  if ($group_role) {
348  // Die Paginierung für eine Gruppe/Rolle Suche muss logisch erfolgen
349  $n++;
350  if ($from > 0 && $n <= $from) {
351  continue;
352  }
353  if (sizeof($users) == $limit) {
354  break;
355  }
356  }
357 
358  $users[] = $user_sql;
359  }
360  }
361  }
362 
363  return $returnTotal ? [
364  'users' => $users,
365  'hits' => sizeof($users)
366  ] : $users;
367  }
368 
378  public function getChars($type = ''): array {
379  // Suchparameter für die Suche
380  $search_params = [
381  'index' => $this->config['index'],
382  'body' => [
383  'aggs' => [
384  'username_chars' => [
385  'aggs' => [ // Unterteilung nötig, damit je nach Typ ein Filter eingestellt werden kann
386  'username_chars' => [
387  'terms' => [
388  'field' => 'username_char',
389  'size' => 128 // Länge der ASCII-Tabelle (Mögliche Anfangsbuchstaben)
390  ]
391  ]
392  ]
393  ]
394  ],
395  'size' => -1 // Kein Suchlimit
396  ]
397  ];
398 
399  // Je nach Typ den Filter für die Abfrage setzten
400  if ($type) {
401  switch ($type) {
402  case 'admin' :
403  $search_params['body']['aggs']['username_chars']['filter'] = [
404  'bool' => [
405  'must' => [
406  [
407  'match' => [
408  'no_admin' => 0 // Nur Benutzer, die in den Adminbereich dürfen
409  ]
410  ],[
411  'match' => [
412  'no_relation' => 0 // Nur Benutzer, die in eine Gruppe/Rolle haben
413  ]
414  ], [
415  'match' => [
416  'user_inactive' => 0
417  ]
418  ], [
419  'bool' => [
420  'should' => [
421  [
422  'range' => [
423  'release_from' => [
424  'lte' => strtotime('now')
425  ]
426  ]
427  ], [
428  'match' => [
429  'release_from' => 0
430  ]
431  ]
432  ]
433  ]
434  ], [
435  'bool' => [
436  'should' => [
437  [
438  'range' => [
439  'release_until' => [
440  'gte' => strtotime('now')
441  ]
442  ]
443  ], [
444  'match' => [
445  'release_until' => 0
446  ]
447  ]
448  ]
449  ]
450  ]
451  ]
452  ]
453  ];
454  break;
455  case 'intranet' :
456  $search_params['body']['aggs']['username_chars']['filter'] = [
457  'bool' => [
458  'must' => [
459  [
460  'match' => [
461  'no_admin' => 1 // Nur Benutzer, die nicht in den Adminbereich dürfen
462  ]
463  ], [
464  'match' => [
465  'user_inactive' => 0
466  ]
467  ], [
468  'bool' => [
469  'should' => [
470  [
471  'range' => [
472  'release_from' => [
473  'lte' => strtotime('now')
474  ]
475  ]
476  ], [
477  'match' => [
478  'release_from' => 0
479  ]
480  ]
481  ]
482  ]
483  ], [
484  'bool' => [
485  'should' => [
486  [
487  'range' => [
488  'release_until' => [
489  'gte' => strtotime('now')
490  ]
491  ]
492  ], [
493  'match' => [
494  'release_until' => 0
495  ]
496  ]
497  ]
498  ]
499  ]
500  ]
501  ]
502  ];
503  break;
504  case 'norelation' :
505  $search_params['body']['aggs']['username_chars']['filter'] = [
506  'bool' => [
507  'must' => [
508  [
509  'match' => [
510  'no_relation' => 1 // Nur Benutzer, die keiner Gruppe zugewiesen sind
511  ]
512  ], [
513  'match' => [
514  'user_inactive' => 0
515  ]
516  ], [
517  'bool' => [
518  'should' => [
519  [
520  'range' => [
521  'release_from' => [
522  'lte' => strtotime('now')
523  ]
524  ]
525  ], [
526  'match' => [
527  'release_from' => 0
528  ]
529  ]
530  ]
531  ]
532  ], [
533  'bool' => [
534  'should' => [
535  [
536  'range' => [
537  'release_until' => [
538  'gte' => strtotime('now')
539  ]
540  ]
541  ], [
542  'match' => [
543  'release_until' => 0
544  ]
545  ]
546  ]
547  ]
548  ]
549  ]
550  ]
551  ];
552  break;
553  case 'inactive' :
554  $search_params['body']['aggs']['username_chars']['filter'] = [
555  'bool' => [
556  'should' => [
557  [
558  'match' => [
559  'user_inactive' => 1
560  ]
561  ], [
562  'bool' => [
563  'should' => [
564  'range' => [
565  'release_from' => [
566  'gte' => strtotime('now')
567  ]
568  ]
569  ],
570  'must_not' =>[
571  'match' => [
572  'release_from' => 0
573  ]
574  ]
575  ]
576  ], [
577  'bool' => [
578  'should' => [
579  'range' => [
580  'release_until' => [
581  'lte' => strtotime('now')
582  ]
583  ]
584  ],
585  'must_not' =>[
586  'match' => [
587  'release_until' => 0
588  ]
589  ]
590  ]
591  ]
592  ],
593  'must_not' => [
594  'match' => [
595  'user_deleted' => 1 // Keine gelöschten Benutzer finden
596  ]
597  ],
598  'minimum_should_match' => 1
599  ]
600  ];
601  }
602  }
603 
604  // Suche durchführen
605  $results = $this->client->search($search_params)['aggregations']['username_chars']['username_chars']['buckets'];
606  $return_array = [];
607 
608  // Ergebnis alphabetisch sortieren
609  usort($results, function($a, $b) {
610  return strcasecmp($a['key'], $b['key']);
611  });
612 
613  // Für jedes Ergebnis ein Array aus Buchstabe und Anzahl der Benutzer zurückliefern
614  foreach ($results as $bucket) {
615  $return_array[] = [
616  'char' => $bucket['key'], // Anfangsbuchstabe
617  'number' => $bucket['doc_count'] // Anzahl der Benutzer mit diesen Anfangsbuchstaben
618  ];
619  }
620 
621  return $return_array;
622  }
623 
631  private function getUserBody(User_SQL $user): array {
632  // Prüfen ob der Benutzer einer Gruppe zugeordnet ist
633  if (!$user->getAllGroups()) {
634  // Der Benutzer ist keiner Gruppe zugewiesen
635  $no_relation = 1;
636  } else {
637  // Der Benutzer ist mindestens einer Gruppe zugewiesen
638  $no_relation = 0;
639  }
640 
641  $fields = [
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)), // Für die Sortierung in der Sitemap
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, // Immer als int speichern
663  'liveserver' => $user->extra['liveserver'] ? 1 : 0, // Immer als int speichern
664  'user_inactive' => $user->extra['user_inactive'] ? 1 : 0, // Immer als int speichern
665  'user_deleted' => $user->field['deleted'] ? 1 : 0, // Immer als int speichern
666  'no_admin' => $user->field['no_admin'] ? 1 : 0, // Immer als int speichern
667  'no_singlesignon' => $user->extra['no_singlesignon'] ? 1 : 0, // Immer als int speichern
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']
672  ];
673 
674  // Kundenspezifische Felder in den Index aufnehmen
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]));
678  }
679  }
680 
681  return $fields;
682  }
683 
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']);
701 
702  // Suchparameter je nach Typ anpassen
703  switch ($type) {
704  case 'admin':
705  // Wenn Admin-Benutzer aufgeklappt werden
706  $search['no_admin'] = 0;
707  $search['user_inactive'] = 0;
708  break;
709  case 'intranet':
710  // Wenn Intranet-Benutzern aufgeklappt werden
711  $search['no_admin'] = 1;
712  $search['no_relation'] = 0;
713  $search['user_deleted'] = 0;
714  $search['user_inactive'] = 0;
715  break;
716  case 'norelation':
717  // Wenn Benutzer ohne Gruppenzuweisung aufgeklappt werden
718  $search['no_relation'] = 1;
719  $search['user_deleted'] = 0;
720  $search['user_inactive'] = 0;
721  break;
722  case 'inactive':
723  // Wenn Inaktive Benutzer aufgeklappt werden
724  $search['user_inactive'] = 1;
725  $search['user_deleted'] = 0;
726  break;
727  case 'trash':
728  $search['user_deleted'] = 1;
729  }
730 
731  // Maximale Anzahl an Treffer
732  if ($limit == -1 && ($max_results = intval($GLOBALS['egotec_conf']['elastic']['max_results']))) {
733  $limit = $max_results;
734  $from = 0;
735  }
736 
737  // Suchparameter
738  $search_params = [
739  'index' => $this->config['index'],
740  'body' => [
741  'query' => [
742  'bool' => [
743  'must' => [],
744  'should' => [],
745  'minimum_should_match' => 0
746  ]
747  ],
748  'size' => $limit,
749  'from' => $from,
750  ]
751  ];
752 
753  // Wenn das Ergebnis Sortiert werden soll muss die query um "sort" erweitert werden
754  if ($sortResult) {
755  $field = 'username.keyword';
756  $order = 'asc';
757 
758  if ($sort_order && $sort_order['field'] && $sort_order['field'] !== '') {
759  $field = $sort_order['field'];
760  }
761 
762  if ($sort_order && $sort_order['order'] && $sort_order['order'] !== '') {
763  $order = $sort_order['order'];
764  }
765 
766  $search_params['body']['sort'] = [
767  $field => [
768  'order' => $order,
769  'unmapped_type' => 'keyword'
770  ]
771  ];
772  }
773 
774  $must = [];
775  $should = [];
776  $minimum_should_match = 0;
777 
778  // Query um Parameter erweitern, die für die Suche nach inaktiven/aktiven Benutzern nötig sind
779  if ($search['user_inactive'] === 0) {
780  // Suche nach aktiven Benutzern
781 
782  // Nur wenn user_inactive = 0, kann der Benutzer aktiv sein (muss aber nicht)
783  $must[] = [
784  'match' => [
785  'user_inactive' => 0
786  ]
787  ];
788 
789  // Nur wenn "Freigabe von" in der Vergangenheit liegt, oder "Freigabe von" 0 ist (kein Freigabedatum), kann der Benutzer aktiv sein
790  $must[] = [
791  'bool' => [
792  'should' => [
793  [
794  'range' => [
795  'release_from' => [
796  'lte' => strtotime('now')
797  ]
798  ]
799  ], [
800  'match' => [
801  'release_from' => 0
802  ]
803  ]
804  ]
805  ]
806  ];
807 
808  // Nur wenn "Freigabe bis" in der Zukunft liegt, oder "Freigabe bis" 0 ist (kein Freigabedatum), kann der Benutzer aktiv sein
809  $must[] = [
810  'bool' => [
811  'should' => [
812  [
813  'range' => [
814  'release_until' => [
815  'gte' => strtotime('now')
816  ]
817  ]
818  ], [
819  'match' => [
820  'release_until' => 0
821  ]
822  ]
823  ]
824  ]
825  ];
826  } else if ($search['user_inactive'] === 1) {
827  // Suche nach inaktiven Benutzern -> OR verknüpfte Abfrage
828 
829  // Wenn user_inactive = 1, dann ist der Benutzer immer inaktiv
830  $should[] = [
831  'match' => [
832  'user_inactive' => 1
833  ]
834  ];
835 
836  // Wenn das Freigabedatum in der Zukunft liegt, oder 0 ist (kein Freigabedatum), ist der Benutzer inaktiv
837  $should[] = [
838  'bool' => [
839  'should' => [
840  'range' => [
841  'release_from' => [
842  'gte' => strtotime('now')
843  ]
844  ]
845  ],
846  'must_not' =>[
847  'match' => [
848  'release_from' => 0
849  ]
850  ]
851  ]
852  ];
853 
854  // Wenn das Freigabedatum in der Vergangenheit liegt, oder 0 ist (kein Freigabedatum), ist der Benutzer inaktiv
855  $should[] = [
856  'bool' => [
857  'should' => [
858  'range' => [
859  'release_until' => [
860  'lte' => strtotime('now')
861  ]
862  ]
863  ],
864  'must_not' => [
865  'match' => [
866  'release_until' => 0
867  ]
868  ]
869  ]
870  ];
871 
872  // Mindestens eine der Bedingungen trifft zu, wenn der Benutzer inaktiv ist
873  $minimum_should_match = 1;
874  }
875 
876  unset($search['user_inactive']);
877 
878  // Folgende Parameter exakt suchen, den Rest als wildcard
879  $match_exact = ['no_admin', 'no_relation', 'user_inactive', 'user_deleted', 'username_char'];
880 
881  $search_lower = ['username', 'email', 'vorname', 'name', 'categories'];
882 
883  // Kundenspezifische Felder berücksichtigen
884  if ($GLOBALS['egotec_conf']['user_search_fields']) {
885  if (Ego_System::file_exists($GLOBALS['egotec_conf']['var_dir'] . 'lib/admin/user_search_fields.php')) {
886  // Gibt es einen kundenspezifischen Filter, dann werden die eigenen Felder nicht abgefragt
887  $search = array_diff_key($search, $GLOBALS['egotec_conf']['user_search_fields']);
888  } else {
889  foreach ($GLOBALS['egotec_conf']['user_search_fields'] as $name => $type) {
890  if ($type == 'boolean') {
891  $match_exact[] = $name;
892  }
893  }
894  }
895  }
896 
897  // Query aufbauen
898  foreach ($search as $key => $value) {
899  // Keine leeren Werte in den Query aufnehmen (0 ist kein leerer Wert)
900  if (($value !== '' && $value !== false && $value !== null) || $key === 'username') { // Username kann bei der Suche leer sein
901  if (in_array($key, $match_exact)) {
902  // Wenn der aktuelle $key muss exakt gesucht werden muss
903  $must[] = [
904  'match' => [
905  $key => $value
906  ]
907  ];
908  } else {
909  // Bei manchen keys muss nach dem keyword gesucht werden
910  if (in_array($key, ['username', 'vorname', 'name'])) {
911  $key = "$key.keyword";
912  }
913 
914  // Der aktuelle $key muss als wildcard gesucht werden
915  $must[] = [
916  'wildcard' => [
917  $key => $value && !in_array($key, ['tfa_secret'])
918  ? '*' . (in_array($key, $search_lower) ? mb_strtolower($value) : $value) . '*'
919  : '*'
920  ]
921  ];
922  }
923  }
924  }
925 
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;
929 
930  return $search_params;
931  }
932 }
static file_exists($file)
static flush($string='')
Definition: Ego_System.php:934
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)