ILIAS  Release_5_0_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 {
9  const MAX_ENTRIES = 1000;
10 
11 
15  const SEARCH_TYPE_LIKE = 1;
16 
20  const SEARCH_TYPE_EQUALS = 2;
21 
26 
31 
35  private $searchable_check = false;
36 
40  private $user_access_check = true;
41 
45  private $possible_fields = array();
46 
50  private $result_field;
51 
55  private $search_type;
56 
60  private $privacy_mode;
61 
65  private $user;
66 
67 
68  private $limit = 0;
69 
73  private $more_link_available = false;
74 
78  public function __construct()
79  {
80  $this->result_field = 'login';
81 
82  $this->setSearchType(self::SEARCH_TYPE_LIKE);
83  $this->setPrivacyMode(self::PRIVACY_MODE_IGNORE_USER_SETTING);
84  }
85 
86  public function setLimit($a_limit)
87  {
88  $this->limit = $a_limit;
89  }
90 
91  public function getLimit()
92  {
93  return $this->limit;
94  }
95 
99  public function setSearchType($search_type)
100  {
101  $this->search_type = $search_type;
102  }
103 
107  public function getSearchType()
108  {
109  return $this->search_type;
110  }
111 
115  public function setPrivacyMode($privacy_mode)
116  {
117  $this->privacy_mode = $privacy_mode;
118  }
119 
123  public function getPrivacyMode()
124  {
125  return $this->privacy_mode;
126  }
127 
131  public function setUser($user)
132  {
133  $this->user = $user;
134  }
135 
139  public function getUser()
140  {
141  return $this->user;
142  }
143 
148  public function enableFieldSearchableCheck($a_status)
149  {
150  $this->searchable_check = $a_status;
151  }
152 
158  {
160  }
161 
167  public function enableUserAccessCheck($a_status)
168  {
169  $this->user_access_check = $a_status;
170  }
171 
176  public function isUserAccessCheckEnabled()
177  {
179  }
180 
185  public function setSearchFields($a_fields)
186  {
187  $this->possible_fields = $a_fields;
188  }
189 
194  public function getSearchFields()
195  {
196  return $this->possible_fields;
197  }
198 
203  protected function getFields()
204  {
205  if(!$this->isFieldSearchableCheckEnabled())
206  {
207  return $this->getSearchFields();
208  }
209  $available_fields = array();
210  foreach($this->getSearchFields() as $field)
211  {
212  include_once 'Services/Search/classes/class.ilUserSearchOptions.php';
214  {
215  $available_fields[] = $field;
216  }
217  }
218  return $available_fields;
219  }
220 
225  public function setResultField($a_field)
226  {
227  $this->result_field = $a_field;
228  }
229 
235  public function getList($a_str)
236  {
241  global $ilDB, $ilLog;
242 
243  $select_part = $this->getSelectPart();
244  $where_part = $this->getWherePart($a_str);
245  $order_by_part = $this->getOrderByPart();
246  $query = implode(" ", array(
247  'SELECT ' . $select_part,
248  'FROM ' . $this->getFromPart(),
249  $where_part ? 'WHERE ' . $where_part : '',
250  $order_by_part ? 'ORDER BY ' . $order_by_part : ''
251  ));
252 
253  $ilLog->write(__METHOD__ . ': Query: ' . $query);
254 
255  $res = $ilDB->query($query);
256 
257  // add email only if it is "searchable"
258  $add_email = true;
259  include_once 'Services/Search/classes/class.ilUserSearchOptions.php';
261  {
262  $add_email = false;
263  }
264 
265  include_once './Services/Search/classes/class.ilSearchSettings.php';
266  $max = $this->getLimit() ? $this->getLimit() : ilSearchSettings::getInstance()->getAutoCompleteLength();
267  $cnt = 0;
268  $more_results = FALSE;
269  $result = array();
270  while(($rec = $ilDB->fetchAssoc($res)) && $cnt < ($max + 1))
271  {
272  if($cnt >= $max && $this->isMoreLinkAvailable())
273  {
274  $more_results = TRUE;
275  break;
276  }
277 
278  // @todo: Open discussion: We should remove all non public fields from result
279  $label = $rec['lastname'] . ', ' . $rec['firstname'] . ' [' . $rec['login'] . ']';
280 
281  if($add_email && $rec['email'] && (self::PRIVACY_MODE_RESPECT_USER_SETTING != $this->getPrivacyMode() || 'y' == $rec['email_value']))
282  {
283  $label .= ', ' . $rec['email'];
284  }
285 
286  $result[$cnt]['value'] = (string)$rec[$this->result_field];
287  $result[$cnt]['label'] = $label;
288  $result[$cnt]['id'] = $rec['usr_id'];
289  $cnt++;
290  }
291 
292  include_once 'Services/JSON/classes/class.ilJsonUtil.php';
293 
294  $result_json['items'] = $result;
295  $result_json['hasMoreResults'] = $more_results;
296 
297  $GLOBALS['ilLog']->write(__METHOD__.': '.print_r($result_json,TRUE));
298 
299  return ilJsonUtil::encode($result_json);
300  }
301 
305  protected function getSelectPart()
306  {
307  $fields = array(
308  'ud.usr_id',
309  'ud.login',
310  'ud.firstname',
311  'ud.lastname',
312  'ud.email'
313  );
314 
315  if(self::PRIVACY_MODE_RESPECT_USER_SETTING == $this->getPrivacyMode())
316  {
317  $fields[] = 'profpref.value profile_value';
318  $fields[] = 'pubemail.value email_value';
319  }
320 
321  return implode(', ', $fields);
322  }
323 
327  protected function getFromPart()
328  {
332  global $ilDB;
333 
334  $joins = array();
335 
336  if(self::PRIVACY_MODE_RESPECT_USER_SETTING == $this->getPrivacyMode())
337  {
338  $joins[] = 'LEFT JOIN usr_pref profpref
339  ON profpref.usr_id = ud.usr_id
340  AND profpref.keyword = ' . $ilDB->quote('public_profile', 'text');
341 
342  $joins[] = 'LEFT JOIN usr_pref pubemail
343  ON pubemail.usr_id = ud.usr_id
344  AND pubemail.keyword = ' . $ilDB->quote('public_email', 'text');
345  }
346 
347  if($joins)
348  {
349  return 'usr_data ud ' . implode(' ', $joins);
350  }
351  else
352  {
353  return 'usr_data ud';
354  }
355  }
356 
361  protected function getWherePart($search_query)
362  {
367  global $ilDB, $ilSetting;
368 
369  $outer_conditions = array();
370 
371  // In 'anonymous' context with respected user privacy, only users with globally published profiles should be found.
372  if(self::PRIVACY_MODE_RESPECT_USER_SETTING == $this->getPrivacyMode() &&
373  $this->getUser() instanceof ilObjUser &&
374  $this->getUser()->isAnonymous()
375  )
376  {
377  if(!$ilSetting->get('enable_global_profiles', 0))
378  {
379  // If 'Enable User Content Publishing' is not set in the administration, no user should be found for 'anonymous' context.
380  return '1 = 2';
381  }
382  else
383  {
384  // Otherwise respect the profile activation setting of every user (as a global (outer) condition in the where clause).
385  $outer_conditions[] = 'profpref.value = ' . $ilDB->quote('g', 'text');
386  }
387  }
388 
389  $outer_conditions[] = 'ud.usr_id != ' . $ilDB->quote(ANONYMOUS_USER_ID, 'integer');
390 
391  $field_conditions = array();
392  foreach($this->getFields() as $field)
393  {
394  $field_condition = $this->getQueryConditionByFieldAndValue($field, $search_query);
395 
396  if('email' == $field && self::PRIVACY_MODE_RESPECT_USER_SETTING == $this->getPrivacyMode())
397  {
398  // If privacy should be respected, the profile setting of every user concerning the email address has to be
399  // respected (in every user context, no matter if the user is 'logged in' or 'anonymous').
400  $email_query = array();
401  $email_query[] = $field_condition;
402  $email_query[] = 'pubemail.value = ' . $ilDB->quote('y', 'text');
403  $field_conditions[] = '(' . implode(' AND ', $email_query) . ')';
404  }
405  else
406  {
407  $field_conditions[] = $field_condition;
408  }
409  }
410 
411  // If the current user context ist 'logged in' and privacy should be respected, all fields >>>except the login<<<
412  // should only be searchable if the users' profile is published (y oder g)
413  // In 'anonymous' context we do not need this additional conditions,
414  // because we checked the privacy setting in the condition above: profile = 'g'
415  if(self::PRIVACY_MODE_RESPECT_USER_SETTING == $this->getPrivacyMode() &&
416  $this->getUser() instanceof ilObjUser && !$this->getUser()->isAnonymous() &&
417  $field_conditions
418  )
419  {
420  $fields = implode(' OR ', $field_conditions);
421 
422  $field_conditions[] = '(' . implode(' AND ', array(
423  $fields,
424  $ilDB->in('profpref.value', array('y', 'g'), false, 'text')
425  )) . ')';
426  }
427 
428  // The login field must be searchable regardless (for 'logged in' users) of any privacy settings.
429  // We handled the general condition for 'anonymous' context above: profile = 'g'
430  $field_conditions[] = $this->getQueryConditionByFieldAndValue('login', $search_query);
431 
432  include_once 'Services/User/classes/class.ilUserAccountSettings.php';
433  if(ilUserAccountSettings::getInstance()->isUserAccessRestricted())
434  {
435  include_once './Services/User/classes/class.ilUserFilter.php';
436  $outer_conditions[] = $ilDB->in('time_limit_owner', ilUserFilter::getInstance()->getFolderIds(), false, 'integer');
437  }
438 
439  if($field_conditions)
440  {
441  $outer_conditions[] = '(' . implode(' OR ', $field_conditions) . ')';
442  }
443 
444  return implode(' AND ', $outer_conditions);
445  }
446 
450  protected function getOrderByPart()
451  {
452  return 'login ASC';
453  }
454 
460  protected function getQueryConditionByFieldAndValue($field, $a_str)
461  {
465  global $ilDB;
466 
467  // #14768
468  if(!stristr($a_str, '\\'))
469  {
470  $a_str = str_replace('%', '\%', $a_str);
471  $a_str = str_replace('_', '\_', $a_str);
472  }
473 
474  if(self::SEARCH_TYPE_LIKE == $this->getSearchType())
475  {
476  return $ilDB->like($field, 'text', $a_str . '%');
477  }
478  else
479  {
480  return $ilDB->like($field, 'text', $a_str);
481  }
482  }
483 
487  public function isMoreLinkAvailable()
488  {
490  }
491 
498  {
499  $this->more_link_available = $more_link_available;
500  }
501 
502 
503 }