ILIAS  Release_4_4_x_branch Revision 61816
 All Data Structures Namespaces Files Functions Variables Groups Pages
class.ilUserAutoComplete.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (c) 1998-2013 ILIAS open source, Extended GPL, see docs/LICENSE */
3 
8 {
12  const SEARCH_TYPE_LIKE = 1;
13 
17  const SEARCH_TYPE_EQUALS = 2;
18 
23 
28 
32  private $searchable_check = false;
33 
37  private $user_access_check = true;
38 
42  private $possible_fields = array();
43 
47  private $result_field;
48 
52  private $search_type;
53 
57  private $privacy_mode;
58 
62  private $user;
63 
67  public function __construct()
68  {
69  $this->result_field = 'login';
70 
71  $this->setSearchType(self::SEARCH_TYPE_LIKE);
72  $this->setPrivacyMode(self::PRIVACY_MODE_IGNORE_USER_SETTING);
73  }
74 
78  public function setSearchType($search_type)
79  {
80  $this->search_type = $search_type;
81  }
82 
86  public function getSearchType()
87  {
88  return $this->search_type;
89  }
90 
94  public function setPrivacyMode($privacy_mode)
95  {
96  $this->privacy_mode = $privacy_mode;
97  }
98 
102  public function getPrivacyMode()
103  {
104  return $this->privacy_mode;
105  }
106 
110  public function setUser($user)
111  {
112  $this->user = $user;
113  }
114 
118  public function getUser()
119  {
120  return $this->user;
121  }
122 
127  public function enableFieldSearchableCheck($a_status)
128  {
129  $this->searchable_check = $a_status;
130  }
131 
137  {
139  }
140 
146  public function enableUserAccessCheck($a_status)
147  {
148  $this->user_access_check = $a_status;
149  }
150 
155  public function isUserAccessCheckEnabled()
156  {
158  }
159 
164  public function setSearchFields($a_fields)
165  {
166  $this->possible_fields = $a_fields;
167  }
168 
173  public function getSearchFields()
174  {
175  return $this->possible_fields;
176  }
177 
182  protected function getFields()
183  {
184  if(!$this->isFieldSearchableCheckEnabled())
185  {
186  return $this->getSearchFields();
187  }
188  $available_fields = array();
189  foreach($this->getSearchFields() as $field)
190  {
191  include_once 'Services/Search/classes/class.ilUserSearchOptions.php';
193  {
194  $available_fields[] = $field;
195  }
196  }
197  return $available_fields;
198  }
199 
204  public function setResultField($a_field)
205  {
206  $this->result_field = $a_field;
207  }
208 
214  public function getList($a_str)
215  {
220  global $ilDB, $ilLog;
221 
222  $select_part = $this->getSelectPart();
223  $where_part = $this->getWherePart($a_str);
224  $order_by_part = $this->getOrderByPart();
225  $query = implode(" ", array(
226  'SELECT ' . $select_part,
227  'FROM ' . $this->getFromPart(),
228  $where_part ? 'WHERE ' . $where_part : '',
229  $order_by_part ? 'ORDER BY ' . $order_by_part : ''
230  ));
231 
232  $ilLog->write(__METHOD__ . ': Query: ' . $query);
233 
234  $res = $ilDB->query($query);
235 
236  // add email only if it is "searchable"
237  $add_email = true;
238  include_once 'Services/Search/classes/class.ilUserSearchOptions.php';
240  {
241  $add_email = false;
242  }
243 
244  include_once './Services/Search/classes/class.ilSearchSettings.php';
245  $max = ilSearchSettings::getInstance()->getAutoCompleteLength();
246  $cnt = 0;
247  $result = array();
248  while(($rec = $ilDB->fetchAssoc($res)) && $cnt < $max)
249  {
250  // @todo: Open discussion: We should remove all non public fields from result
251  $label = $rec['lastname'] . ', ' . $rec['firstname'] . ' [' . $rec['login'] . ']';
252 
253  if($add_email && $rec['email'] && (self::PRIVACY_MODE_RESPECT_USER_SETTING != $this->getPrivacyMode() || 'y' == $rec['email_value']))
254  {
255  $label .= ', ' . $rec['email'];
256  }
257 
258  $result[$cnt] = new stdClass();
259  $result[$cnt]->value = (string)$rec[$this->result_field];
260  $result[$cnt]->label = $label;
261  $cnt++;
262  }
263 
264  include_once 'Services/JSON/classes/class.ilJsonUtil.php';
265  return ilJsonUtil::encode($result);
266  }
267 
271  protected function getSelectPart()
272  {
273  $fields = array(
274  'login',
275  'firstname',
276  'lastname',
277  'email'
278  );
279 
280  if(self::PRIVACY_MODE_RESPECT_USER_SETTING == $this->getPrivacyMode())
281  {
282  $fields[] = 'profpref.value profile_value';
283  $fields[] = 'pubemail.value email_value';
284  }
285 
286  return implode(', ', $fields);
287  }
288 
292  protected function getFromPart()
293  {
297  global $ilDB;
298 
299  $joins = array();
300 
301  if(self::PRIVACY_MODE_RESPECT_USER_SETTING == $this->getPrivacyMode())
302  {
303  $joins[] = 'LEFT JOIN usr_pref profpref
304  ON profpref.usr_id = usr_data.usr_id
305  AND profpref.keyword = ' . $ilDB->quote('public_profile', 'text');
306 
307  $joins[] = 'LEFT JOIN usr_pref pubemail
308  ON pubemail.usr_id = usr_data.usr_id
309  AND pubemail.keyword = ' . $ilDB->quote('public_email', 'text');
310  }
311 
312  if($joins)
313  {
314  return 'usr_data ' . implode(' ', $joins);
315  }
316  else
317  {
318  return 'usr_data ';
319  }
320  }
321 
326  protected function getWherePart($search_query)
327  {
332  global $ilDB, $ilSetting;
333 
334  $outer_conditions = array();
335 
336  // In 'anonymous' context with respected user privacy, only users with globally published profiles should be found.
337  if(self::PRIVACY_MODE_RESPECT_USER_SETTING == $this->getPrivacyMode() &&
338  $this->getUser() instanceof ilObjUser &&
339  $this->getUser()->isAnonymous()
340  )
341  {
342  if(!$ilSetting->get('enable_global_profiles', 0))
343  {
344  // If 'Enable User Content Publishing' is not set in the administration, no user should be found for 'anonymous' context.
345  return '1 = 2';
346  }
347  else
348  {
349  // Otherwise respect the profile activation setting of every user (as a global (outer) condition in the where clause).
350  $outer_conditions[] = 'profpref.value = ' . $ilDB->quote('g', 'text');
351  }
352  }
353 
354  $outer_conditions[] = 'usr_data.usr_id != ' . $ilDB->quote(ANONYMOUS_USER_ID, 'integer');
355 
356  $field_conditions = array();
357  foreach($this->getFields() as $field)
358  {
359  $field_condition = $this->getQueryConditionByFieldAndValue($field, $search_query);
360 
361  if('email' == $field && self::PRIVACY_MODE_RESPECT_USER_SETTING == $this->getPrivacyMode())
362  {
363  // If privacy should be respected, the profile setting of every user concerning the email address has to be
364  // respected (in every user context, no matter if the user is 'logged in' or 'anonymous').
365  $email_query = array();
366  $email_query[] = $field_condition;
367  $email_query[] = 'pubemail.value = ' . $ilDB->quote('y', 'text');
368  $field_conditions[] = '(' . implode(' AND ', $email_query) . ')';
369  }
370  else
371  {
372  $field_conditions[] = $field_condition;
373  }
374  }
375 
376  // If the current user context ist 'logged in' and privacy should be respected, all fields >>>except the login<<<
377  // should only be searchable if the users' profile is published (y oder g)
378  // In 'anonymous' context we do not need this additional conditions,
379  // because we checked the privacy setting in the condition above: profile = 'g'
380  if(self::PRIVACY_MODE_RESPECT_USER_SETTING == $this->getPrivacyMode() &&
381  $this->getUser() instanceof ilObjUser && !$this->getUser()->isAnonymous() &&
382  $field_conditions
383  )
384  {
385  $fields = implode(' OR ', $field_conditions);
386 
387  $field_conditions[] = '(' . implode(' AND ', array(
388  $fields,
389  $ilDB->in('profpref.value', array('y', 'g'), false, 'text')
390  )) . ')';
391  }
392 
393  // The login field must be searchable regardless (for 'logged in' users) of any privacy settings.
394  // We handled the general condition for 'anonymous' context above: profile = 'g'
395  $field_conditions[] = $this->getQueryConditionByFieldAndValue('login', $search_query);
396 
397  include_once 'Services/User/classes/class.ilUserAccountSettings.php';
398  if(ilUserAccountSettings::getInstance()->isUserAccessRestricted())
399  {
400  include_once './Services/User/classes/class.ilUserFilter.php';
401  $outer_conditions[] = $ilDB->in('time_limit_owner', ilUserFilter::getInstance()->getFolderIds(), false, 'integer');
402  }
403 
404  if($field_conditions)
405  {
406  $outer_conditions[] = '(' . implode(' OR ', $field_conditions) . ')';
407  }
408 
409  return implode(' AND ', $outer_conditions);
410  }
411 
415  protected function getOrderByPart()
416  {
417  return 'login ASC';
418  }
419 
425  protected function getQueryConditionByFieldAndValue($field, $a_str)
426  {
430  global $ilDB;
431 
432  // #14768
433  if(!stristr($a_str, '\\'))
434  {
435  $a_str = str_replace('%', '\%', $a_str);
436  $a_str = str_replace('_', '\_', $a_str);
437  }
438 
439  if(self::SEARCH_TYPE_LIKE == $this->getSearchType())
440  {
441  return $ilDB->like($field, 'text', $a_str . '%');
442  }
443  else
444  {
445  return $ilDB->like($field, 'text', $a_str);
446  }
447  }
448 }