Example #1
0
/**
 * The CSV file is parsed here so validation errors can be returned to the
 * user. The data from a successful parsing is stored in the <var>$CVSDATA</var>
 * array so it can be accessed by the submit function
 *
 * @param Pieform  $form   The form to validate
 * @param array    $values The values submitted
 */
function uploadcsv_validate(Pieform $form, $values)
{
    global $CSVDATA, $ALLOWEDKEYS, $MANDATORYFIELDS, $FORMAT, $USER, $UPDATES, $MEMBERS, $GROUPS;
    // Don't even start attempting to parse if there are previous errors
    if ($form->has_errors()) {
        return;
    }
    if ($values['file']['size'] == 0) {
        $form->set_error('file', $form->i18n('rule', 'required', 'required', array()));
        return;
    }
    $institution = $values['institution'];
    if (!$USER->can_edit_institution($institution)) {
        $form->set_error('institution', get_string('notadminforinstitution', 'admin'));
        return;
    }
    require_once 'csvfile.php';
    $csvgroups = new CsvFile($values['file']['tmp_name']);
    $csvgroups->set('allowedkeys', $ALLOWEDKEYS);
    $csvgroups->set('mandatoryfields', $MANDATORYFIELDS);
    $csvdata = $csvgroups->get_data();
    if (!empty($csvdata->errors['file'])) {
        $form->set_error('file', $csvdata->errors['file']);
        return;
    }
    $csverrors = new CSVErrors();
    $formatkeylookup = array_flip($csvdata->format);
    $shortnames = array();
    $hadadmin = array();
    $num_lines = count($csvdata->data);
    foreach ($csvdata->data as $key => $line) {
        // If headers exists, increment i = key + 2 for actual line number
        $i = $csvgroups->get('headerExists') ? $key + 2 : $key + 1;
        // In adding 5000 groups, this part was approx 8% of the wall time.
        if (!($key % 25)) {
            set_progress_info('uploadgroupmemberscsv', $key, $num_lines * 10, get_string('validating', 'admin'));
        }
        // Trim non-breaking spaces -- they get left in place by File_CSV
        foreach ($line as &$field) {
            $field = preg_replace('/^(\\s|\\xc2\\xa0)*(.*?)(\\s|\\xc2\\xa0)*$/', '$2', $field);
        }
        $shortname = $line[$formatkeylookup['shortname']];
        $username = $line[$formatkeylookup['username']];
        $role = $line[$formatkeylookup['role']];
        $gid = get_field('group', 'id', 'shortname', $shortname, 'institution', $institution);
        if (!$gid) {
            $csverrors->add($i, get_string('uploadgroupmemberscsverrornosuchshortname', 'admin', $i, $shortname, $institution));
            continue;
        }
        $uid = get_field_sql('SELECT id FROM {usr} WHERE LOWER(username) = ?', array(strtolower($username)));
        if (!$uid) {
            $csverrors->add($i, get_string('uploadgroupmemberscsverrornosuchusername', 'admin', $i, $username));
            continue;
        }
        if ($institution != 'mahara' && !record_exists('usr_institution', 'usr', $uid, 'institution', $institution)) {
            $csverrors->add($i, get_string('uploadgroupmemberscsverrorusernotininstitution', 'admin', $i, $username, $institution));
            continue;
        }
        if (!in_array($role, array_keys(group_get_role_info($gid)))) {
            $csverrors->add($i, get_string('uploadgroupmemberscsverrorinvalidrole', 'admin', $i, $role));
            continue;
        }
        if (!isset($MEMBERS[$gid])) {
            $MEMBERS[$gid] = array();
        }
        if (isset($MEMBERS[$gid][$uid])) {
            $csverrors->add($i, get_string('uploadgroupmemberscsverrorduplicateusername', 'admin', $i, $shortname, $username));
            continue;
        }
        $MEMBERS[$gid][$uid] = $role;
        $GROUPS[$gid] = $shortname;
        if ($role == 'admin') {
            $hasadmin[$shortname] = 1;
        }
    }
    foreach ($GROUPS as $shortname) {
        if (!isset($hasadmin[$shortname])) {
            $csverrors->add($i, get_string('uploadgroupmemberscsverrornoadminlisted', 'admin', $i, $shortname));
        }
    }
    if ($errors = $csverrors->process()) {
        $form->set_error('file', clean_html($errors));
        return;
    }
    $FORMAT = $csvdata->format;
    $CSVDATA = $csvdata->data;
}
Example #2
0
/**
 * Add the users to the system.
 */
