/** * Return multidimensional array with details of user courses (at * least dn and idnumber). * * @param string $memberuid user idnumber (without magic quotes). * @param object role is a record from the mdl_role table. * @return array */ protected function find_ext_enrolments($memberuid, $role) { global $CFG; require_once $CFG->libdir . '/ldaplib.php'; if (empty($memberuid)) { // No "idnumber" stored for this user, so no LDAP enrolments return array(); } $ldap_contexts = trim($this->get_config('contexts_role' . $role->id)); if (empty($ldap_contexts)) { // No role contexts, so no LDAP enrolments return array(); } $extmemberuid = core_text::convert($memberuid, 'utf-8', $this->get_config('ldapencoding')); if ($this->get_config('memberattribute_isdn')) { if (!($extmemberuid = $this->ldap_find_userdn($extmemberuid))) { return array(); } } $ldap_search_pattern = ''; if ($this->get_config('nested_groups')) { $usergroups = $this->ldap_find_user_groups($extmemberuid); if (count($usergroups) > 0) { foreach ($usergroups as $group) { $ldap_search_pattern .= '(' . $this->get_config('memberattribute_role' . $role->id) . '=' . $group . ')'; } } } // Default return value $courses = array(); // Get all the fields we will want for the potential course creation // as they are light. don't get membership -- potentially a lot of data. $ldap_fields_wanted = array('dn', $this->get_config('course_idnumber')); $fullname = $this->get_config('course_fullname'); $shortname = $this->get_config('course_shortname'); $summary = $this->get_config('course_summary'); if (isset($fullname)) { array_push($ldap_fields_wanted, $fullname); } if (isset($shortname)) { array_push($ldap_fields_wanted, $shortname); } if (isset($summary)) { array_push($ldap_fields_wanted, $summary); } // Define the search pattern if (empty($ldap_search_pattern)) { $ldap_search_pattern = '(' . $this->get_config('memberattribute_role' . $role->id) . '=' . ldap_filter_addslashes($extmemberuid) . ')'; } else { $ldap_search_pattern = '(|' . $ldap_search_pattern . '(' . $this->get_config('memberattribute_role' . $role->id) . '=' . ldap_filter_addslashes($extmemberuid) . ')' . ')'; } $ldap_search_pattern = '(&' . $this->get_config('objectclass') . $ldap_search_pattern . ')'; // Get all contexts and look for first matching user $ldap_contexts = explode(';', $ldap_contexts); $ldap_pagedresults = ldap_paged_results_supported($this->get_config('ldap_version')); foreach ($ldap_contexts as $context) { $context = trim($context); if (empty($context)) { continue; } $ldap_cookie = ''; $flat_records = array(); do { if ($ldap_pagedresults) { ldap_control_paged_result($this->ldapconnection, $this->config->pagesize, true, $ldap_cookie); } if ($this->get_config('course_search_sub')) { // Use ldap_search to find first user from subtree $ldap_result = @ldap_search($this->ldapconnection, $context, $ldap_search_pattern, $ldap_fields_wanted); } else { // Search only in this context $ldap_result = @ldap_list($this->ldapconnection, $context, $ldap_search_pattern, $ldap_fields_wanted); } if (!$ldap_result) { continue; } if ($ldap_pagedresults) { ldap_control_paged_result_response($this->ldapconnection, $ldap_result, $ldap_cookie); } // Check and push results. ldap_get_entries() already // lowercases the attribute index, so there's no need to // use array_change_key_case() later. $records = ldap_get_entries($this->ldapconnection, $ldap_result); // LDAP libraries return an odd array, really. Fix it. for ($c = 0; $c < $records['count']; $c++) { array_push($flat_records, $records[$c]); } // Free some mem unset($records); } while ($ldap_pagedresults && !empty($ldap_cookie)); // If LDAP paged results were used, the current connection must be completely // closed and a new one created, to work without paged results from here on. if ($ldap_pagedresults) { $this->ldap_close(); $this->ldap_connect(); } if (count($flat_records)) { $courses = array_merge($courses, $flat_records); } } return $courses; }
/** * Returns all usernames from LDAP * * @param $filter An LDAP search filter to select desired users * @return array of LDAP user names converted to UTF-8 */ function ldap_get_userlist($filter = '*') { $fresult = array(); $ldapconnection = $this->ldap_connect(); if ($filter == '*') { $filter = '(&(' . $this->config->user_attribute . '=*)' . $this->config->objectclass . ')'; } $contexts = explode(';', $this->config->contexts); if (!empty($this->config->create_context)) { array_push($contexts, $this->config->create_context); } $ldap_cookie = ''; $ldap_pagedresults = ldap_paged_results_supported($this->config->ldap_version); foreach ($contexts as $context) { $context = trim($context); if (empty($context)) { continue; } do { if ($ldap_pagedresults) { ldap_control_paged_result($ldapconnection, $this->config->pagesize, true, $ldap_cookie); } if ($this->config->search_sub) { // Use ldap_search to find first user from subtree. $ldap_result = ldap_search($ldapconnection, $context, $filter, array($this->config->user_attribute)); } else { // Search only in this context. $ldap_result = ldap_list($ldapconnection, $context, $filter, array($this->config->user_attribute)); } if (!$ldap_result) { continue; } if ($ldap_pagedresults) { ldap_control_paged_result_response($ldapconnection, $ldap_result, $ldap_cookie); } $users = ldap_get_entries_moodle($ldapconnection, $ldap_result); // Add found users to list. for ($i = 0; $i < count($users); $i++) { $extuser = core_text::convert($users[$i][$this->config->user_attribute][0], $this->config->ldapencoding, 'utf-8'); array_push($fresult, $extuser); } unset($ldap_result); // Free mem. } while ($ldap_pagedresults && !empty($ldap_cookie)); } // If paged results were used, make sure the current connection is completely closed $this->ldap_close($ldap_pagedresults); return $fresult; }
/** * Prints a form for configuring this authentication plugin. * * This function is called from admin/auth.php, and outputs a full page with * a form for configuring this plugin. * * @param array $page An object containing all the data for this page. */ function config_form($config, $err, $user_fields) { global $CFG, $OUTPUT; if (!function_exists('ldap_connect')) { // Is php-ldap really there? echo $OUTPUT->notification(get_string('auth_ldap_noextension', 'auth_ldap')); // Don't return here, like we do in auth/ldap. We cas use CAS without LDAP. // So just warn the user (done above) and define the LDAP constants we use // in config.html, to silence the warnings. if (!defined('LDAP_DEREF_NEVER')) { define('LDAP_DEREF_NEVER', 0); } if (!defined('LDAP_DEREF_ALWAYS')) { define('LDAP_DEREF_ALWAYS', 3); } } if (!ldap_paged_results_supported($this->config->ldap_version)) { echo $OUTPUT->notification(get_string('pagedresultsnotsupp', 'auth_ldap')); } include $CFG->dirroot . '/auth/cas/config.html'; }
/** * Prints a form for configuring this authentication plugin. * * This function is called from admin/auth.php, and outputs a full page with * a form for configuring this plugin. * * @param array $page An object containing all the data for this page. */ function config_form($config, $err, $user_fields) { global $CFG, $OUTPUT; if (!function_exists('ldap_connect')) { // Is php-ldap really there? echo $OUTPUT->notification(get_string('auth_ldap_noextension', 'auth_ldap')); return; } if (!ldap_paged_results_supported($this->config->ldap_version)) { echo $OUTPUT->notification(get_string('pagedresultsnotsupp', 'auth_ldap')); } include $CFG->dirroot . '/auth/ldap/config.html'; }
/** * Syncronizes user from external LDAP server to moodle user table * * Sync is now using username attribute. * * Syncing users removes or suspends users that dont exists anymore in external LDAP. * Creates new users and updates coursecreator status of users. * * @param bool $do_updates will do pull in data updates from LDAP if relevant */ function local_ent_installer_sync_users($ldapauth, $options) { global $CFG, $DB, $MATCH_STATUS; mtrace(''); $enable = get_config('local_ent_installer', 'sync_enable'); if (!$enable) { mtrace(get_string('syncdisabled', 'local_ent_installer')); return; } $USERFIELDS = local_ent_installer_load_user_fields(); $lastrun = get_config('local_ent_installer', 'last_sync_date'); mtrace(get_string('lastrun', 'local_ent_installer', userdate($lastrun))); mtrace(get_string('connectingldap', 'auth_ldap')); if (isset($CFG->auth_ldap_sync_user_type)) { $ldapauth->config->user_type = $CFG->auth_ldap_sync_user_type; } if (isset($CFG->auth_ldap_sync_search_contexts)) { $ldapauth->config->contexts = $CFG->auth_ldap_sync_search_contexts; } $ldapconnection = $ldapauth->ldap_connect(); $dbman = $DB->get_manager(); list($usec, $sec) = explode(' ', microtime()); $starttick = (double) $sec + (double) $usec; // Define table user to be created. $table = new xmldb_table('tmp_extuser'); $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); $table->add_field('username', XMLDB_TYPE_CHAR, '100', null, XMLDB_NOTNULL, null, null); $table->add_field('mnethostid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null); $table->add_field('usertype', XMLDB_TYPE_CHAR, '16', null, null, null, null); $table->add_field('lastmodified', XMLDB_TYPE_INTEGER, '11', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null); $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id')); $table->add_index('userprofile', XMLDB_INDEX_UNIQUE, array('mnethostid', 'username', 'usertype')); mtrace(get_string('creatingtemptable', 'auth_ldap', 'tmp_extuser')); if ($dbman->table_exists($table)) { $dbman->drop_table($table); } $dbman->create_temp_table($table); // // get user's list from ldap to sql in a scalable fashion from different user profiles // defined as LDAP filters // // prepare some data we'll need $filters = array(); $institutionid = get_config('local_ent_installer', 'institution_id'); // Students. if (empty($options['role']) || preg_match('/eleve/', $options['role'])) { $filterdef = new StdClass(); $filterdef->institution = '(ENTPersonEtablissements=' . $institutionid . ')'; $filterdef->usertype = '(ENTPersonProfils=Eleves)'; $filterdef->userfield = 'eleve'; $filters[] = $filterdef; } // Teaching staff. if (empty($options['role']) || preg_match('/enseignant/', $options['role'])) { $filterdef = new StdClass(); $filterdef->institution = '(ENTPersonEtablissements=' . $institutionid . ')'; $filterdef->usertype = '(|(ENTPersonProfils=Professeurs)(ENTPersonProfils=Documentalistes)(ENTPersonProfils=ProfesseursVacataires)(ENTPersonProfils=Inspecteur))'; $filterdef->userfield = 'enseignant'; $filters[] = $filterdef; } // Non teaching staff. if (empty($options['role']) || preg_match('/administration/', $options['role'])) { $filterdef = new StdClass(); $filterdef->institution = '(ENTPersonEtablissements=' . $institutionid . ')'; $filterdef->usertype = '(|(ENTPersonProfils=Administrateurs)(ENTPersonProfils=Direction)(ENTPersonProfils=PersonnelAdministratif)(ENTPersonProfils=PersonnelNonEnseignant)' . '(ENTPersonProfils=AdministrateurITOP)(ENTPersonProfils=PersonnelVieScolaire)(ENTPersonProfils=ATOS)(ENTPersonProfils=PersonnelRectorat)(ENTPersonProfils=MissionTice)' . '(ENTPersonProfils=TuteurEntreprise)(ENTPersonProfils=CollectivitesLocales)(ENTPersonProfils=AccompagnementEducatif)(ENTPersonProfils=CPE)(ENTPersonProfils=Invite)' . '(ENTPersonProfils=AdminProjet))'; $filterdef->userfield = 'administration'; $filters[] = $filterdef; } $contexts = explode(';', $ldapauth->config->contexts); if (!empty($ldapauth->config->create_context)) { array_push($contexts, $ldapauth->config->create_context); } $ldap_pagedresults = ldap_paged_results_supported($ldapauth->config->ldap_version); $ldap_cookie = ''; foreach ($filters as $filterdef) { $filter = '(&(' . $ldapauth->config->user_attribute . '=*)' . $filterdef->usertype . $filterdef->institution . ')'; foreach ($contexts as $context) { $context = trim($context); if (empty($context)) { continue; } do { if ($ldap_pagedresults) { ldap_control_paged_result($ldapconnection, $ldapauth->config->pagesize, true, $ldap_cookie); } if ($ldapauth->config->search_sub) { // Use ldap_search to find first user from subtree. mtrace("ldapsearch {$context}, {$filter} for " . $ldapauth->config->user_attribute); $ldap_result = ldap_search($ldapconnection, $context, $filter, array($ldapauth->config->user_attribute, 'whenChanged')); } else { // Search only in this context. mtrace("ldaplist {$context}, {$filter} for " . $ldapauth->config->user_attribute); $ldap_result = ldap_list($ldapconnection, $context, $filter, array($ldapauth->config->user_attribute, 'whenChanged')); } if (!$ldap_result) { continue; } if ($ldap_pagedresults) { ldap_control_paged_result_response($ldapconnection, $ldap_result, $ldap_cookie); } if ($entry = @ldap_first_entry($ldapconnection, $ldap_result)) { do { $value = ldap_get_values_len($ldapconnection, $entry, $ldapauth->config->user_attribute); $value = core_text::convert($value[0], $ldapauth->config->ldapencoding, 'utf-8'); $modify = ldap_get_values_len($ldapconnection, $entry, 'whenChanged'); // $modify = strtotime($modify[0]); // OpenLDAP version if (preg_match('/(\\d{4})(\\d{2})(\\d{2})(\\d{2})(\\d{2})(\\d{2})/', $modify[0], $matches)) { $year = $matches[1]; $month = $matches[2]; $day = $matches[3]; $hour = $matches[4]; $min = $matches[5]; $sec = $matches[6]; $modify = mktime($hour, $min, $sec, $month, $day, $year); } else { $modify = time(); } local_ent_installer_ldap_bulk_insert($value, $filterdef->userfield, $modify); } while ($entry = ldap_next_entry($ldapconnection, $entry)); } unset($ldap_result); // Free mem. } while ($ldap_pagedresults && !empty($ldap_cookie)); } } /* * If LDAP paged results were used, the current connection must be completely * closed and a new one created, to work without paged results from here on. */ if ($ldap_pagedresults) { $ldapauth->ldap_close(true); $ldapconnection = $ldapauth->ldap_connect(); } /* * preserve our user database * if the temp table is empty, it probably means that something went wrong, exit * so as to avoid mass deletion of users; which is hard to undo */ $count = $DB->count_records_sql('SELECT COUNT(username) AS count, 1 FROM {tmp_extuser}'); if ($count < 1) { mtrace(get_string('didntgetusersfromldap', 'auth_ldap')); $dbman->drop_table($table); $ldapauth->ldap_close(true); return false; } else { mtrace(get_string('gotcountrecordsfromldap', 'auth_ldap', $count)); } /********************** User removal. *****************************/ /* * Find users in DB that aren't in ldap -- to be removed! * this is still not as scalable (but how often do we mass delete?) */ if ($ldapauth->config->removeuser != AUTH_REMOVEUSER_KEEP) { $sql = ' SELECT u.* FROM {user} u LEFT JOIN {tmp_extuser} e ON (u.username = e.username AND u.mnethostid = e.mnethostid) WHERE u.auth = ? AND u.deleted = 0 AND e.username IS NULL '; $real_user_auth = get_config('local_ent_installer', 'real_used_auth'); $remove_users = $DB->get_records_sql($sql, array($real_user_auth)); if (!empty($remove_users)) { mtrace(get_string('userentriestoremove', 'auth_ldap', count($remove_users))); foreach ($remove_users as $user) { if ($ldapauth->config->removeuser == AUTH_REMOVEUSER_FULLDELETE) { if (empty($options['simulate'])) { if (empty($options['fulldelete'])) { // Make a light delete of users, but keeping data for revival. $user->deleted = 1; try { $DB->update_record('user', $user); // Subscription does not work if it contains a user marked as deleted $DB->delete_records('cohort_members', array('userid' => $user->id)); mtrace(get_string('auth_dbdeleteuser', 'auth_db', array('name' => $user->username, 'id' => $user->id))); } catch (Exception $e) { mtrace(get_string('auth_dbdeleteusererror', 'auth_db', $user->username)); } } else { // Make a complete delete of users, enrols, grades and data if (delete_user($user)) { echo "\t"; mtrace(get_string('auth_dbdeleteuser', 'auth_db', array('name' => $user->username, 'id' => $user->id))); } else { echo "\t"; mtrace(get_string('auth_dbdeleteusererror', 'auth_db', $user->username)); } } } else { mtrace(get_string('simulateuserdelete', 'ent_installer', $user->username)); } } elseif ($ldapauth->config->removeuser == AUTH_REMOVEUSER_SUSPEND) { if (empty($options['simulate'])) { $updateuser = new stdClass(); $updateuser->id = $user->id; $updateuser->auth = 'nologin'; $DB->update_record('user', $updateuser); echo "\t"; mtrace(get_string('auth_dbsuspenduser', 'auth_db', array('name' => $user->username, 'id' => $user->id))); $euser = $DB->get_record('user', array('id' => $user->id)); //events_trigger('user_updated', $euser); => deprecated ! $event = core\event\user_updated::create_from_userid($euser->id); $event->trigger(); } else { mtrace(get_string('simulateusersuspend', 'ent_installer', $user->username)); } } } } else { mtrace(get_string('nouserentriestoremove', 'auth_ldap')); } unset($remove_users); // free mem! } else { mtrace("AUTH_REMOVEUSER_KEEP is on or ldapauth config removeuser is off"); } /********************* Revive suspended users. *********************************/ if (!empty($ldapauth->config->removeuser) && $ldapauth->config->removeuser == AUTH_REMOVEUSER_SUSPEND) { $sql = "\n SELECT\n u.id, u.username\n FROM\n {user} u\n JOIN\n {tmp_extuser} e\n ON\n (u.username = e.username AND u.mnethostid = e.mnethostid)\n WHERE\n u.auth = 'nologin' AND u.deleted = 0\n "; $revive_users = $DB->get_records_sql($sql); if (!empty($revive_users)) { mtrace(get_string('userentriestorevive', 'auth_ldap', count($revive_users))); foreach ($revive_users as $user) { $updateuser = new stdClass(); $updateuser->id = $user->id; $updateuser->auth = $ldapauth->authtype; $DB->update_record('user', $updateuser); echo "\t"; mtrace(get_string('auth_dbreviveduser', 'auth_db', array('name' => $user->username, 'id' => $user->id))); $euser = $DB->get_record('user', array('id' => $user->id)); //events_trigger('user_updated', $euser); => deprecated ! $event = core\event\user_updated::create_from_userid($euser->id); $event->trigger(); } } else { mtrace(get_string('nouserentriestorevive', 'auth_ldap')); } unset($revive_users); } /****************************** User Updates - time-consuming (optional). ***************************/ // This might be an OBSOLETE code, regarding the updat ecapability of the create process. if (!empty($options['doupdates'])) { // Narrow down what fields we need to update. $all_keys = array_keys(get_object_vars($ldapauth->config)); $updatekeys = array(); foreach ($all_keys as $key) { if (preg_match('/^field_updatelocal_(.+)$/', $key, $match)) { /* * If we have a field to update it from * and it must be updated 'onlogin' we * update it on cron */ if (!empty($ldapauth->config->{'field_map_' . $match[1]}) && $ldapauth->config->{$match[0]} === 'onlogin') { // The actual key name. array_push($updatekeys, $match[1]); } } } unset($all_keys); unset($key); } else { mtrace(get_string('noupdatestobedone', 'auth_ldap')); } if (@$options['doupdates'] and !empty($updatekeys)) { // Run updates only if relevant. $users = $DB->get_records_sql('SELECT u.username, u.id FROM {user} u WHERE u.deleted = 0 AND u.auth = ? AND u.mnethostid = ?', array($ldapauth->authtype, $CFG->mnet_localhost_id)); if (!empty($users)) { mtrace(get_string('userentriestoupdate', 'auth_ldap', count($users))); $sitecontext = context_system::instance(); if (!empty($ldapauth->config->creators) and !empty($ldapauth->config->memberattribute) && ($roles = get_archetype_roles('coursecreator'))) { // We can only use one, let's use the first one. $creatorrole = array_shift($roles); } else { $creatorrole = false; } $transaction = $DB->start_delegated_transaction(); $xcount = 0; $maxxcount = 100; foreach ($users as $user) { echo "\t"; $tracestr = get_string('auth_dbupdatinguser', 'auth_db', array('name' => $user->username, 'id' => $user->id)); if (!$ldapauth->update_user_record($user->username, $updatekeys)) { $tracestr .= ' - ' . get_string('skipped'); } mtrace($tracestr); $xcount++; // Update course creators if needed. if ($creatorrole !== false) { if ($ldapauth->iscreator($user->username)) { role_assign($creatorrole->id, $user->id, $sitecontext->id, $ldapauth->roleauth); } else { role_unassign($creatorrole->id, $user->id, $sitecontext->id, $ldapauth->roleauth); } } } $transaction->allow_commit(); unset($users); // free mem } } else { // End do updates. mtrace(get_string('noupdatestobedone', 'auth_ldap')); } /***************************** User Additions or full profile update. **********************************/ /* * Find users missing in DB that are in LDAP or users that have been modified since last run * and gives me a nifty object I don't want. * note: we do not care about deleted accounts anymore, this feature was replaced by suspending to nologin auth plugin */ if (empty($options['force'])) { $sql = 'SELECT e.id, e.username, e.usertype FROM {tmp_extuser} e LEFT JOIN {user} u ON (e.username = u.username AND e.mnethostid = u.mnethostid) WHERE u.id IS NULL OR ( e.lastmodified > ? ) ORDER BY e.username'; $params = array($lastrun); } else { $sql = 'SELECT e.id, e.username, e.usertype FROM {tmp_extuser} e ORDER BY e.username'; $params = array(); } $add_users = $DB->get_records_sql($sql, $params); if (!empty($add_users)) { mtrace(get_string('userentriestoadd', 'auth_ldap', count($add_users))); $sitecontext = context_system::instance(); if (!empty($ldapauth->config->creators) && !empty($ldapauth->config->memberattribute) && ($roles = get_archetype_roles('coursecreator'))) { // We can only use one, let's use the first one. $creatorrole = array_shift($roles); } else { $creatorrole = false; } $inserterrorcount = 0; $updateerrorcount = 0; $insertcount = 0; $updatecount = 0; // Before processing each user we check that every common hosts access keys fields are correctly set up if (file_exists($CFG->dirroot . '/blocks/user_mnet_hosts/locallib.php')) { require_once $CFG->dirroot . '/blocks/user_mnet_hosts/locallib.php'; $like = $DB->sql_like('wwwroot', ':wwwroot', false, false); $mainhosts = explode(',', @$CFG->mainhostprefix); if (!empty($mainhosts)) { foreach ($mainhosts as $hostwww) { // Check if common hosts exist if ($commonroots = $DB->get_records_select('mnet_host', " {$like} AND deleted <> 1 ", array('wwwroot' => $hostwww . '%'))) { foreach ($commonroots as $root) { // Check if current common host access key field exists, if not create one $expectedname = user_mnet_hosts_make_accesskey($root->wwwroot, true); $accessmainhost = $DB->get_records('user_info_field', array('shortname' => $expectedname), '', 'id'); if (!$accessmainhost) { mtrace("Common host access key '{$expectedname}' not found"); if (!isset($CFG->accesscategory)) { $accesscategory = new stdClass(); $accesscategory->name = get_string('accesscategory', 'block_user_mnet_hosts'); $accesscategory->sortorder = 1; $id = $DB->insert_record('user_info_category', $accesscategory); set_config('accesscategory', $id); } $hostkey = user_mnet_hosts_make_accesskey($root->wwwroot, false); $newfield = new stdClass(); $newfield->shortname = $expectedname; $newfield->name = get_string('fieldname', 'block_user_mnet_hosts') . ' ' . $hostkey; $newfield->datatype = 'checkbox'; $newfield->locked = 1; $newfield->categoryid = $CFG->accesscategory; if ($DB->insert_record('user_info_field', $newfield)) { mtrace("Common host access key created : {$expectedname}"); } else { mtrace("Common host access key creation error : {$expectedname}"); } } } } } } } // Before processing each user we check that custom field to store ENT profil & guid are correctly set up $infoscateg = $DB->get_records('user_info_category', array('name' => 'Informations académiques'), '', 'id'); if (!empty($infoscateg)) { $infoscateg = array_values($infoscateg); $idinfocateg = $infoscateg[0]->id; $profilent = $DB->get_records('user_info_field', array('shortname' => 'profilent'), '', 'id'); if (empty($profilent)) { $maxsortorder = $DB->get_records_sql('SELECT MAX(sortorder) AS maxsortorder FROM {user_info_field} WHERE categoryid = ?', array($idinfocateg)); $maxsortorder = array_values($maxsortorder); $sortordertoinsert = $maxsortorder[0]->maxsortorder + 1; $user_info_field = new stdClass(); $user_info_field->shortname = 'profilent'; $user_info_field->name = 'Profil ENT'; $user_info_field->datatype = 'text'; $user_info_field->description = '<p>Les profils ENT sont utilisés pour traitements spécifiques post-synchronisation et proviennent du champ ENTPersonProfils du SDET<br></p>'; $user_info_field->descriptionformat = 1; $user_info_field->categoryid = $idinfocateg; $user_info_field->sortorder = $sortordertoinsert; $user_info_field->required = 0; $user_info_field->locked = 1; $user_info_field->visible = 0; $user_info_field->forceunique = 0; $user_info_field->signup = 0; $user_info_field->defaultdata = ''; $user_info_field->defaultdataformat = 0; $user_info_field->param1 = '30'; $user_info_field->param2 = '2048'; $user_info_field->param3 = '0'; $user_info_field->param4 = ''; $user_info_field->param5 = ''; $fieldid = $DB->insert_record('user_info_field', $user_info_field); mtrace("user_info_field : 'profilent' inserted !"); if ($USERFIELDS['profilent'] == 0 && $fieldid != 0) { $USERFIELDS['profilent'] = $fieldid; } else { mtrace("user_info_field : cannot get id for 'profilent' !"); } } $guident = $DB->get_records('user_info_field', array('shortname' => 'guident'), '', 'id'); if (empty($guident)) { $maxsortorder = $DB->get_records_sql('SELECT MAX(sortorder) AS maxsortorder FROM {user_info_field} WHERE categoryid = ?', array($idinfocateg)); $maxsortorder = array_values($maxsortorder); $sortordertoinsert = $maxsortorder[0]->maxsortorder + 1; $user_info_field = new stdClass(); $user_info_field->shortname = 'guident'; $user_info_field->name = 'Guid ENT'; $user_info_field->datatype = 'text'; $user_info_field->description = '<p><p>Le GUID ENT est utilisé pour la synchronisation des comptes et provient du champ AD objectGuid<br></p></p>'; $user_info_field->descriptionformat = 1; $user_info_field->categoryid = $idinfocateg; $user_info_field->sortorder = $sortordertoinsert; $user_info_field->required = 0; $user_info_field->locked = 1; $user_info_field->visible = 0; $user_info_field->forceunique = 0; $user_info_field->signup = 0; $user_info_field->defaultdata = ''; $user_info_field->defaultdataformat = 0; $user_info_field->param1 = '36'; $user_info_field->param2 = '2048'; $user_info_field->param3 = '0'; $user_info_field->param4 = ''; $user_info_field->param5 = ''; $fieldid = $DB->insert_record('user_info_field', $user_info_field); mtrace("user_info_field : 'guident' inserted !"); if ($USERFIELDS['guident'] == 0 && $fieldid != 0) { $USERFIELDS['guident'] = $fieldid; } else { mtrace("user_info_field : cannot get id for 'guident' !"); } } } else { mtrace("user_info_category : 'Informations académiques' missing !"); } // We scan new proposed users from LDAP. foreach ($add_users as $user) { // Save usertype. $usertype = $user->usertype; $user = local_ent_installer_get_userinfo_asobj($ldapauth, $user->username, $options); // Restore usertype in user. $user->usertype = $usertype; // Post filter of idnumber list($foosdetprefix, $user->idnumber) = explode('$', $user->idnumber); if (empty($user->firstname)) { mtrace('ERROR : Missing firstname in incoming record ' . $user->username); $updateerrorcount++; continue; } if (empty($user->lastname)) { mtrace('ERROR : Missing lastname in incoming record ' . $user->username); $updateerrorcount++; continue; } if (empty($user->email)) { $user->email = local_ent_installer_generate_email($user); } // Prep a few params. $user->modified = time(); $user->confirmed = 1; $user->deleted = 0; $user->suspended = 0; // Authentication is the ldap plugin or a real auth plugin defined in setup. $realauth = get_config('local_ent_installer', 'real_used_auth'); $user->auth = empty($realauth) ? $ldapauth->authtype : $realauth; $user->mnethostid = $CFG->mnet_localhost_id; $user->country = $CFG->country; /* * Get_userinfo_asobj() might have replaced $user->username with the value. * from the LDAP server (which can be mixed-case). Make sure it's lowercase */ $user->username = trim(core_text::strtolower($user->username)); if (empty($user->lang)) { $user->lang = $CFG->lang; } /* * Process additional info for student : * extra information fields transport and regime. */ if ($user->usertype == 'eleve') { // Transport. $user->profile_field_transport = 'Y' == @$user->ENTEleveTransport ? '1' : 0; // Regime. $user->profile_field_regime = @$user->ENTEleveRegime; // Cohort (must have). $user->profile_field_cohort = $user->ENTEleveClasses; } // Profil ENT $user->profile_field_profil = $user->ENTPersonProfils; // Guid ENT $user->profile_field_guid = $user->objectGUID; $personfunction = @$user->ENTPersonFonctions; unset($user->ENTPersonFonctions); // Get the last term of personfunction and set it as department. if (!empty($personfunction)) { preg_match('/\\$([^\\$]+)$/', $personfunction, $matches); $user->department = $matches[1]; } if (empty($options['simulate'])) { // Creation/full update sequence. $a = clone $user; $a->function = $personfunction; /* * Special case : si there a matching policy possible for previous accounts NOT being * created by this system ? */ try { $oldrec = local_ent_installer_guess_old_record($user, $status); } catch (Exception $e) { mtrace('ERROR : Fail to bind user ' . $user->username); if ($options['verbose']) { trace_debug($e); } $inserterrorcount++; continue; } if ($oldrec) { $a->status = $MATCH_STATUS[$status]; $id = $user->id = $oldrec->id; try { $DB->update_record('user', $user); mtrace(get_string('dbupdateuser', 'local_ent_installer', $a)); $updatecount++; } catch (Exception $e) { mtrace('ERROR : Fail to update user ' . $user->username); if ($options['verbose']) { trace_debug($e); } $updateerrorcount++; continue; } } else { try { $id = $DB->insert_record('user', $user); mtrace(get_string('dbinsertuser', 'local_ent_installer', $a)); $insertcount++; } catch (Exception $e) { mtrace('ERROR : Fail to insert user ' . $user->username); if ($options['verbose']) { trace_debug($e); } $inserterrorcount++; continue; } } } else { $a = clone $user; $a->function = $personfunction; if (!($oldrec = local_ent_installer_guess_old_record($user, $status))) { mtrace(get_string('dbinsertusersimul', 'local_ent_installer', $a)); } else { $a->status = $MATCH_STATUS[$status]; mtrace(get_string('dbupdateusersimul', 'local_ent_installer', $a)); } } if (empty($options['simulate'])) { $euser = $DB->get_record('user', array('id' => $id)); //events_trigger('user_created', $euser); => deprecated ! $event = core\event\user_created::create_from_userid($euser->id); $event->trigger(); if (!empty($ldapauth->config->forcechangepassword)) { set_user_preference('auth_forcepasswordchange', 1, $id); } // Cohort information / create/update cohorts. if ($user->usertype == 'eleve') { // Adds user to cohort and create cohort if missing. $cohortshort = local_ent_installer_check_cohort($id, $user->profile_field_cohort); local_ent_installer_update_info_data($id, $USERFIELDS['transport'], $user->profile_field_transport); local_ent_installer_update_info_data($id, $USERFIELDS['regime'], $user->profile_field_regime); local_ent_installer_update_info_data($id, $USERFIELDS['cohort'], $cohortshort); if (isset($user->ENTEleveGroupes) && count($user->ENTEleveGroupes) > 0) { foreach ($user->ENTEleveGroupes as $group) { $cohortshort = local_ent_installer_check_cohort($id, $group, false, $options['verbose']); } } } // Create profil cohort to allow enrollment by profil $cohortshort = local_ent_installer_check_cohort($id, $user->profile_field_profil, false, $options['verbose']); if ($user->profile_field_profil == 'Administrateurs') { if (isset($id)) { $managerrole = $DB->get_record('role', array('shortname' => 'manager')); role_assign($managerrole->id, $id, 1); // 1=system context } else { mtrace('WARNING : Cannot assign role manager to ' . $user->username); } } local_ent_installer_update_info_data($id, $USERFIELDS['profilent'], $user->profile_field_profil); local_ent_installer_update_info_data($id, $USERFIELDS['guident'], $user->profile_field_guid); // Add course creators if needed. if ($creatorrole !== false and $ldapauth->iscreator($user->username)) { role_assign($creatorrole->id, $id, $sitecontext->id, $ldapauth->roleauth); } // Process user_fields setup. if (preg_match('#\\$CTR\\$#', $personfunction)) { // Special case. local_ent_installer_update_info_data($id, $USERFIELDS['cdt'], 1); } else { // Other user types. local_ent_installer_update_info_data($id, $USERFIELDS[$user->usertype], 1); } if (file_exists($CFG->dirroot . '/blocks/user_mnet_hosts/locallib.php')) { // user_mnet_hosts local library has already been included upstream of this script // All users have access marked on self. user_mnet_hosts_set_access($id, true); // Setting default access field policy for powered users. if ($user->usertype == 'enseignant' || $user->usertype == 'administration') { $like = $DB->sql_like('wwwroot', ':wwwroot', false, false); $mainhosts = explode(',', @$CFG->mainhostprefix); $given = false; if (!empty($mainhosts)) { foreach ($mainhosts as $hostwww) { if ($commonroots = $DB->get_records_select('mnet_host', " {$like} AND deleted <> 1 ", array('wwwroot' => $hostwww . '%'))) { foreach ($commonroots as $root) { $given = true; user_mnet_hosts_set_access($id, true, $root->wwwroot); } } } } if (!$given) { mtrace('Giving teacher access : no common host found '); } } } // Add a workplace to teachers. if ($user->usertype == 'enseignant') { if (get_config('local_ent_installer', 'build_teacher_category')) { if (isset($options['unassignteachercategoryrole'])) { local_ent_installer_make_teacher_category($euser, $options['unassignteachercategoryrole']); } else { local_ent_installer_make_teacher_category($euser); } } } // Identify librarians and give library enabled role at system level. if (preg_match('#\\$DOC\\$#', $personfunction)) { if ($role = $DB->get_record('role', array('shortname' => 'librarian'))) { $systemcontext = context_system::instance(); role_assign($role->id, $id, $systemcontext->id); } } } } unset($add_users); // free mem } else { mtrace(get_string('nouserstobeadded', 'auth_ldap')); } $ldapauth->ldap_close(); list($usec, $sec) = explode(' ', microtime()); $stoptick = (double) $sec + (double) $usec; $deltatime = $stoptick - $starttick; mtrace('Execution time : ' . $deltatime); $benchrec = new StdClass(); $benchrec->timestart = floor($starttick); $benchrec->timerun = ceil($deltatime); $benchrec->added = 0 + @$insertcount; $benchrec->updated = 0 + @$updatecount; $benchrec->updateerrors = 0 + @$inserterrorcount; $benchrec->inserterrors = 0 + @$updateerrorcount; $DB->insert_record('local_ent_installer', $benchrec); // Mark last time the user sync was run. set_config('last_sync_date', time(), 'local_ent_installer'); try { $dbman->drop_table($table); } catch (Exception $e) { } return true; }