ILIAS  release_5-1 Revision 5.0.0-5477-g43f3e3fab5f
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 
70  private $user_limitations = true;
71 
75  private $more_link_available = false;
76 
80  public function __construct()
81  {
82  $this->result_field = 'login';
83 
84  $this->setSearchType(self::SEARCH_TYPE_LIKE);
85  $this->setPrivacyMode(self::PRIVACY_MODE_IGNORE_USER_SETTING);
86  }
87 
88  public function setLimit($a_limit)
89  {
90  $this->limit = $a_limit;
91  }
92 
93  public function getLimit()
94  {
95  return $this->limit;
96  }
97 
101  public function setSearchType($search_type)
102  {
103  $this->search_type = $search_type;
104  }
105 
109  public function getSearchType()
110  {
111  return $this->search_type;
112  }
113 
117  public function setPrivacyMode($privacy_mode)
118  {
119  $this->privacy_mode = $privacy_mode;
120  }
121 
125  public function getPrivacyMode()
126  {
127  return $this->privacy_mode;
128  }
129 
133  public function setUser($user)
134  {
135  $this->user = $user;
136  }
137 
141  public function getUser()
142  {
143  return $this->user;
144  }
145 
150  public function enableFieldSearchableCheck($a_status)
151  {
152  $this->searchable_check = $a_status;
153  }
154 
160  {
162  }
163 
169  public function enableUserAccessCheck($a_status)
170  {
171  $this->user_access_check = $a_status;
172  }
173 
178  public function isUserAccessCheckEnabled()
179  {
181  }
182 
187  public function setSearchFields($a_fields)
188  {
189  $this->possible_fields = $a_fields;
190  }
191 
196  public function getSearchFields()
197  {
198  return $this->possible_fields;
199  }
200 
205  protected function getFields()
206  {
207  if(!$this->isFieldSearchableCheckEnabled())
208  {
209  return $this->getSearchFields();
210  }
211  $available_fields = array();
212  foreach($this->getSearchFields() as $field)
213  {
214  include_once 'Services/Search/classes/class.ilUserSearchOptions.php';
216  {
217  $available_fields[] = $field;
218  }
219  }
220  return $available_fields;
221  }
222 
227  public function setResultField($a_field)
228  {
229  $this->result_field = $a_field;
230  }
231 
237  public function getList($a_str)
238  {
243  global $ilDB, $ilLog;
244 
245  $select_part = $this->getSelectPart();
246  $where_part = $this->getWherePart($a_str);
247  $order_by_part = $this->getOrderByPart();
248  $query = implode(" ", array(
249  'SELECT ' . $select_part,
250  'FROM ' . $this->getFromPart(),
251  $where_part ? 'WHERE ' . $where_part : '',
252  $order_by_part ? 'ORDER BY ' . $order_by_part : ''
253  ));
254 
255  $ilLog->write(__METHOD__ . ': Query: ' . $query);
256 
257  $res = $ilDB->query($query);
258 
259  // add email only if it is "searchable"
260  $add_email = true;
261  include_once 'Services/Search/classes/class.ilUserSearchOptions.php';
263  {
264  $add_email = false;
265  }
266 
267  include_once './Services/Search/classes/class.ilSearchSettings.php';
268  $max = $this->getLimit() ? $this->getLimit() : ilSearchSettings::getInstance()->getAutoCompleteLength();
269  $cnt = 0;
270  $more_results = FALSE;
271  $result = array();
272  while(($rec = $ilDB->fetchAssoc($res)) && $cnt < ($max + 1))
273  {
274  if($cnt >= $max && $this->isMoreLinkAvailable())
275  {
276  $more_results = TRUE;
277  break;
278  }
279 
280  // @todo: Open discussion: We should remove all non public fields from result
281  $label = $rec['lastname'] . ', ' . $rec['firstname'] . ' [' . $rec['login'] . ']';
282 
283  if($add_email && $rec['email'] && (self::PRIVACY_MODE_RESPECT_USER_SETTING != $this->getPrivacyMode() || 'y' == $rec['email_value']))
284  {
285  $label .= ', ' . $rec['email'];
286  }
287 
288  $result[$cnt]['value'] = (string)$rec[$this->result_field];
289  $result[$cnt]['label'] = $label;
290  $result[$cnt]['id'] = $rec['usr_id'];
291  $cnt++;
292  }
293 
294  include_once 'Services/JSON/classes/class.ilJsonUtil.php';
295 
296  $result_json['items'] = $result;
297  $result_json['hasMoreResults'] = $more_results;
298 
299  $GLOBALS['ilLog']->write(__METHOD__.': '.print_r($result_json,TRUE));
300 
301  return ilJsonUtil::encode($result_json);
302  }
303 
307  protected function getSelectPart()
308  {
309  $fields = array(
310  'ud.usr_id',
311  'ud.login',
312  'ud.firstname',
313  'ud.lastname',
314  'ud.email'
315  );
316 
317  if(self::PRIVACY_MODE_RESPECT_USER_SETTING == $this->getPrivacyMode())
318  {
319  $fields[] = 'profpref.value profile_value';
320  $fields[] = 'pubemail.value email_value';
321  }
322 
323  return implode(', ', $fields);
324  }
325 
329  protected function getFromPart()
330  {
334  global $ilDB;
335 
336  $joins = array();
337 
338  if(self::PRIVACY_MODE_RESPECT_USER_SETTING == $this->getPrivacyMode())
339  {
340  $joins[] = 'LEFT JOIN usr_pref profpref
341  ON profpref.usr_id = ud.usr_id
342  AND profpref.keyword = ' . $ilDB->quote('public_profile', 'text');
343 
344  $joins[] = 'LEFT JOIN usr_pref pubemail
345  ON pubemail.usr_id = ud.usr_id
346  AND pubemail.keyword = ' . $ilDB->quote('public_email', 'text');
347  }
348 
349  if($joins)
350  {
351  return 'usr_data ud ' . implode(' ', $joins);
352  }
353  else
354  {
355  return 'usr_data ud';
356  }
357  }
358 
363  protected function getWherePart($search_query)
364  {
369  global $ilDB, $ilSetting;
370 
371  $outer_conditions = array();
372 
373  // In 'anonymous' context with respected user privacy, only users with globally published profiles should be found.
374  if(self::PRIVACY_MODE_RESPECT_USER_SETTING == $this->getPrivacyMode() &&
375  $this->getUser() instanceof ilObjUser &&
376  $this->getUser()->isAnonymous()
377  )
378  {
379  if(!$ilSetting->get('enable_global_profiles', 0))
380  {
381  // If 'Enable User Content Publishing' is not set in the administration, no user should be found for 'anonymous' context.
382  return '1 = 2';
383  }
384  else
385  {
386  // Otherwise respect the profile activation setting of every user (as a global (outer) condition in the where clause).
387  $outer_conditions[] = 'profpref.value = ' . $ilDB->quote('g', 'text');
388  }
389  }
390 
391  $outer_conditions[] = 'ud.usr_id != ' . $ilDB->quote(ANONYMOUS_USER_ID, 'integer');
392 
393  $field_conditions = array();
394  foreach($this->getFields() as $field)
395  {
396  $field_condition = $this->getQueryConditionByFieldAndValue($field, $search_query);
397 
398  if('email' == $field && self::PRIVACY_MODE_RESPECT_USER_SETTING == $this->getPrivacyMode())
399  {
400  // If privacy should be respected, the profile setting of every user concerning the email address has to be
401  // respected (in every user context, no matter if the user is 'logged in' or 'anonymous').
402  $email_query = array();
403  $email_query[] = $field_condition;
404  $email_query[] = 'pubemail.value = ' . $ilDB->quote('y', 'text');
405  $field_conditions[] = '(' . implode(' AND ', $email_query) . ')';
406  }
407  else
408  {
409  $field_conditions[] = $field_condition;
410  }
411  }
412 
413  // If the current user context ist 'logged in' and privacy should be respected, all fields >>>except the login<<<
414  // should only be searchable if the users' profile is published (y oder g)
415  // In 'anonymous' context we do not need this additional conditions,
416  // because we checked the privacy setting in the condition above: profile = 'g'
417  if(self::PRIVACY_MODE_RESPECT_USER_SETTING == $this->getPrivacyMode() &&
418  $this->getUser() instanceof ilObjUser && !$this->getUser()->isAnonymous() &&
419  $field_conditions
420  )
421  {
422  $fields = implode(' OR ', $field_conditions);
423 
424  $field_conditions[] = '(' . implode(' AND ', array(
425  $fields,
426  $ilDB->in('profpref.value', array('y', 'g'), false, 'text')
427  )) . ')';
428  }
429 
430  // The login field must be searchable regardless (for 'logged in' users) of any privacy settings.
431  // We handled the general condition for 'anonymous' context above: profile = 'g'
432  $field_conditions[] = $this->getQueryConditionByFieldAndValue('login', $search_query);
433 
434  include_once 'Services/User/classes/class.ilUserAccountSettings.php';
435  if(ilUserAccountSettings::getInstance()->isUserAccessRestricted())
436  {
437  include_once './Services/User/classes/class.ilUserFilter.php';
438  $outer_conditions[] = $ilDB->in('time_limit_owner', ilUserFilter::getInstance()->getFolderIds(), false, 'integer');
439  }
440 
441  if($field_conditions)
442  {
443  $outer_conditions[] = '(' . implode(' OR ', $field_conditions) . ')';
444  }
445 
446  include_once './Services/Search/classes/class.ilSearchSettings.php';
447  $settings = ilSearchSettings::getInstance();
448 
449  if(!$settings->isInactiveUserVisible() && $this->getUserLimitations())
450  {
451  $outer_conditions[] = "ud.active = ". $ilDB->quote(1, 'integer');
452  }
453 
454  if(!$settings->isLimitedUserVisible() && $this->getUserLimitations())
455  {
456  $unlimited = "ud.time_limit_unlimited = ". $ilDB->quote(1, 'integer');
457  $from = "ud.time_limit_from < ". $ilDB->quote(time(), 'integer');
458  $until = "ud.time_limit_until > ". $ilDB->quote(time(), 'integer');
459 
460  $outer_conditions[] = '(' .$unlimited.' OR ('.$from.' AND ' .$until.'))';
461  }
462 
463  return implode(' AND ', $outer_conditions);
464  }
465 
469  protected function getOrderByPart()
470  {
471  return 'login ASC';
472  }
473 
479  protected function getQueryConditionByFieldAndValue($field, $a_str)
480  {
484  global $ilDB;
485 
486  // #14768
487  if(!stristr($a_str, '\\'))
488  {
489  $a_str = str_replace('%', '\%', $a_str);
490  $a_str = str_replace('_', '\_', $a_str);
491  }
492 
493  if(self::SEARCH_TYPE_LIKE == $this->getSearchType())
494  {
495  return $ilDB->like($field, 'text', $a_str . '%');
496  }
497  else
498  {
499  return $ilDB->like($field, 'text', $a_str);
500  }
501  }
502 
508  public function setUserLimitations($a_limitations)
509  {
510  $this->user_limitations = (bool) $a_limitations;
511  }
512 
517  public function getUserLimitations()
518  {
520  }
521 
525  public function isMoreLinkAvailable()
526  {
528  }
529 
536  {
537  $this->more_link_available = $more_link_available;
538  }
539 
540 
541 }
isFieldSearchableCheckEnabled()
Searchable check enabled.
$result
setUserLimitations($a_limitations)
allow user limitations like inactive and access limitations
setMoreLinkAvailable($more_link_available)
IMPORTANT: remember to read request parameter &#39;fetchall&#39; to use this function.
static getInstance()
Singelton get instance.
Auto completion class for user lists.
getFields()
Get searchable fields.
static encode($mixed, $suppress_native=false)
enableUserAccessCheck($a_status)
Enable user access check.
getSearchFields()
get possible search fields
getUserLimitations()
allow user limitations like inactive and access limitations
setResultField($a_field)
Set result field.
isUserAccessCheckEnabled()
Check if user access check is enabled.
enableFieldSearchableCheck($a_status)
Enable the check whether the field is searchable in Administration -> Settings -> Standard Fields...
__construct()
Default constructor.
global $ilSetting
Definition: privfeed.php:40
static getInstance()
Singelton get instance.
global $ilDB
setSearchFields($a_fields)
Set searchable fields.
$GLOBALS['PHPCAS_CLIENT']
This global variable is used by the interface class phpCAS.
Definition: CAS.php:276