function bulkimport_submit(Pieform $form, $values)
{
    global $SESSION, $LEAP2AFILES;
    require_once 'file.php';
    require_once get_config('docroot') . 'import/lib.php';
    safe_require('import', 'leap');
    $key = 0;
    $total = count($LEAP2AFILES);
    log_info('Attempting to import ' . $total . ' users from Leap2A files');
    foreach ($LEAP2AFILES as $username => $filename) {
        if (!($key % 10)) {
            set_progress_info('bulkimport', $key, $total, get_string('importing', 'admin'));
        }
        $key++;
        import_next_user($filename, $username, $values['authinstance']);
    }
    finish_import();
}
Example #3
0
/**
 * Add the users to the system. Make sure that they have to change their
 * password on next login also.
 */
function uploadcsv_submit(Pieform $form, $values)
{
    global $USER, $SESSION, $CSVDATA, $FORMAT, $UPDATES;
    $formatkeylookup = array_flip($FORMAT);
    $authinstance = (int) $values['authinstance'];
    $authrecord = get_record('auth_instance', 'id', $authinstance);
    $authobj = AuthFactory::create($authinstance);
    $institution = new Institution($authobj->institution);
    $maxusers = $institution->maxuseraccounts;
    if (!empty($maxusers)) {
        $members = count_records_sql('
            SELECT COUNT(*) FROM {usr} u INNER JOIN {usr_institution} i ON u.id = i.usr
            WHERE i.institution = ? AND u.deleted = 0', array($institution->name));
        if ($members + count($CSVDATA) > $maxusers) {
            $SESSION->add_error_msg(get_string('uploadcsvfailedusersexceedmaxallowed', 'admin'));
            redirect('/admin/users/uploadcsv.php');
        }
    }
    if ($values['updateusers']) {
        log_info('Updating users from the CSV file');
    } else {
        log_info('Inserting users from the CSV file');
    }
    db_begin();
    $addedusers = array();
    $cfgsendemail = get_config('sendemail');
    if (empty($values['emailusers'])) {
        // Temporarily disable email sent during user creation, e.g. institution membership
        $GLOBALS['CFG']->sendemail = false;
    }
    $key = 0;
    $steps_total = $values['updateusers'] ? 5 : 4;
    $steps_done = $steps_total - 3;
    $num_lines = sizeof($CSVDATA);
    foreach ($CSVDATA as $record) {
        if (!($key % 25)) {
            // This part has three times the weight of the other two steps.
            set_progress_info('uploaduserscsv', $num_lines * $steps_done + $key * 3, $num_lines * $steps_total, get_string('committingchanges', 'admin'));
        }
        $key++;
        $user = new StdClass();
        foreach ($FORMAT as $field) {
            if ($field == 'username' || $field == 'firstname' || $field == 'lastname' || $field == 'password' || $field == 'email' || $field == 'studentid' || $field == 'preferredname') {
                $user->{$field} = $record[$formatkeylookup[$field]];
            }
        }
        $user->authinstance = $authinstance;
        if ($USER->get('admin') || get_config_plugin('artefact', 'file', 'institutionaloverride')) {
            $user->quota = $values['quota'];
        }
        $profilefields = new StdClass();
        $remoteuser = null;
        foreach ($FORMAT as $field) {
            if ($field == 'username' || $field == 'password') {
                continue;
            }
            if ($field == 'remoteuser') {
                if (!empty($record[$formatkeylookup[$field]])) {
                    $remoteuser = $record[$formatkeylookup[$field]];
                }
                continue;
            }
            $profilefields->{$field} = $record[$formatkeylookup[$field]];
        }
        if (!$values['updateusers'] || !isset($UPDATES[$user->username])) {
            $user->passwordchange = (int) $values['forcepasswordchange'];
            $user->id = create_user($user, $profilefields, $institution, $authrecord, $remoteuser, $values, true);
            $addedusers[] = $user;
            log_debug('added user ' . $user->username);
        } else {
            if (isset($UPDATES[$user->username])) {
                $updated = update_user($user, $profilefields, $remoteuser, $values, true, true);
                if (empty($updated)) {
                    // Nothing changed for this user
                    unset($UPDATES[$user->username]);
                } else {
                    $UPDATES[$user->username] = $updated;
                    log_debug('updated user ' . $user->username . ' (' . implode(', ', array_keys($updated)) . ')');
                }
            }
        }
        set_time_limit(10);
    }
    db_commit();
    // Reenable email
    set_config('sendemail', $cfgsendemail);
    // Only send e-mail to users after we're sure they have been inserted
    // successfully
    $straccountcreatedtext = $values['forcepasswordchange'] ? 'accountcreatedchangepasswordtext' : 'accountcreatedtext';
    $straccountcreatedhtml = $values['forcepasswordchange'] ? 'accountcreatedchangepasswordhtml' : 'accountcreatedhtml';
    if ($values['emailusers'] && $addedusers) {
        foreach ($addedusers as $user) {
            $failedusers = array();
            try {
                email_user($user, null, get_string('accountcreated', 'mahara', get_config('sitename')), get_string($straccountcreatedtext, 'mahara', $user->firstname, get_config('sitename'), $user->username, $user->password, get_config('wwwroot'), get_config('sitename')), get_string($straccountcreatedhtml, 'mahara', $user->firstname, get_config('wwwroot'), get_config('sitename'), $user->username, $user->password, get_config('wwwroot'), get_config('wwwroot'), get_config('sitename')));
            } catch (EmailException $e) {
                log_info($e->getMessage());
                $failedusers[] = $user;
            }
        }
        if ($failedusers) {
            $message = get_string('uploadcsvsomeuserscouldnotbeemailed', 'admin') . "\n<ul>\n";
            foreach ($failedusers as $user) {
                $message .= '<li>' . full_name($user) . ' &lt;' . hsc($user->email) . "&gt;</li>\n";
            }
            $message .= "</ul>\n";
            $SESSION->add_info_msg($message, false);
        }
    }
    log_info('Added ' . count($addedusers) . ' users, updated ' . count($UPDATES) . ' users.');
    $SESSION->add_ok_msg(get_string('csvfileprocessedsuccessfully', 'admin'));
    if ($UPDATES) {
        $updatemsg = smarty_core();
        $updatemsg->assign('added', count($addedusers));
        $updatemsg->assign('updates', $UPDATES);
        $SESSION->add_info_msg($updatemsg->fetch('admin/users/csvupdatemessage.tpl'), false);
    } else {
        $SESSION->add_ok_msg(get_string('numbernewusersadded', 'admin', count($addedusers)));
    }
    set_progress_done('uploaduserscsv');
    redirect('/admin/users/uploadcsv.php');
}
Example #4
0
/**
 * Completely update the membership of a group
 *
 * @param int $groupid ID of group
 * @param array $members list of members and roles, structured like this:
 *            array(
 *                userid => role,
 *                userid => role,
 *                ...
 *            )
 * @param lines_done Number of lines in the file that have been completed so far
 * @param num_lines Number of lines in the file (this and the previous values
 *  are used to update the progress meter.
 */
function group_update_members($groupid, $members, $lines_done = 0, $num_lines = 0)
{
    global $USER;
    $groupid = group_param_groupid($groupid);
    if (!($group = get_record('group', 'id', $groupid, 'deleted', 0))) {
        throw new NotFoundException("group_update_members: group not found: {$groupid}");
    }
    if ($group->institution && !$USER->can_edit_institution($group->institution) || !$group->institution && !$USER->get('admin')) {
        throw new AccessDeniedException("group_update_members: access denied");
    }
    if (!is_array($members)) {
        throw new SystemException("group_update_members: members must be an array");
    }
    $badroles = array_unique(array_diff($members, array_keys(group_get_role_info($groupid))));
    if (!empty($badroles)) {
        throw new UserException("group_update_members: invalid role(s) specified for group {$group->name} (id {$groupid}): " . join(', ', $badroles));
    }
    if (!in_array('admin', $members)) {
        $groupname = get_field('group', 'name', 'id', $groupid);
        throw new UserException("group_update_members: no group admins listed for group {$group->name} (id {$groupid})");
    }
    // Check the new members list for invalid users
    if (!empty($members)) {
        $userids = array_map('intval', array_keys($members));
        if ($group->institution && $group->institution != 'mahara') {
            $gooduserids = get_column_sql('
                SELECT usr
                FROM {usr_institution}
                WHERE usr IN (' . join(',', $userids) . ') AND institution = ?', array($group->institution));
            if ($baduserids = array_diff($userids, $gooduserids)) {
                if (!(count($baduserids) == 1 && $baduserids[0] == $USER->id)) {
                    throw new UserException("group_update_members: some members are not in the institution {$group->institution}: " . join(',', $baduserids));
                }
            }
        } else {
            $gooduserids = get_column_sql('
                SELECT id FROM {usr} WHERE id IN (' . join(',', $userids) . ') AND deleted = 0', array());
            if ($baduserids = array_diff($userids, $gooduserids)) {
                throw new UserException("group_update_members: some new members do not exist: " . join(',', $baduserids));
            }
        }
    }
    // Update group members
    $oldmembers = get_records_assoc('group_member', 'group', $groupid, '', 'member,role');
    $added = 0;
    $removed = 0;
    $updated = 0;
    $to_add = count(array_diff_key($members, $oldmembers));
    $to_remove = count(array_diff_key($oldmembers, $members));
    $to_update = count($members) - $to_add;
    db_begin();
    foreach ($members as $userid => $role) {
        if (!isset($oldmembers[$userid])) {
            group_add_user($groupid, $userid, $role);
            $added++;
            if (!(($lines_done + $added) % 25)) {
                set_progress_info('uploadgroupmemberscsv', $num_lines + 9 * ($lines_done + count($members) * $added / ($to_add + $to_remove)), $num_lines * 10, get_string('committingchanges', 'admin'));
            }
        } else {
            if ($oldmembers[$userid]->role != $role) {
                set_field('group_member', 'role', $role, 'group', $groupid, 'member', $userid);
                $updated++;
            }
        }
    }
    foreach (array_keys($oldmembers) as $userid) {
        if (!isset($members[$userid])) {
            group_remove_user($groupid, $userid, true);
            $removed++;
            if (!(($lines_done + $added + $removed) % 25)) {
                set_progress_info('uploadgroupmemberscsv', $num_lines + 9 * ($lines_done + count($members) * ($added + $removed) / ($to_add + $to_remove)), $num_lines * 10, get_string('committingchanges', 'admin'));
            }
        }
    }
    db_commit();
    if ($added == 0 && $removed == 0 && $updated == 0) {
        return null;
    }
    return array('added' => $added, 'removed' => $removed, 'updated' => $updated);
}
Example #5
0
/**
 * Add the users to the system. Make sure that they have to change their
 * password on next login also.
 */
function uploadcsv_submit(Pieform $form, $values)
{
    global $SESSION, $CSVDATA, $FORMAT, $UPDATES, $USER;
    $formatkeylookup = array_flip($FORMAT);
    $institution = $values['institution'];
    if ($values['updategroups']) {
        log_info('Updating groups from the CSV file');
    } else {
        log_info('Inserting groups from the CSV file');
    }
    db_begin();
    $addedgroups = array();
    $key = 0;
    $num_lines = count($CSVDATA);
    foreach ($CSVDATA as $record) {
        if (!($key % 25)) {
            set_progress_info('uploadgroupscsv', $num_lines + $key * 9, $num_lines * 10, get_string('committingchanges', 'admin'));
        }
        $key++;
        $group = new StdClass();
        $group->name = $record[$formatkeylookup['displayname']];
        $group->shortname = $record[$formatkeylookup['shortname']];
        $group->institution = $institution;
        $group->grouptype = $record[$formatkeylookup['roles']];
        foreach ($FORMAT as $field) {
            if ($field == 'displayname' || $field == 'shortname' || $field == 'roles') {
                continue;
            }
            if ($field == 'submitpages') {
                $group->submittableto = $record[$formatkeylookup[$field]];
                continue;
            }
            $group->{$field} = $record[$formatkeylookup[$field]];
        }
        if (!$values['updategroups'] || !isset($UPDATES[$group->shortname])) {
            $group->members = array($USER->id => 'admin');
            $group->id = group_create((array) $group);
            $addedgroups[] = $group;
            log_debug('added group ' . $group->name);
        } else {
            if (isset($UPDATES[$group->shortname])) {
                $shortname = $group->shortname;
                $updates = group_update($group);
                if (empty($updates)) {
                    unset($UPDATES[$shortname]);
                } else {
                    if (isset($updates['name'])) {
                        $updates['displayname'] = $updates['name'];
                        unset($updates['name']);
                    }
                    $UPDATES[$shortname] = $updates;
                    log_debug('updated group ' . $group->name . ' (' . implode(', ', array_keys((array) $updates)) . ')');
                }
            }
        }
    }
    db_commit();
    $SESSION->add_ok_msg(get_string('csvfileprocessedsuccessfully', 'admin'));
    if ($UPDATES) {
        $updatemsg = smarty_core();
        $updatemsg->assign('added', count($addedgroups));
        $updatemsg->assign('updates', $UPDATES);
        $SESSION->add_info_msg($updatemsg->fetch('admin/groups/csvupdatemessage.tpl'), false);
    } else {
        $SESSION->add_ok_msg(get_string('numbernewgroupsadded', 'admin', count($addedgroups)));
    }
    set_progress_done('uploadgroupscsv');
    redirect('/admin/groups/uploadcsv.php');
}
Example #6
0
function bulkexport_submit(Pieform $form, $values)
{
    global $SESSION;
    $usernames = array();
    // Read in the usernames explicitly specified
    foreach (explode("\n", $values['usernames']) as $username) {
        $username = trim($username);
        if (!empty($username)) {
            $usernames[] = $username;
        }
    }
    if (empty($usernames) and !empty($values['authinstance'])) {
        // Export all users from the selected institution
        $rs = get_recordset_select('usr', 'authinstance = ? AND deleted = 0', array($values['authinstance']), '', 'username');
        while ($record = $rs->FetchRow()) {
            $usernames[] = $record['username'];
        }
    }
    safe_require('export', 'leap');
    $listing = array();
    $files = array();
    $exportcount = 0;
    $exporterrors = array();
    $num_users = count($usernames);
    foreach ($usernames as $username) {
        if (!($exportcount % 25)) {
            set_progress_info('bulkexport', $exportcount, $num_users, get_string('validating', 'admin'));
        }
        $user = new User();
        try {
            $user->find_by_username($username);
        } catch (AuthUnknownUserException $e) {
            continue;
            // Skip non-existent users
        }
        $exporter = new PluginExportLeap($user, PluginExport::EXPORT_ALL_VIEWS_COLLECTIONS, PluginExport::EXPORT_ALL_ARTEFACTS);
        try {
            $zipfile = $exporter->export();
        } catch (Exception $e) {
            $exporterrors[] = $username;
            continue;
        }
        $listing[] = array($username, $zipfile);
        $files[] = $exporter->get('exportdir') . $zipfile;
        $exportcount++;
    }
    if (!($zipfile = create_zipfile($listing, $files))) {
        export_iframe_die(get_string('bulkexportempty', 'admin'));
    }
    log_info("Exported {$exportcount} users to {$zipfile}");
    if (!empty($exporterrors)) {
        $SESSION->add_error_msg(get_string('couldnotexportusers', 'admin', implode(', ', $exporterrors)));
    }
    // Store the filename in the session, and redirect the iframe to it to trigger
    // the download. Here it would be nice to trigger the download for everyone,
    // but alas this is not possible for people without javascript.
    $SESSION->set('exportfile', $zipfile);
    set_progress_done('bulkexport', array('redirect' => get_config('wwwroot') . 'admin/users/bulkexport.php'));
    // Download the export file once it has been generated
    require_once 'file.php';
    serve_file($zipfile, basename($zipfile), 'application/x-zip', array('lifetime' => 0, 'forcedownload' => true));
    // TODO: delete the zipfile (and temporary files) once it's been downloaded
}