' . "\n" .
'
\n
\n";
$output .= '';
$output .= '';
$output .= '';
// And the search options.
$optionsoutput = false;
if (!user_selector_base::$searchoptionsoutput) {
$output .= print_collapsible_region_start('', 'userselector_options',
get_string('searchoptions'), 'userselector_optionscollapsed', true, true);
$output .= $this->option_checkbox('preserveselected', $this->preserveselected,
get_string('userselectorpreserveselected'));
$output .= $this->option_checkbox('autoselectunique', $this->autoselectunique,
get_string('userselectorautoselectunique'));
$output .= $this->option_checkbox('searchanywhere', $this->searchanywhere,
get_string('userselectorsearchanywhere'));
$output .= print_collapsible_region_end(true);
$PAGE->requires->js_init_call('M.core_user.init_user_selector_options_tracker', array(), false, self::$jsmodule);
user_selector_base::$searchoptionsoutput = true;
}
$output .= "
\n
\n\n";
// Initialise the ajax functionality.
$output .= $this->initialise_javascript($search);
// Return or output it.
if ($return) {
return $output;
} else {
echo $output;
}
}
/**
* The height this control will be displayed, in rows.
*
* @param integer $numrows the desired height.
*/
public function set_rows($numrows) {
$this->rows = $numrows;
}
/**
* Returns the number of rows to display in this control.
*
* @return integer the height this control will be displayed, in rows.
*/
public function get_rows() {
return $this->rows;
}
/**
* Whether this control will allow selection of many, or just one user.
*
* @param boolean $multiselect true = allow multiple selection.
*/
public function set_multiselect($multiselect) {
$this->multiselect = $multiselect;
}
/**
* Returns true is multiselect should be allowed.
*
* @return boolean whether this control will allow selection of more than one user.
*/
public function is_multiselect() {
return $this->multiselect;
}
/**
* Returns the id/name of this control.
*
* @return string the id/name that this control will have in the HTML.
*/
public function get_name() {
return $this->name;
}
/**
* Set the user fields that are displayed in the selector in addition to the user's name.
*
* @param array $fields a list of field names that exist in the user table.
*/
public function set_extra_fields($fields) {
$this->extrafields = $fields;
}
/**
* Search the database for users matching the $search string, and any other
* conditions that apply. The SQL for testing whether a user matches the
* search string should be obtained by calling the search_sql method.
*
* This method is used both when getting the list of choices to display to
* the user, and also when validating a list of users that was selected.
*
* When preparing a list of users to choose from ($this->is_validating()
* return false) you should probably have an maximum number of users you will
* return, and if more users than this match your search, you should instead
* return a message generated by the too_many_results() method. However, you
* should not do this when validating.
*
* If you are writing a new user_selector subclass, I strongly recommend you
* look at some of the subclasses later in this file and in admin/roles/lib.php.
* They should help you see exactly what you have to do.
*
* @param string $search the search string.
* @return array An array of arrays of users. The array keys of the outer
* array should be the string names of optgroups. The keys of the inner
* arrays should be userids, and the values should be user objects
* containing at least the list of fields returned by the method
* required_fields_sql(). If a user object has a ->disabled property
* that is true, then that option will be displayed greyed out, and
* will not be returned by get_selected_users.
*/
public abstract function find_users($search);
/**
*
* Note: this function must be implemented if you use the search ajax field
* (e.g. set $options['file'] = '/admin/filecontainingyourclass.php';)
* @return array the options needed to recreate this user_selector.
*/
protected function get_options() {
return array(
'class' => get_class($this),
'name' => $this->name,
'exclude' => $this->exclude,
'extrafields' => $this->extrafields,
'multiselect' => $this->multiselect,
'accesscontext' => $this->accesscontext,
);
}
/**
* Returns true if this control is validating a list of users.
*
* @return boolean if true, we are validating a list of selected users,
* rather than preparing a list of uesrs to choose from.
*/
protected function is_validating() {
return !is_null($this->validatinguserids);
}
/**
* Get the list of users that were selected by doing optional_param then validating the result.
*
* @return array of user objects.
*/
protected function load_selected_users() {
// See if we got anything.
if ($this->multiselect) {
$userids = optional_param_array($this->name, array(), PARAM_INT);
} else if ($userid = optional_param($this->name, 0, PARAM_INT)) {
$userids = array($userid);
}
// If there are no users there is nobody to load.
if (empty($userids)) {
return array();
}
// If we did, use the find_users method to validate the ids.
$this->validatinguserids = $userids;
$groupedusers = $this->find_users('');
$this->validatinguserids = null;
// Aggregate the resulting list back into a single one.
$users = array();
foreach ($groupedusers as $group) {
foreach ($group as $user) {
if (!isset($users[$user->id]) && empty($user->disabled) && in_array($user->id, $userids)) {
$users[$user->id] = $user;
}
}
}
// If we are only supposed to be selecting a single user, make sure we do.
if (!$this->multiselect && count($users) > 1) {
$users = array_slice($users, 0, 1);
}
return $users;
}
/**
* Returns SQL to select required fields.
*
* @param string $u the table alias for the user table in the query being
* built. May be ''.
* @return string fragment of SQL to go in the select list of the query.
*/
protected function required_fields_sql($u) {
// Raw list of fields.
$fields = array('id');
// Add additional name fields.
$fields = array_merge($fields, get_all_user_name_fields(), $this->extrafields);
// Prepend the table alias.
if ($u) {
foreach ($fields as &$field) {
$field = $u . '.' . $field;
}
}
return implode(',', $fields);
}
/**
* Returns an array with SQL to perform a search and the params that go into it.
*
* @param string $search the text to search for.
* @param string $u the table alias for the user table in the query being
* built. May be ''.
* @return array an array with two elements, a fragment of SQL to go in the
* where clause the query, and an array containing any required parameters.
* this uses ? style placeholders.
*/
protected function search_sql($search, $u) {
return users_search_sql($search, $u, $this->searchanywhere, $this->extrafields,
$this->exclude, $this->validatinguserids);
}
/**
* Used to generate a nice message when there are too many users to show.
*
* The message includes the number of users that currently match, and the
* text of the message depends on whether the search term is non-blank.
*
* @param string $search the search term, as passed in to the find users method.
* @param int $count the number of users that currently match.
* @return array in the right format to return from the find_users method.
*/
protected function too_many_results($search, $count) {
if ($search) {
$a = new stdClass;
$a->count = $count;
$a->search = $search;
return array(get_string('toomanyusersmatchsearch', '', $a) => array(),
get_string('pleasesearchmore') => array());
} else {
return array(get_string('toomanyuserstoshow', '', $count) => array(),
get_string('pleaseusesearch') => array());
}
}
/**
* Output the list of