Commit 0c6d05d2 authored by Robert Lyon's avatar Robert Lyon
Browse files

Bug 1597133: Adding institutions to groups that don't have them



And adding an institution selection to the Admin -> Group search

Also making sure that we can retain supplied shortname or throw error
if there is a clash

behatnotneeded

Change-Id: Ibbd6c05c1428e522c048b10c64389ebe3360473a
Signed-off-by: Robert Lyon's avatarRobert Lyon <robertl@catalyst.net.nz>
parent 97bf0689
......@@ -22,8 +22,9 @@ require_once('searchlib.php');
$query = param_variable('query', '');
$offset = param_integer('offset', 0);
$limit = param_integer('limit', 10);
$institution = param_alphanum('institution', 'all');
$data = build_grouplist_html($query, $limit, $offset, $count);
$data = build_grouplist_html($query, $limit, $offset, $count, $institution);
$data['count'] = $count;
$data['offset'] = $offset;
$data['query'] = $query;
......
......@@ -24,36 +24,52 @@ $query = param_variable('query', '');
$offset = param_integer('offset', 0);
$limit = param_integer('limit', 0);
$limit = user_preferred_limit($limit, 'itemsperpage');
$institution = param_alphanum('institution', null);
$data = build_grouplist_html($query, $limit, $offset);
// Build the institution select field that sits behind the search field
$inst_select = array();
$institution = !$institution ? 'all' : $institution;
$institutions = get_records_array('institution', '', '', 'displayname');
$inst_select['all'] = get_string('Allinstitutions');
if (is_array($institutions)) {
foreach ($institutions as $inst) {
$inst_select[$inst->name] = $inst->displayname;
}
}
$count = 0;
$data = build_grouplist_html($query, $limit, $offset, $count, $institution);
$searchform = pieform(array(
'name' => 'search',
'renderer' => 'div',
'class' => 'form-inline with-heading',
'class' => 'form-inline with-heading dropdown admin-user-search',
'autofocus' => false,
'elements' => array(
'inputgroup' => array(
'type' => 'fieldset',
'title' => get_string('Query') . ': ',
'class' => 'input-group form-inline',
'class' => 'dropdown-group js-dropdown-group',
'elements' => array(
'query' => array(
'type' => 'text',
'defaultvalue' => $query,
'hiddenlabel' => true,
'value' => get_string('search'),
'class' => 'emptyonfocus',
'title' => get_string('search'),
'class' => 'with-dropdown js-with-dropdown',
'title' => get_string('search') . ': ',
),
'institution' => array(
'type' => 'select',
'title' => get_string('Institution', 'admin'),
'defaultvalue' => $institution,
'options' => $inst_select,
'class' => 'dropdown-connect js-dropdown-connect',
),
'submit' => array(
'type' => 'button',
'usebuttontag' => true,
'class' => 'btn-primary input-group-btn',
'value' => get_string('search'),
)
),
),
'submit' => array(
'type' => 'button',
'usebuttontag' => true,
'class' => 'btn-search btn btn-primary admin-groups',
'value' => get_string('search'),
)
),
));
......@@ -62,7 +78,8 @@ addLoadEvent(function () {
p = {$data['pagination_js']}
connect('search_submit', 'onclick', function (event) {
replaceChildNodes('messages');
var params = {'query': $('search_query').value};
var params = {'query': $('search_query').value,
'institution': $('search_institution').value};
p.sendQuery(params);
event.stop();
});
......@@ -78,5 +95,8 @@ $smarty->assign('results', $data);
$smarty->display('admin/groups/groups.tpl');
function search_submit(Pieform $form, $values) {
redirect(get_config('wwwroot') . 'admin/groups/groups.php' . ((isset($values['query']) && ($values['query'] != '')) ? '?query=' . urlencode($values['query']) : ''));
$search = (isset($values['query']) && $values['query'] != '') ? 'query=' . urlencode($values['query']) : null;
$institution = (isset($values['institution']) && $values['institution'] != '') ? urlencode($values['institution']) : null;
$query = '?search=1&query=' . $search . '&institution=' . $institution;
redirect(get_config('wwwroot') . 'admin/groups/groups.php' . $query);
}
......@@ -306,6 +306,7 @@ function uploadcsv_submit(Pieform $form, $values) {
if (!$values['updategroups'] || !isset($UPDATES[$group->shortname])) {
$group->members = array($USER->id => 'admin');
$group->retainshortname = true;
$group->id = group_create((array)$group);
$addedgroups[] = $group;
......
......@@ -4484,7 +4484,7 @@ function xmldb_core_upgrade($oldversion=0) {
}
if ($oldversion < 2016062200) {
include_once(get_config('docroot') . 'lib/group.php');
require_once(get_config('docroot') . 'lib/group.php');
log_debug('Assign a unique shortname for each existing group that doesn\'t have one.');
$groups = get_records_select_array(
......@@ -4500,5 +4500,11 @@ function xmldb_core_upgrade($oldversion=0) {
}
}
if ($oldversion < 2016062900) {
log_debug('Assign an istitution for each existing group that doesn\'t have one.');
$groups = execute_sql("UPDATE {group} SET institution = 'mahara'
WHERE (institution IS NULL OR institution = '') AND deleted = 0", array());
}
return $status;
}
......@@ -354,39 +354,30 @@ function group_create($data) {
$data['invitefriends'] = (isset($data['invitefriends'])) ? intval($data['invitefriends']) : 0;
$data['suggestfriends'] = (isset($data['suggestfriends'])) ? intval($data['suggestfriends']) : 0;
if (isset($data['shortname']) && strlen($data['shortname'])) {
// This is a group whose details and membership can be updated automatically, using a
// webservice api or possibly csv upload.
// On updates to this group, it will be identified using the institution and shortname
// which must be unique.
if (!empty($data['shortname'])) {
// make sure it is unique and is correct length
$shortname = group_generate_shortname($data['shortname']);
// If we want to retain the supplied shortname we need to make sure it can be done
if (!empty($data['retainshortname'])) {
if ($shortname != $data['shortname']) {
throw new UserException('group_create: problem with supplied shortname ' . $data['shortname'] . ' not matching allowed shortname ' . $shortname);
}
}
$data['shortname'] = $shortname;
}
else {
// Create it from group name
$data['shortname'] = group_generate_shortname($data['name']);
}
// The $USER object will be set to someone with at least institutional admin permission.
if (!empty($data['institution']) && $data['institution'] != 'mahara') {
global $USER;
if (empty($data['institution'])) {
throw new SystemException("group_create: a group with a shortname must have an institution; shortname: " . $data['shortname']);
}
if (!$USER->can_edit_institution($data['institution'])) {
throw new AccessDeniedException("group_create: cannot create a group in this institution");
}
if (!preg_match('/^[a-zA-Z0-9_.-]{2,255}$/', $data['shortname'])) {
$message = get_string('invalidshortname', 'group') . ': ' . $data['shortname'];
$message .= "\n" . get_string('shortnameformat', 'group');
throw new UserException($message);
}
if (record_exists('group', 'shortname', $data['shortname'], 'institution', $data['institution'])) {
throw new UserException('group_create: group with shortname ' . $data['shortname'] . ' and institution ' . $data['institution'] . ' already exists');
}
if (empty($data['members'])) {
$data['members'] = array($USER->get('id') => 'admin');
}
}
else {
if (!empty($data['institution'])) {
throw new SystemException("group_create: group institution only available for api-controlled groups");
}
$data['shortname'] = group_generate_shortname($data['name']);
$data['institution'] = 'mahara';
}
if (get_config('cleanurls') && (!isset($data['urlid']) || strlen($data['urlid']) == 0)) {
......@@ -394,8 +385,9 @@ function group_create($data) {
$data['urlid'] = group_get_new_homepage_urlid($data['urlid']);
}
if (!is_array($data['members']) || count($data['members']) == 0) {
throw new InvalidArgumentException("group_create: at least one member must be specified for adding to the group");
// Need to make sure group has at least one member
if (empty($data['members'])) {
$data['members'] = array($USER->get('id') => 'admin');
}
if (!isset($data['submittableto'])) {
......@@ -1599,9 +1591,9 @@ function group_format_editwindow($group) {
/*
* Used by admin/groups/groups.php and admin/groups/groups.json.php for listing groups.
*/
function build_grouplist_html($query, $limit, $offset, &$count=null) {
function build_grouplist_html($query, $limit, $offset, &$count=null, $institution) {
$groups = search_group($query, $limit, $offset, 'all');
$groups = search_group($query, $limit, $offset, 'all', '', $institution);
$count = $groups['count'];
if ($ids = array_map(create_function('$a', 'return intval($a->id);'), $groups['data'])) {
......
......@@ -1171,7 +1171,7 @@ EOF;
* @return string The attributes for the element
*/
public function element_attributes($element, $exclude=array()) {/*{{{*/
static $attributes = array('accesskey', 'autocomplete', 'class', 'dir', 'data-confirm', 'id', 'lang', 'name', 'onclick', 'size', 'style', 'tabindex');
static $attributes = array('accesskey', 'autocomplete', 'class', 'dir', 'data-confirm', 'id', 'lang', 'name', 'onclick', 'placeholder', 'size', 'style', 'tabindex');
$elementattributes = array_diff($attributes, $exclude);
$result = '';
foreach ($elementattributes as $attribute) {
......
......@@ -946,6 +946,8 @@ function get_group_user_search_results($group, $query, $offset, $limit, $members
* @param string The query string
* @param integer How many results to return
* @param integer What result to start at (0 == first result)
* @param string Category the group belongs to
* @param string The institution the group belongs
* @return array A data structure containing results looking like ...
* $results = array(
* count => integer, // total number of results
......@@ -972,11 +974,11 @@ function get_group_user_search_results($group, $query, $offset, $limit, $members
* ),
* );
*/
function search_group($query_string, $limit, $offset = 0, $type = 'member', $groupcategory = '') {
function search_group($query_string, $limit, $offset = 0, $type = 'member', $groupcategory = '', $institution='all') {
$plugin = get_config('searchplugin');
safe_require('search', $plugin);
return call_static_method(generate_class_name('search', $plugin), 'search_group', $query_string, $limit, $offset, $type, $groupcategory);
return call_static_method(generate_class_name('search', $plugin), 'search_group', $query_string, $limit, $offset, $type, $groupcategory, $institution);
}
function search_selfsearch($query_string, $limit, $offset, $type = 'all') {
......
......@@ -16,7 +16,7 @@ $config = new stdClass();
// See https://wiki.mahara.org/wiki/Developer_Area/Version_Numbering_Policy
// For upgrades on stable branches, increment the version by one. On master, use the date.
$config->version = 2016062200;
$config->version = 2016062900;
$config->series = '16.10';
$config->release = '16.10dev';
$config->minupgradefrom = 2012080604;
......
......@@ -881,10 +881,10 @@ class PluginSearchElasticsearch extends PluginSearch {
return PluginSearchInternal::search_user($query_string, $limit, $offset, $data);
}
public static function search_group($query_string, $limit, $offset=0, $type='member', $category='') {
public static function search_group($query_string, $limit, $offset=0, $type='member', $category='', $institution='all') {
// Given the results depends on the user the SQL search makes more sense here than Elastic Search
// So I'll just call the PluginSearchInternal related function
return PluginSearchInternal::search_group($query_string, $limit, $offset, $type, $category);
return PluginSearchInternal::search_group($query_string, $limit, $offset, $type, $category, $institution);
}
public static function self_search($query_string, $limit, $offset, $type = 'all') {
......
......@@ -782,6 +782,8 @@ class PluginSearchInternal extends PluginSearch {
* @param integer How many results to return
* @param integer What result to start at (0 == first result)
* @param string Which groups to search (all, member, notmember)
* @param string Category the group belongs to
* @param string The institution the group belongs
* @return array A data structure containing results looking like ...
* $results = array(
* count => integer, // total number of results
......@@ -810,7 +812,7 @@ class PluginSearchInternal extends PluginSearch {
* ),
* );
*/
public static function search_group($query_string, $limit, $offset=0, $type='member', $category='') {
public static function search_group($query_string, $limit, $offset=0, $type='member', $category='', $institution='all') {
global $USER;
$data = array();
......@@ -853,6 +855,10 @@ class PluginSearchInternal extends PluginSearch {
$values[] = $category;
}
}
if ($institution != 'all') {
$sql .= ' AND institution = ?';
$values[] = $institution;
}
$count = get_field_sql('SELECT COUNT(*) '.$sql, $values);
......
......@@ -60,6 +60,8 @@ interface IPluginSearch {
* @param integer How many results to return
* @param integer What result to start at (0 == first result)
* @param string Which groups to search (all, member, notmember)
* @param string Category the group belongs to
* @param string The institution the group belongs
* @return array A data structure containing results looking like ...
* $results = array(
* count => integer, // total number of results
......@@ -88,7 +90,7 @@ interface IPluginSearch {
* ),
* );
*/
public static function search_group($query_string, $limit, $offset=0, $type='member');
public static function search_group($query_string, $limit, $offset=0, $type='member', $category='', $institution='all');
/**
* Returns search results for users in a particular group
......
......@@ -432,3 +432,8 @@
#auth_config_institutionidp {
width: 90%;
}
.btn-search.btn.btn-primary.admin-groups.button.btn {
margin-left: -13px;
vertical-align: text-top;
}
......@@ -209,6 +209,7 @@ class mahara_group_external extends external_api {
}
// create the group
$create['retainshortname'] = true;
$id = group_create($create);
$groupids[] = array('id'=> $id, 'name'=> $group['name']);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment