ILIAS  trunk Revision v12.0_alpha-16-g3e876e53c80
LegacyUserSearchBasedProvider.php
Go to the documentation of this file.
1<?php
2
19declare(strict_types=1);
20
22
27{
31 public function current(): array
32 {
33 return [
34 'login' => $this->data['login'],
35 'firstname' => $this->data['firstname'],
36 'lastname' => $this->data['lastname'],
37 ];
38 }
39
40 public function key(): string
41 {
42 return $this->data['login'];
43 }
44
45 public function rewind(): void
46 {
47 if ($this->res !== null) {
48 $this->db->free($this->res);
49 $this->res = null;
50 }
51
52 $select_part = $this->getSelectPart();
53 $where_part = $this->getWherePart($this->quoted_term);
54 $order_by_part = $this->getOrderByPart();
55 $query = implode(' ', [
56 'SELECT ' . $select_part,
57 'FROM ' . $this->getFromPart(),
58 $where_part !== '' ? 'WHERE ' . $where_part : '',
59 $order_by_part !== '' ? 'ORDER BY ' . $order_by_part : '',
60 ]);
61
62 $this->res = $this->db->query($query);
63 }
64
65 protected function getSelectPart(): string
66 {
67 $fields = [
68 'login',
69 \sprintf(
70 '(CASE WHEN (firstname IS NOT NULL AND (profpref.value = %s OR profpref.value = %s)) THEN firstname ELSE \'\' END) firstname',
71 $this->db->quote('y', 'text'),
72 $this->db->quote('g', 'text')
73 ),
74 \sprintf(
75 '(CASE WHEN (lastname IS NOT NULL AND (profpref.value = %s OR profpref.value = %s)) THEN lastname ELSE \'\' END) lastname',
76 $this->db->quote('y', 'text'),
77 $this->db->quote('g', 'text')
78 ),
79 \sprintf(
80 '(CASE WHEN (email IS NOT NULL AND (profpref.value = %s OR profpref.value = %s) ' .
81 "AND pubemail.value = %s) THEN email ELSE '' END) email",
82 $this->db->quote('y', 'text'),
83 $this->db->quote('g', 'text'),
84 $this->db->quote('y', 'text')
85 ),
86 ];
87
88 $fields[] = 'profpref.value profile_value';
89 $fields[] = 'pubemail.value email_value';
90
91 return implode(', ', $fields);
92 }
93
94 protected function getFromPart(): string
95 {
96 $joins = [];
97
98 $joins[] = '
99 LEFT JOIN usr_pref profpref
100 ON profpref.usr_id = usr_data.usr_id
101 AND profpref.keyword = ' . $this->db->quote('public_profile', 'text');
102
103 $joins[] = '
104 LEFT JOIN usr_pref pubemail
105 ON pubemail.usr_id = usr_data.usr_id
106 AND pubemail.keyword = ' . $this->db->quote('public_email', 'text');
107
108 return 'usr_data ' . implode(' ', $joins);
109 }
110
111 protected function getWherePart(string $search_query): string
112 {
113 $outer_conditions = [];
114 $outer_conditions[] = 'usr_data.usr_id != ' . $this->db->quote(ANONYMOUS_USER_ID, 'integer');
115 $outer_conditions[] = 'usr_data.active != ' . $this->db->quote(0, 'integer');
116
117 $field_conditions = [];
118 foreach ($this->getFields() as $field) {
119 $field_condition = $this->getQueryConditionByFieldAndValue($field, $search_query);
120
121 if ($field === 'email') {
122 // If privacy should be respected,
123 // the profile setting of every user concerning the email address has to be
124 // respected (in every user context, no matter if the user is 'logged in' or 'anonymous').
125 $email_query = [];
126 $email_query[] = $field_condition;
127 $email_query[] = 'pubemail.value = ' . $this->db->quote('y', 'text');
128 $field_conditions[] = '(' . implode(' AND ', $email_query) . ')';
129 } else {
130 $field_conditions[] = $field_condition;
131 }
132 }
133
134 // If the current user context ist 'logged in' and privacy should be respected,
135 // all fields >>>except the login<<<
136 // should only be searchable if the users' profile is published (y oder g)
137 // In 'anonymous' context we do not need this additional conditions,
138 // because we checked the privacy setting in the condition above: profile = 'g'
139 if ($field_conditions !== []) {
140 $fields = '(' . implode(' OR ', $field_conditions) . ')';
141
142 $field_conditions = [
143 '(' . implode(' AND ', [
144 $fields,
145 $this->db->in('profpref.value', ['y', 'g'], false, 'text'),
146 ]) . ')'
147 ];
148 }
149
150 // The login field must be searchable regardless (for 'logged in' users) of any privacy settings.
151 // We handled the general condition for 'anonymous' context above: profile = 'g'
152 $field_conditions[] = $this->getQueryConditionByFieldAndValue('login', $search_query);
153
154 if (\ilUserAccountSettings::getInstance()->isUserAccessRestricted()) {
155 $outer_conditions[] = $this->db->in(
156 'time_limit_owner',
157 \ilUserFilter::getInstance()->getFolderIds(),
158 false,
159 'integer'
160 );
161 }
162
163 if ($field_conditions !== []) {
164 $outer_conditions[] = '(' . implode(' OR ', $field_conditions) . ')';
165 }
166
167 return implode(' AND ', $outer_conditions);
168 }
169
170 protected function getOrderByPart(): string
171 {
172 return 'login ASC';
173 }
174
175 protected function getQueryConditionByFieldAndValue(string $field, $a_str): string
176 {
177 return $this->db->like($field, 'text', $a_str . '%');
178 }
179
183 protected function getFields(): array
184 {
185 $available_fields = [];
186 foreach (['firstname', 'lastname'] as $field) {
187 if (\ilUserSearchOptions::_isEnabled($field)) {
188 $available_fields[] = $field;
189 }
190 }
191
192 return $available_fields;
193 }
194}
@phpstan-import-type AutoCompleteUserRecord from RecipientSearchProvider
@phpstan-type AutoCompleteUserRecord array{login?: string, firstname?: string, lastname?...
const ANONYMOUS_USER_ID
Definition: constants.php:27