|
Moodle
2.2.1
http://www.collinsharper.com
|
00001 <?php 00002 // This file is part of Moodle - http://moodle.org/ 00003 // 00004 // Moodle is free software: you can redistribute it and/or modify 00005 // it under the terms of the GNU General Public License as published by 00006 // the Free Software Foundation, either version 3 of the License, or 00007 // (at your option) any later version. 00008 // 00009 // Moodle is distributed in the hope that it will be useful, 00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 // GNU General Public License for more details. 00013 // 00014 // You should have received a copy of the GNU General Public License 00015 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 00016 00026 require('../../../config.php'); 00027 require_once($CFG->libdir.'/adminlib.php'); 00028 require_once($CFG->libdir.'/csvlib.class.php'); 00029 require_once($CFG->dirroot.'/user/profile/lib.php'); 00030 require_once($CFG->dirroot.'/group/lib.php'); 00031 require_once($CFG->dirroot.'/cohort/lib.php'); 00032 require_once('locallib.php'); 00033 require_once('user_form.php'); 00034 00035 $iid = optional_param('iid', '', PARAM_INT); 00036 $previewrows = optional_param('previewrows', 10, PARAM_INT); 00037 00038 @set_time_limit(60*60); // 1 hour should be enough 00039 raise_memory_limit(MEMORY_HUGE); 00040 00041 require_login(); 00042 admin_externalpage_setup('tooluploaduser'); 00043 require_capability('moodle/site:uploadusers', get_context_instance(CONTEXT_SYSTEM)); 00044 00045 $struserrenamed = get_string('userrenamed', 'tool_uploaduser'); 00046 $strusernotrenamedexists = get_string('usernotrenamedexists', 'error'); 00047 $strusernotrenamedmissing = get_string('usernotrenamedmissing', 'error'); 00048 $strusernotrenamedoff = get_string('usernotrenamedoff', 'error'); 00049 $strusernotrenamedadmin = get_string('usernotrenamedadmin', 'error'); 00050 00051 $struserupdated = get_string('useraccountupdated', 'tool_uploaduser'); 00052 $strusernotupdated = get_string('usernotupdatederror', 'error'); 00053 $strusernotupdatednotexists = get_string('usernotupdatednotexists', 'error'); 00054 $strusernotupdatedadmin = get_string('usernotupdatedadmin', 'error'); 00055 00056 $struseruptodate = get_string('useraccountuptodate', 'tool_uploaduser'); 00057 00058 $struseradded = get_string('newuser'); 00059 $strusernotadded = get_string('usernotaddedregistered', 'error'); 00060 $strusernotaddederror = get_string('usernotaddederror', 'error'); 00061 00062 $struserdeleted = get_string('userdeleted', 'tool_uploaduser'); 00063 $strusernotdeletederror = get_string('usernotdeletederror', 'error'); 00064 $strusernotdeletedmissing = get_string('usernotdeletedmissing', 'error'); 00065 $strusernotdeletedoff = get_string('usernotdeletedoff', 'error'); 00066 $strusernotdeletedadmin = get_string('usernotdeletedadmin', 'error'); 00067 00068 $strcannotassignrole = get_string('cannotassignrole', 'error'); 00069 00070 $struserauthunsupported = get_string('userauthunsupported', 'error'); 00071 $stremailduplicate = get_string('useremailduplicate', 'error'); 00072 00073 $strinvalidpasswordpolicy = get_string('invalidpasswordpolicy', 'error'); 00074 $errorstr = get_string('error'); 00075 00076 $stryes = get_string('yes'); 00077 $strno = get_string('no'); 00078 $stryesnooptions = array(0=>$strno, 1=>$stryes); 00079 00080 $returnurl = new moodle_url('/admin/tool/uploaduser/index.php'); 00081 $bulknurl = new moodle_url('/admin/user/user_bulk.php'); 00082 00083 $today = time(); 00084 $today = make_timestamp(date('Y', $today), date('m', $today), date('d', $today), 0, 0, 0); 00085 00086 // array of all valid fields for validation 00087 $STD_FIELDS = array('id', 'firstname', 'lastname', 'username', 'email', 00088 'city', 'country', 'lang', 'timezone', 'mailformat', 00089 'maildisplay', 'maildigest', 'htmleditor', 'ajax', 'autosubscribe', 00090 'institution', 'department', 'idnumber', 'skype', 00091 'msn', 'aim', 'yahoo', 'icq', 'phone1', 'phone2', 'address', 00092 'url', 'description', 'descriptionformat', 'password', 00093 'auth', // watch out when changing auth type or using external auth plugins! 00094 'oldusername', // use when renaming users - this is the original username 00095 'suspended', // 1 means suspend user account, 0 means activate user account, nothing means keep as is for existing users 00096 'deleted', // 1 means delete user 00097 ); 00098 00099 $PRF_FIELDS = array(); 00100 00101 if ($prof_fields = $DB->get_records('user_info_field')) { 00102 foreach ($prof_fields as $prof_field) { 00103 $PRF_FIELDS[] = 'profile_field_'.$prof_field->shortname; 00104 } 00105 } 00106 unset($prof_fields); 00107 00108 if (empty($iid)) { 00109 $mform1 = new admin_uploaduser_form1(); 00110 00111 if ($formdata = $mform1->get_data()) { 00112 $iid = csv_import_reader::get_new_iid('uploaduser'); 00113 $cir = new csv_import_reader($iid, 'uploaduser'); 00114 00115 $content = $mform1->get_file_content('userfile'); 00116 00117 $readcount = $cir->load_csv_content($content, $formdata->encoding, $formdata->delimiter_name); 00118 unset($content); 00119 00120 if ($readcount === false) { 00121 print_error('csvloaderror', '', $returnurl); 00122 } else if ($readcount == 0) { 00123 print_error('csvemptyfile', 'error', $returnurl); 00124 } 00125 // test if columns ok 00126 $filecolumns = uu_validate_user_upload_columns($cir, $STD_FIELDS, $PRF_FIELDS, $returnurl); 00127 // continue to form2 00128 00129 } else { 00130 echo $OUTPUT->header(); 00131 00132 echo $OUTPUT->heading_with_help(get_string('uploadusers', 'tool_uploaduser'), 'uploadusers', 'tool_uploaduser'); 00133 00134 $mform1->display(); 00135 echo $OUTPUT->footer(); 00136 die; 00137 } 00138 } else { 00139 $cir = new csv_import_reader($iid, 'uploaduser'); 00140 $filecolumns = uu_validate_user_upload_columns($cir, $STD_FIELDS, $PRF_FIELDS, $returnurl); 00141 } 00142 00143 $mform2 = new admin_uploaduser_form2(null, array('columns'=>$filecolumns, 'data'=>array('iid'=>$iid, 'previewrows'=>$previewrows))); 00144 00145 // If a file has been uploaded, then process it 00146 if ($formdata = $mform2->is_cancelled()) { 00147 $cir->cleanup(true); 00148 redirect($returnurl); 00149 00150 } else if ($formdata = $mform2->get_data()) { 00151 // Print the header 00152 echo $OUTPUT->header(); 00153 echo $OUTPUT->heading(get_string('uploadusersresult', 'tool_uploaduser')); 00154 00155 $optype = $formdata->uutype; 00156 00157 $updatetype = isset($formdata->uuupdatetype) ? $formdata->uuupdatetype : 0; 00158 $createpasswords = (!empty($formdata->uupasswordnew) and $optype != UU_USER_UPDATE); 00159 $updatepasswords = (!empty($formdata->uupasswordold) and $optype != UU_USER_ADDNEW and $optype != UU_USER_ADDINC and ($updatetype == UU_UPDATE_FILEOVERRIDE or $updatetype == UU_UPDATE_ALLOVERRIDE)); 00160 $allowrenames = (!empty($formdata->uuallowrenames) and $optype != UU_USER_ADDNEW and $optype != UU_USER_ADDINC); 00161 $allowdeletes = (!empty($formdata->uuallowdeletes) and $optype != UU_USER_ADDNEW and $optype != UU_USER_ADDINC); 00162 $allowsuspends = (!empty($formdata->uuallowsuspends)); 00163 $bulk = $formdata->uubulk; 00164 $noemailduplicates = $formdata->uunoemailduplicates; 00165 $standardusernames = $formdata->uustandardusernames; 00166 $resetpasswords = isset($formdata->uuforcepasswordchange) ? $formdata->uuforcepasswordchange : UU_PWRESET_NONE; 00167 00168 // verification moved to two places: after upload and into form2 00169 $usersnew = 0; 00170 $usersupdated = 0; 00171 $usersuptodate = 0; //not printed yet anywhere 00172 $userserrors = 0; 00173 $deletes = 0; 00174 $deleteerrors = 0; 00175 $renames = 0; 00176 $renameerrors = 0; 00177 $usersskipped = 0; 00178 $weakpasswords = 0; 00179 00180 // caches 00181 $ccache = array(); // course cache - do not fetch all courses here, we will not probably use them all anyway! 00182 $cohorts = array(); 00183 $rolecache = uu_allowed_roles_cache(); // roles lookup cache 00184 $manualcache = array(); // cache of used manual enrol plugins in each course 00185 $supportedauths = uu_supported_auths(); // officially supported plugins that are enabled 00186 00187 // we use only manual enrol plugin here, if it is disabled no enrol is done 00188 if (enrol_is_enabled('manual')) { 00189 $manual = enrol_get_plugin('manual'); 00190 } else { 00191 $manual = NULL; 00192 } 00193 00194 // clear bulk selection 00195 if ($bulk) { 00196 $SESSION->bulk_users = array(); 00197 } 00198 00199 // init csv import helper 00200 $cir->init(); 00201 $linenum = 1; //column header is first line 00202 00203 // init upload progress tracker 00204 $upt = new uu_progress_tracker(); 00205 $upt->start(); // start table 00206 00207 while ($line = $cir->next()) { 00208 $upt->flush(); 00209 $linenum++; 00210 00211 $upt->track('line', $linenum); 00212 00213 $user = new stdClass(); 00214 00215 // add fields to user object 00216 foreach ($line as $keynum => $value) { 00217 if (!isset($filecolumns[$keynum])) { 00218 // this should not happen 00219 continue; 00220 } 00221 $key = $filecolumns[$keynum]; 00222 if (strpos($key, 'profile_field_') === 0) { 00223 //NOTE: bloody mega hack alert!! 00224 if (isset($USER->$key) and is_array($USER->$key)) { 00225 // this must be some hacky field that is abusing arrays to store content and format 00226 $user->$key = array(); 00227 $user->$key['text'] = $value; 00228 $user->$key['format'] = FORMAT_MOODLE; 00229 } else { 00230 $user->$key = $value; 00231 } 00232 } else { 00233 $user->$key = $value; 00234 } 00235 00236 if (in_array($key, $upt->columns)) { 00237 // default value in progress tracking table, can be changed later 00238 $upt->track($key, s($value), 'normal'); 00239 } 00240 } 00241 if (!isset($user->username)) { 00242 // prevent warnings below 00243 $user->username = ''; 00244 } 00245 00246 if ($optype == UU_USER_ADDNEW or $optype == UU_USER_ADDINC) { 00247 // user creation is a special case - the username may be constructed from templates using firstname and lastname 00248 // better never try this in mixed update types 00249 $error = false; 00250 if (!isset($user->firstname) or $user->firstname === '') { 00251 $upt->track('status', get_string('missingfield', 'error', 'firstname'), 'error'); 00252 $upt->track('firstname', $errorstr, 'error'); 00253 $error = true; 00254 } 00255 if (!isset($user->lastname) or $user->lastname === '') { 00256 $upt->track('status', get_string('missingfield', 'error', 'lastname'), 'error'); 00257 $upt->track('lastname', $errorstr, 'error'); 00258 $error = true; 00259 } 00260 if ($error) { 00261 $userserrors++; 00262 continue; 00263 } 00264 // we require username too - we might use template for it though 00265 if (empty($user->username) and !empty($formdata->username)) { 00266 $user->username = uu_process_template($formdata->username, $user); 00267 $upt->track('username', s($user->username)); 00268 } 00269 } 00270 00271 // normalize username 00272 $originalusername = $user->username; 00273 if ($standardusernames) { 00274 $user->username = clean_param($user->username, PARAM_USERNAME); 00275 } 00276 00277 // make sure we really have username 00278 if (empty($user->username)) { 00279 $upt->track('status', get_string('missingfield', 'error', 'username'), 'error'); 00280 $upt->track('username', $errorstr, 'error'); 00281 $userserrors++; 00282 continue; 00283 } else if ($user->username === 'guest') { 00284 $upt->track('status', get_string('guestnoeditprofileother', 'error'), 'error'); 00285 $userserrors++; 00286 continue; 00287 } 00288 00289 if ($existinguser = $DB->get_record('user', array('username'=>$user->username, 'mnethostid'=>$CFG->mnet_localhost_id))) { 00290 $upt->track('id', $existinguser->id, 'normal', false); 00291 } 00292 00293 // find out in username incrementing required 00294 if ($existinguser and $optype == UU_USER_ADDINC) { 00295 $user->username = uu_increment_username($user->username); 00296 $existinguser = false; 00297 } 00298 00299 // notify about nay username changes 00300 if ($originalusername !== $user->username) { 00301 $upt->track('username', '', 'normal', false); // clear previous 00302 $upt->track('username', s($originalusername).'-->'.s($user->username), 'info'); 00303 } else { 00304 $upt->track('username', s($user->username), 'normal', false); 00305 } 00306 00307 // add default values for remaining fields 00308 $formdefaults = array(); 00309 foreach ($STD_FIELDS as $field) { 00310 if (isset($user->$field)) { 00311 continue; 00312 } 00313 // all validation moved to form2 00314 if (isset($formdata->$field)) { 00315 // process templates 00316 $user->$field = uu_process_template($formdata->$field, $user); 00317 $formdefaults[$field] = true; 00318 if (in_array($field, $upt->columns)) { 00319 $upt->track($field, s($user->$field), 'normal'); 00320 } 00321 } 00322 } 00323 foreach ($PRF_FIELDS as $field) { 00324 if (isset($user->$field)) { 00325 continue; 00326 } 00327 if (isset($formdata->$field)) { 00328 // process templates 00329 $user->$field = uu_process_template($formdata->$field, $user); 00330 $formdefaults[$field] = true; 00331 } 00332 } 00333 00334 // delete user 00335 if (!empty($user->deleted)) { 00336 if (!$allowdeletes) { 00337 $usersskipped++; 00338 $upt->track('status', $strusernotdeletedoff, 'warning'); 00339 continue; 00340 } 00341 if ($existinguser) { 00342 if (is_siteadmin($existinguser->id)) { 00343 $upt->track('status', $strusernotdeletedadmin, 'error'); 00344 $deleteerrors++; 00345 continue; 00346 } 00347 if (delete_user($existinguser)) { 00348 $upt->track('status', $struserdeleted); 00349 $deletes++; 00350 } else { 00351 $upt->track('status', $strusernotdeletederror, 'error'); 00352 $deleteerrors++; 00353 } 00354 } else { 00355 $upt->track('status', $strusernotdeletedmissing, 'error'); 00356 $deleteerrors++; 00357 } 00358 continue; 00359 } 00360 // we do not need the deleted flag anymore 00361 unset($user->deleted); 00362 00363 // renaming requested? 00364 if (!empty($user->oldusername) ) { 00365 if (!$allowrenames) { 00366 $usersskipped++; 00367 $upt->track('status', $strusernotrenamedoff, 'warning'); 00368 continue; 00369 } 00370 00371 if ($existinguser) { 00372 $upt->track('status', $strusernotrenamedexists, 'error'); 00373 $renameerrors++; 00374 continue; 00375 } 00376 00377 if ($user->username === 'guest') { 00378 $upt->track('status', get_string('guestnoeditprofileother', 'error'), 'error'); 00379 $renameerrors++; 00380 continue; 00381 } 00382 00383 if ($standardusernames) { 00384 $oldusername = clean_param($user->oldusername, PARAM_USERNAME); 00385 } else { 00386 $oldusername = $user->oldusername; 00387 } 00388 00389 // no guessing when looking for old username, it must be exact match 00390 if ($olduser = $DB->get_record('user', array('username'=>$oldusername, 'mnethostid'=>$CFG->mnet_localhost_id))) { 00391 $upt->track('id', $olduser->id, 'normal', false); 00392 if (is_siteadmin($olduser->id)) { 00393 $upt->track('status', $strusernotrenamedadmin, 'error'); 00394 $renameerrors++; 00395 continue; 00396 } 00397 $DB->set_field('user', 'username', $user->username, array('id'=>$olduser->id)); 00398 $upt->track('username', '', 'normal', false); // clear previous 00399 $upt->track('username', s($oldusername).'-->'.s($user->username), 'info'); 00400 $upt->track('status', $struserrenamed); 00401 $renames++; 00402 } else { 00403 $upt->track('status', $strusernotrenamedmissing, 'error'); 00404 $renameerrors++; 00405 continue; 00406 } 00407 $existinguser = $olduser; 00408 $existinguser->username = $user->username; 00409 } 00410 00411 // can we process with update or insert? 00412 $skip = false; 00413 switch ($optype) { 00414 case UU_USER_ADDNEW: 00415 if ($existinguser) { 00416 $usersskipped++; 00417 $upt->track('status', $strusernotadded, 'warning'); 00418 $skip = true; 00419 } 00420 break; 00421 00422 case UU_USER_ADDINC: 00423 if ($existinguser) { 00424 //this should not happen! 00425 $upt->track('status', $strusernotaddederror, 'error'); 00426 $userserrors++; 00427 $skip = true; 00428 } 00429 break; 00430 00431 case UU_USER_ADD_UPDATE: 00432 break; 00433 00434 case UU_USER_UPDATE: 00435 if (!$existinguser) { 00436 $usersskipped++; 00437 $upt->track('status', $strusernotupdatednotexists, 'warning'); 00438 $skip = true; 00439 } 00440 break; 00441 00442 default: 00443 // unknown type 00444 $skip = true; 00445 } 00446 00447 if ($skip) { 00448 continue; 00449 } 00450 00451 if ($existinguser) { 00452 $user->id = $existinguser->id; 00453 00454 $upt->track('username', html_writer::link(new moodle_url('/user/profile.php', array('id'=>$existinguser->id)), s($existinguser->username)), 'normal', false); 00455 $upt->track('suspended', $stryesnooptions[$existinguser->suspended] , 'normal', false); 00456 00457 if (is_siteadmin($user->id)) { 00458 $upt->track('status', $strusernotupdatedadmin, 'error'); 00459 $userserrors++; 00460 continue; 00461 } 00462 00463 $existinguser->timemodified = time(); 00464 // do NOT mess with timecreated or firstaccess here! 00465 00466 //load existing profile data 00467 profile_load_data($existinguser); 00468 00469 $upt->track('auth', $existinguser->auth, 'normal', false); 00470 00471 $doupdate = false; 00472 $dologout = false; 00473 00474 if ($updatetype != UU_UPDATE_NOCHANGES) { 00475 if (!empty($user->auth) and $user->auth !== $existinguser->auth) { 00476 $upt->track('auth', s($existinguser->auth).'-->'.s($user->auth), 'info', false); 00477 $existinguser->auth = $user->auth; 00478 if (!isset($supportedauths[$user->auth])) { 00479 $upt->track('auth', $struserauthunsupported, 'warning'); 00480 } 00481 $doupdate = true; 00482 if ($existinguser->auth === 'nologin') { 00483 $dologout = true; 00484 } 00485 } 00486 $allcolumns = array_merge($STD_FIELDS, $PRF_FIELDS); 00487 foreach ($allcolumns as $column) { 00488 if ($column === 'username' or $column === 'password' or $column === 'auth' or $column === 'suspended') { 00489 // these can not be changed here 00490 continue; 00491 } 00492 if (!property_exists($user, $column) or !property_exists($existinguser, $column)) { 00493 // this should never happen 00494 continue; 00495 } 00496 if ($updatetype == UU_UPDATE_MISSING) { 00497 if (!is_null($existinguser->$column) and $existinguser->$column !== '') { 00498 continue; 00499 } 00500 } else if ($updatetype == UU_UPDATE_ALLOVERRIDE) { 00501 // we override everything 00502 00503 } else if ($updatetype == UU_UPDATE_FILEOVERRIDE) { 00504 if (!empty($formdefaults[$column])) { 00505 // do not override with form defaults 00506 continue; 00507 } 00508 } 00509 if ($existinguser->$column !== $user->$column) { 00510 if ($column === 'email') { 00511 if ($DB->record_exists('user', array('email'=>$user->email))) { 00512 if ($noemailduplicates) { 00513 $upt->track('email', $stremailduplicate, 'error'); 00514 $upt->track('status', $strusernotupdated, 'error'); 00515 $userserrors++; 00516 continue 2; 00517 } else { 00518 $upt->track('email', $stremailduplicate, 'warning'); 00519 } 00520 } 00521 if (!validate_email($user->email)) { 00522 $upt->track('email', get_string('invalidemail'), 'warning'); 00523 } 00524 } 00525 00526 if (in_array($column, $upt->columns)) { 00527 $upt->track($column, s($existinguser->$column).'-->'.s($user->$column), 'info', false); 00528 } 00529 $existinguser->$column = $user->$column; 00530 $doupdate = true; 00531 } 00532 } 00533 } 00534 00535 try { 00536 $auth = get_auth_plugin($existinguser->auth); 00537 } catch (Exception $e) { 00538 $upt->track('auth', get_string('userautherror', 'error', s($existinguser->auth)), 'error'); 00539 $upt->track('status', $strusernotupdated, 'error'); 00540 $userserrors++; 00541 continue; 00542 } 00543 $isinternalauth = $auth->is_internal(); 00544 00545 // deal with suspending and activating of accounts 00546 if ($allowsuspends and isset($user->suspended) and $user->suspended !== '') { 00547 $user->suspended = $user->suspended ? 1 : 0; 00548 if ($existinguser->suspended != $user->suspended) { 00549 $upt->track('suspended', '', 'normal', false); 00550 $upt->track('suspended', $stryesnooptions[$existinguser->suspended].'-->'.$stryesnooptions[$user->suspended], 'info', false); 00551 $existinguser->suspended = $user->suspended; 00552 $doupdate = true; 00553 if ($existinguser->suspended) { 00554 $dologout = true; 00555 } 00556 } 00557 } 00558 00559 // changing of passwords is a special case 00560 // do not force password changes for external auth plugins! 00561 $oldpw = $existinguser->password; 00562 if (!$isinternalauth) { 00563 $existinguser->password = 'not cached'; 00564 $upt->track('password', '-', 'normal', false); 00565 // clean up prefs 00566 unset_user_preference('create_password', $existinguser); 00567 unset_user_preference('auth_forcepasswordchange', $existinguser); 00568 00569 } else if (!empty($user->password)) { 00570 if ($updatepasswords) { 00571 $errmsg = null; 00572 $weak = !check_password_policy($user->password, $errmsg); 00573 if ($resetpasswords == UU_PWRESET_ALL or ($resetpasswords == UU_PWRESET_WEAK and $weak)) { 00574 if ($weak) { 00575 $weakpasswords++; 00576 $upt->track('password', $strinvalidpasswordpolicy, 'warning'); 00577 } 00578 set_user_preference('auth_forcepasswordchange', 1, $existinguser); 00579 } else { 00580 unset_user_preference('auth_forcepasswordchange', $existinguser); 00581 } 00582 unset_user_preference('create_password', $existinguser); // no need to create password any more 00583 $existinguser->password = hash_internal_user_password($user->password); 00584 $upt->track('password', $user->password, 'normal', false); 00585 } else { 00586 // do not print password when not changed 00587 $upt->track('password', '', 'normal', false); 00588 } 00589 } 00590 00591 if ($doupdate or $existinguser->password !== $oldpw) { 00592 // we want only users that were really updated 00593 00594 $DB->update_record('user', $existinguser); 00595 00596 $upt->track('status', $struserupdated); 00597 $usersupdated++; 00598 // save custom profile fields data from csv file 00599 profile_save_data($existinguser); 00600 00601 events_trigger('user_updated', $existinguser); 00602 00603 if ($bulk == UU_BULK_UPDATED or $bulk == UU_BULK_ALL) { 00604 if (!in_array($user->id, $SESSION->bulk_users)) { 00605 $SESSION->bulk_users[] = $user->id; 00606 } 00607 } 00608 00609 } else { 00610 // no user information changed 00611 $upt->track('status', $struseruptodate); 00612 $usersuptodate++; 00613 00614 if ($bulk == UU_BULK_ALL) { 00615 if (!in_array($user->id, $SESSION->bulk_users)) { 00616 $SESSION->bulk_users[] = $user->id; 00617 } 00618 } 00619 } 00620 00621 if ($dologout) { 00622 session_kill_user($existinguser->id); 00623 } 00624 00625 } else { 00626 // save the new user to the database 00627 $user->confirmed = 1; 00628 $user->timemodified = time(); 00629 $user->timecreated = time(); 00630 $user->mnethostid = $CFG->mnet_localhost_id; // we support ONLY local accounts here, sorry 00631 00632 if (!isset($user->suspended) or $user->suspended === '') { 00633 $user->suspended = 0; 00634 } else { 00635 $user->suspended = $user->suspended ? 1 : 0; 00636 } 00637 $upt->track('suspended', $stryesnooptions[$user->suspended], 'normal', false); 00638 00639 if (empty($user->auth)) { 00640 $user->auth = 'manual'; 00641 } 00642 $upt->track('auth', $user->auth, 'normal', false); 00643 00644 // do not insert record if new auth plugin does not exist! 00645 try { 00646 $auth = get_auth_plugin($user->auth); 00647 } catch (Exception $e) { 00648 $upt->track('auth', get_string('userautherror', 'error', s($user->auth)), 'error'); 00649 $upt->track('status', $strusernotaddederror, 'error'); 00650 $userserrors++; 00651 continue; 00652 } 00653 if (!isset($supportedauths[$user->auth])) { 00654 $upt->track('auth', $struserauthunsupported, 'warning'); 00655 } 00656 00657 $isinternalauth = $auth->is_internal(); 00658 00659 if (empty($user->email)) { 00660 $upt->track('email', get_string('invalidemail'), 'error'); 00661 $upt->track('status', $strusernotaddederror, 'error'); 00662 $userserrors++; 00663 continue; 00664 00665 } else if ($DB->record_exists('user', array('email'=>$user->email))) { 00666 if ($noemailduplicates) { 00667 $upt->track('email', $stremailduplicate, 'error'); 00668 $upt->track('status', $strusernotaddederror, 'error'); 00669 $userserrors++; 00670 continue; 00671 } else { 00672 $upt->track('email', $stremailduplicate, 'warning'); 00673 } 00674 } 00675 if (!validate_email($user->email)) { 00676 $upt->track('email', get_string('invalidemail'), 'warning'); 00677 } 00678 00679 $forcechangepassword = false; 00680 00681 if ($isinternalauth) { 00682 if (empty($user->password)) { 00683 if ($createpasswords) { 00684 $user->password = 'to be generated'; 00685 $upt->track('password', '', 'normal', false); 00686 $upt->track('password', get_string('uupasswordcron', 'tool_uploaduser'), 'warning', false); 00687 } else { 00688 $upt->track('password', '', 'normal', false); 00689 $upt->track('password', get_string('missingfield', 'error', 'password'), 'error'); 00690 $upt->track('status', $strusernotaddederror, 'error'); 00691 $userserrors++; 00692 continue; 00693 } 00694 } else { 00695 $errmsg = null; 00696 $weak = !check_password_policy($user->password, $errmsg); 00697 if ($resetpasswords == UU_PWRESET_ALL or ($resetpasswords == UU_PWRESET_WEAK and $weak)) { 00698 if ($weak) { 00699 $weakpasswords++; 00700 $upt->track('password', $strinvalidpasswordpolicy, 'warning'); 00701 } 00702 $forcechangepassword = true; 00703 } 00704 $user->password = hash_internal_user_password($user->password); 00705 } 00706 } else { 00707 $user->password = 'not cached'; 00708 $upt->track('password', '-', 'normal', false); 00709 } 00710 00711 // create user - insert_record ignores any extra properties 00712 $user->id = $DB->insert_record('user', $user); 00713 $upt->track('username', html_writer::link(new moodle_url('/user/profile.php', array('id'=>$user->id)), s($user->username)), 'normal', false); 00714 00715 // save custom profile fields data 00716 profile_save_data($user); 00717 00718 if ($forcechangepassword) { 00719 set_user_preference('auth_forcepasswordchange', 1, $user); 00720 } 00721 if ($user->password === 'to be generated') { 00722 set_user_preference('create_password', 1, $user); 00723 } 00724 00725 $upt->track('status', $struseradded); 00726 $upt->track('id', $user->id, 'normal', false); 00727 $usersnew++; 00728 00729 // make sure user context exists 00730 get_context_instance(CONTEXT_USER, $user->id); 00731 00732 events_trigger('user_created', $user); 00733 00734 if ($bulk == UU_BULK_NEW or $bulk == UU_BULK_ALL) { 00735 if (!in_array($user->id, $SESSION->bulk_users)) { 00736 $SESSION->bulk_users[] = $user->id; 00737 } 00738 } 00739 } 00740 00741 00742 // add to cohort first, it might trigger enrolments indirectly - do NOT create cohorts here! 00743 foreach ($filecolumns as $column) { 00744 if (!preg_match('/^cohort\d+$/', $column)) { 00745 continue; 00746 } 00747 00748 if (!empty($user->$column)) { 00749 $addcohort = $user->$column; 00750 if (!isset($cohorts[$addcohort])) { 00751 if (is_number($addcohort)) { 00752 // only non-numeric idnumbers! 00753 $cohort = $DB->get_record('cohort', array('id'=>$addcohort)); 00754 } else { 00755 $cohort = $DB->get_record('cohort', array('idnumber'=>$addcohort)); 00756 } 00757 00758 if (empty($cohort)) { 00759 $cohorts[$addcohort] = get_string('unknowncohort', 'core_cohort', s($addcohort)); 00760 } else if (!empty($cohort->component)) { 00761 // cohorts synchronised with external sources must not be modified! 00762 $cohorts[$addcohort] = get_string('external', 'core_cohort'); 00763 } else { 00764 $cohorts[$addcohort] = $cohort; 00765 } 00766 } 00767 00768 if (is_object($cohorts[$addcohort])) { 00769 $cohort = $cohorts[$addcohort]; 00770 if (!$DB->record_exists('cohort_members', array('cohortid'=>$cohort->id, 'userid'=>$user->id))) { 00771 cohort_add_member($cohort->id, $user->id); 00772 // we might add special column later, for now let's abuse enrolments 00773 $upt->track('enrolments', get_string('useradded', 'core_cohort', s($cohort->name))); 00774 } 00775 } else { 00776 // error message 00777 $upt->track('enrolments', $cohorts[$addcohort], 'error'); 00778 } 00779 } 00780 } 00781 00782 00783 // find course enrolments, groups, roles/types and enrol periods 00784 // this is again a special case, we always do this for any updated or created users 00785 foreach ($filecolumns as $column) { 00786 if (!preg_match('/^course\d+$/', $column)) { 00787 continue; 00788 } 00789 $i = substr($column, 6); 00790 00791 if (empty($user->{'course'.$i})) { 00792 continue; 00793 } 00794 $shortname = $user->{'course'.$i}; 00795 if (!array_key_exists($shortname, $ccache)) { 00796 if (!$course = $DB->get_record('course', array('shortname'=>$shortname), 'id, shortname')) { 00797 $upt->track('enrolments', get_string('unknowncourse', 'error', s($shortname)), 'error'); 00798 continue; 00799 } 00800 $ccache[$shortname] = $course; 00801 $ccache[$shortname]->groups = null; 00802 } 00803 $courseid = $ccache[$shortname]->id; 00804 $coursecontext = get_context_instance(CONTEXT_COURSE, $courseid); 00805 if (!isset($manualcache[$courseid])) { 00806 $manualcache[$courseid] = false; 00807 if ($manual) { 00808 if ($instances = enrol_get_instances($courseid, false)) { 00809 foreach ($instances as $instance) { 00810 if ($instance->enrol === 'manual') { 00811 $manualcache[$courseid] = $instance; 00812 break; 00813 } 00814 } 00815 } 00816 } 00817 } 00818 00819 if ($manual and $manualcache[$courseid]) { 00820 00821 // find role 00822 $rid = false; 00823 if (!empty($user->{'role'.$i})) { 00824 $addrole = $user->{'role'.$i}; 00825 if (array_key_exists($addrole, $rolecache)) { 00826 $rid = $rolecache[$addrole]->id; 00827 } else { 00828 $upt->track('enrolments', get_string('unknownrole', 'error', s($addrole)), 'error'); 00829 continue; 00830 } 00831 00832 } else if (!empty($user->{'type'.$i})) { 00833 // if no role, then find "old" enrolment type 00834 $addtype = $user->{'type'.$i}; 00835 if ($addtype < 1 or $addtype > 3) { 00836 $upt->track('enrolments', $strerror.': typeN = 1|2|3', 'error'); 00837 continue; 00838 } else if (empty($formdata->{'uulegacy'.$addtype})) { 00839 continue; 00840 } else { 00841 $rid = $formdata->{'uulegacy'.$addtype}; 00842 } 00843 } else { 00844 // no role specified, use the default from manual enrol plugin 00845 $rid = $manualcache[$courseid]->roleid; 00846 } 00847 00848 if ($rid) { 00849 // find duration 00850 $timeend = 0; 00851 if (!empty($user->{'enrolperiod'.$i})) { 00852 $duration = (int)$user->{'enrolperiod'.$i} * 60*60*24; // convert days to seconds 00853 if ($duration > 0) { // sanity check 00854 $timeend = $today + $duration; 00855 } 00856 } 00857 00858 $manual->enrol_user($manualcache[$courseid], $user->id, $rid, $today, $timeend); 00859 00860 $a = new stdClass(); 00861 $a->course = $shortname; 00862 $a->role = $rolecache[$rid]->name; 00863 $upt->track('enrolments', get_string('enrolledincourserole', 'enrol_manual', $a)); 00864 } 00865 } 00866 00867 // find group to add to 00868 if (!empty($user->{'group'.$i})) { 00869 // make sure user is enrolled into course before adding into groups 00870 if (!is_enrolled($coursecontext, $user->id)) { 00871 $upt->track('enrolments', get_string('addedtogroupnotenrolled', '', $user->{'group'.$i}), 'error'); 00872 continue; 00873 } 00874 //build group cache 00875 if (is_null($ccache[$shortname]->groups)) { 00876 $ccache[$shortname]->groups = array(); 00877 if ($groups = groups_get_all_groups($courseid)) { 00878 foreach ($groups as $gid=>$group) { 00879 $ccache[$shortname]->groups[$gid] = new stdClass(); 00880 $ccache[$shortname]->groups[$gid]->id = $gid; 00881 $ccache[$shortname]->groups[$gid]->name = $group->name; 00882 if (!is_numeric($group->name)) { // only non-numeric names are supported!!! 00883 $ccache[$shortname]->groups[$group->name] = new stdClass(); 00884 $ccache[$shortname]->groups[$group->name]->id = $gid; 00885 $ccache[$shortname]->groups[$group->name]->name = $group->name; 00886 } 00887 } 00888 } 00889 } 00890 // group exists? 00891 $addgroup = $user->{'group'.$i}; 00892 if (!array_key_exists($addgroup, $ccache[$shortname]->groups)) { 00893 // if group doesn't exist, create it 00894 $newgroupdata = new stdClass(); 00895 $newgroupdata->name = $addgroup; 00896 $newgroupdata->courseid = $ccache[$shortname]->id; 00897 if ($ccache[$shortname]->groups[$addgroup]->id = groups_create_group($newgroupdata)){ 00898 $ccache[$shortname]->groups[$addgroup]->name = $newgroupdata->name; 00899 } else { 00900 $upt->track('enrolments', get_string('unknowngroup', 'error', s($addgroup)), 'error'); 00901 continue; 00902 } 00903 } 00904 $gid = $ccache[$shortname]->groups[$addgroup]->id; 00905 $gname = $ccache[$shortname]->groups[$addgroup]->name; 00906 00907 try { 00908 if (groups_add_member($gid, $user->id)) { 00909 $upt->track('enrolments', get_string('addedtogroup', '', s($gname))); 00910 } else { 00911 $upt->track('enrolments', get_string('addedtogroupnot', '', s($gname)), 'error'); 00912 } 00913 } catch (moodle_exception $e) { 00914 $upt->track('enrolments', get_string('addedtogroupnot', '', s($gname)), 'error'); 00915 continue; 00916 } 00917 } 00918 } 00919 } 00920 $upt->close(); // close table 00921 00922 $cir->close(); 00923 $cir->cleanup(true); 00924 00925 echo $OUTPUT->box_start('boxwidthnarrow boxaligncenter generalbox', 'uploadresults'); 00926 echo '<p>'; 00927 if ($optype != UU_USER_UPDATE) { 00928 echo get_string('userscreated', 'tool_uploaduser').': '.$usersnew.'<br />'; 00929 } 00930 if ($optype == UU_USER_UPDATE or $optype == UU_USER_ADD_UPDATE) { 00931 echo get_string('usersupdated', 'tool_uploaduser').': '.$usersupdated.'<br />'; 00932 } 00933 if ($allowdeletes) { 00934 echo get_string('usersdeleted', 'tool_uploaduser').': '.$deletes.'<br />'; 00935 echo get_string('deleteerrors', 'tool_uploaduser').': '.$deleteerrors.'<br />'; 00936 } 00937 if ($allowrenames) { 00938 echo get_string('usersrenamed', 'tool_uploaduser').': '.$renames.'<br />'; 00939 echo get_string('renameerrors', 'tool_uploaduser').': '.$renameerrors.'<br />'; 00940 } 00941 if ($usersskipped) { 00942 echo get_string('usersskipped', 'tool_uploaduser').': '.$usersskipped.'<br />'; 00943 } 00944 echo get_string('usersweakpassword', 'tool_uploaduser').': '.$weakpasswords.'<br />'; 00945 echo get_string('errors', 'tool_uploaduser').': '.$userserrors.'</p>'; 00946 echo $OUTPUT->box_end(); 00947 00948 if ($bulk) { 00949 echo $OUTPUT->continue_button($bulknurl); 00950 } else { 00951 echo $OUTPUT->continue_button($returnurl); 00952 } 00953 echo $OUTPUT->footer(); 00954 die; 00955 } 00956 00957 // Print the header 00958 echo $OUTPUT->header(); 00959 00960 echo $OUTPUT->heading(get_string('uploaduserspreview', 'tool_uploaduser')); 00961 00962 // NOTE: this is JUST csv processing preview, we must not prevent import from here if there is something in the file!! 00963 // this was intended for validation of csv formatting and encoding, not filtering the data!!!! 00964 // we definitely must not process the whole file! 00965 00966 // preview table data 00967 $data = array(); 00968 $cir->init(); 00969 $linenum = 1; //column header is first line 00970 while ($linenum <= $previewrows and $fields = $cir->next()) { 00971 $linenum++; 00972 $rowcols = array(); 00973 $rowcols['line'] = $linenum; 00974 foreach($fields as $key => $field) { 00975 $rowcols[$filecolumns[$key]] = s($field); 00976 } 00977 $rowcols['status'] = array(); 00978 00979 if (isset($rowcols['username'])) { 00980 $stdusername = clean_param($rowcols['username'], PARAM_USERNAME); 00981 if ($rowcols['username'] !== $stdusername) { 00982 $rowcols['status'][] = get_string('invalidusernameupload'); 00983 } 00984 if ($userid = $DB->get_field('user', 'id', array('username'=>$stdusername, 'mnethostid'=>$CFG->mnet_localhost_id))) { 00985 $rowcols['username'] = html_writer::link(new moodle_url('/user/profile.php', array('id'=>$userid)), $rowcols['username']); 00986 } 00987 } else { 00988 $rowcols['status'][] = get_string('missingusername'); 00989 } 00990 00991 if (isset($rowcols['email'])) { 00992 if (!validate_email($rowcols['email'])) { 00993 $rowcols['status'][] = get_string('invalidemail'); 00994 } 00995 if ($DB->record_exists('user', array('email'=>$rowcols['email']))) { 00996 $rowcols['status'][] = $stremailduplicate; 00997 } 00998 } 00999 01000 if (isset($rowcols['city'])) { 01001 $rowcols['city'] = trim($rowcols['city']); 01002 if (empty($rowcols['city'])) { 01003 $rowcols['status'][] = get_string('fieldrequired', 'error', 'city'); 01004 } 01005 } 01006 01007 $rowcols['status'] = implode('<br />', $rowcols['status']); 01008 $data[] = $rowcols; 01009 } 01010 if ($fields = $cir->next()) { 01011 $data[] = array_fill(0, count($fields) + 2, '...'); 01012 } 01013 $cir->close(); 01014 01015 $table = new html_table(); 01016 $table->id = "uupreview"; 01017 $table->attributes['class'] = 'generaltable'; 01018 $table->tablealign = 'center'; 01019 $table->summary = get_string('uploaduserspreview', 'tool_uploaduser'); 01020 $table->head = array(); 01021 $table->data = $data; 01022 01023 $table->head[] = get_string('uucsvline', 'tool_uploaduser'); 01024 foreach ($filecolumns as $column) { 01025 $table->head[] = $column; 01026 } 01027 $table->head[] = get_string('status'); 01028 01029 echo html_writer::tag('div', html_writer::table($table), array('class'=>'flexible-wrap')); 01030 01032 01033 $mform2->display(); 01034 echo $OUTPUT->footer(); 01035 die; 01036