/** * This function returns the current language to use, either for a given user * or sitewide, or the default. * * This method is invoked in every call to get_string(), so make it performant! * * @return string */ function current_language() { global $USER, $CFG, $SESSION; static $userlang, $lastlang, $instlang; $loggedin = $USER instanceof User && $USER->is_logged_in(); // Retrieve & cache the user lang pref (if the user is logged in) if (!isset($userlang) && $loggedin) { $userlang = $USER->get_account_preference('lang'); if ($userlang !== null && $userlang != 'default') { if (!language_installed($userlang)) { $USER->set_account_preference('lang', 'default'); $userlang = 'default'; } } } // Retrieve & cache the institution language (if the user is logged in) if (!isset($instlang) && $loggedin) { $instlang = get_user_institution_language(); } // Retrieve the $SESSION lang (from the user selecting a language while logged-out) // Note that if the user selected a language while logged out, and then logs in, // we will have set their user account pref to match that lang, over in // LiveUser->authenticate(). if (!$loggedin && is_a($SESSION, 'Session')) { $sesslang = $SESSION->get('lang'); } else { $sesslang = null; } // Logged-in user's language preference if (!empty($userlang) && $userlang != 'default') { $lang = $userlang; } else { if (!empty($sesslang) && $sesslang != 'default') { $lang = $sesslang; } else { if (!empty($instlang) && $instlang != 'default') { $lang = $instlang; } } } // If there's no language from the user pref or the logged-out lang menu... if (empty($lang)) { $lang = !empty($CFG->lang) ? $CFG->lang : 'en.utf8'; } if ($lang == $lastlang) { return $lang; } set_locale_for_language($lang); return $lastlang = $lang; }
function regenerateurls_submit(Pieform $form, $values) { global $SESSION, $USER; require_once 'upgrade.php'; log_debug("Regenerating clean urls..."); db_begin(); // Checking duplicates one by one is too slow, so drop the index, // generate the urlids in big chunks, remove duplicates in one hit, // recreate the index. // Users: set urlid based on username. $table = new XMLDBTable('usr'); $index = new XMLDBIndex('urliduk'); $index->setAttributes(XMLDB_INDEX_UNIQUE, array('urlid')); drop_index($table, $index); execute_sql('UPDATE {usr} SET urlid = NULL WHERE NOT urlid IS NULL'); $usrcount = count_records_select('usr', 'deleted = 0 AND id > 0'); $sql = 'SELECT id, username FROM {usr} WHERE id > ? AND deleted = 0 ORDER BY id'; $done = 0; $lastid = 0; $limit = 1000; while ($records = get_records_sql_array($sql, array($lastid), 0, $limit)) { $firstid = $lastid; $values = array(); foreach ($records as $r) { $r->urlid = generate_urlid($r->username, get_config('cleanurluserdefault'), 3, 30); array_push($values, $r->id, $r->urlid); $lastid = $r->id; } $updatesql = "UPDATE {usr} SET urlid = CASE id\n "; $updatesql .= join("\n ", array_fill(0, count($records), 'WHEN ? THEN ?')); $updatesql .= "\n ELSE NULL\n END WHERE id > ? AND id <= ? AND deleted = 0"; array_push($values, $firstid, $lastid); execute_sql($updatesql, $values); $done += count($records); log_debug("Generating user urls: {$done}/{$usrcount}"); } // Fix any duplicates created above $dupurls = get_records_sql_array(' SELECT id, urlid FROM {usr} WHERE urlid IN ( SELECT urlid FROM {usr} WHERE id > 0 AND deleted = 0 GROUP BY urlid HAVING COUNT(id) > 1 ) ORDER BY urlid, id', array()); $last = null; if ($dupurls) { log_debug('Fixing ' . count($dupurls) . ' duplicate user urls'); $ids = array(); $values = array(); for ($i = 0; $i < count($dupurls); $i++) { if ($dupurls[$i]->urlid != $last) { // The first user with this name can keep it, but get all the taken urlids that are similar // so we can check against them when appending digits below. $taken = get_column_sql("SELECT urlid FROM {usr} WHERE urlid LIKE ?", array(substr($dupurls[$i]->urlid, 0, 24) . '%')); } else { // Subsequent users need digits appended, while keeping the max length at 30 $suffix = 1; $try = substr($dupurls[$i]->urlid, 0, 28) . '-1'; while (in_array($try, $taken)) { $suffix++; $try = substr($dupurls[$i]->urlid, 0, 29 - strlen($suffix)) . '-' . $suffix; } $taken[] = $try; $ids[] = $dupurls[$i]->id; array_push($values, $dupurls[$i]->id, $try); } $last = $dupurls[$i]->urlid; } $updatesql = "UPDATE {usr} SET urlid = CASE id\n "; $updatesql .= join("\n ", array_fill(0, count($values) / 2, 'WHEN ? THEN ?')); $updatesql .= "\n ELSE urlid\n END\n WHERE id IN ("; $updatesql .= join(',', array_fill(0, count($ids), '?')); $updatesql .= ')'; $values = array_merge($values, $ids); execute_sql($updatesql, $values); } $table = new XMLDBTable('usr'); $index = new XMLDBIndex('urliduk'); $index->setAttributes(XMLDB_INDEX_UNIQUE, array('urlid')); add_index($table, $index); // Groups: set urlid based on group name execute_sql('UPDATE {group} SET urlid = NULL'); $table = new XMLDBTable('group'); $index = new XMLDBIndex('urliduk'); $index->setAttributes(XMLDB_INDEX_UNIQUE, array('urlid')); drop_index($table, $index); // Transliteration using iconv is bad if locale is set to C, so set it based on // the site language. $lang = $sitelang = get_config('lang'); set_locale_for_language($lang); $groupcount = count_records('group', 'deleted', 0); $sql = 'SELECT id, name FROM {group} WHERE deleted = 0 AND id > ? ORDER BY id'; $done = 0; $lastid = 0; $limit = 1000; while ($records = get_records_sql_array($sql, array($lastid), 0, $limit)) { $firstid = $lastid; $values = array(); foreach ($records as $r) { $r->urlid = generate_urlid($r->name, get_config('cleanurlgroupdefault'), 3, 30); array_push($values, $r->id, $r->urlid); $lastid = $r->id; } $updatesql = "UPDATE {group} SET urlid = CASE id\n "; $updatesql .= join("\n ", array_fill(0, count($records), 'WHEN ? THEN ?')); $updatesql .= "\n ELSE NULL\n END WHERE id > ? AND id <= ? AND deleted = 0"; array_push($values, $firstid, $lastid); execute_sql($updatesql, $values); $done += count($records); log_debug("Generating group urls: {$done}/{$groupcount}"); } // Fix duplicates... $dupurls = get_records_sql_array(' SELECT id, urlid FROM {group} WHERE urlid IN ( SELECT urlid FROM {group} WHERE id > 0 AND deleted = 0 GROUP BY urlid HAVING COUNT(id) > 1 ) ORDER BY urlid, id', array()); $last = null; if ($dupurls) { log_debug('Fixing ' . count($dupurls) . ' duplicate group urls'); $ids = array(); $values = array(); for ($i = 0; $i < count($dupurls); $i++) { if ($dupurls[$i]->urlid != $last) { // The first group with this name can keep it, get similar group urls $taken = get_column_sql("SELECT urlid FROM {group} WHERE urlid LIKE ?", array(substr($dupurls[$i]->urlid, 0, 24) . '%')); } else { // Append digits while keeping the max length at 30 $suffix = 1; $try = substr($dupurls[$i]->urlid, 0, 28) . '-1'; while (in_array($try, $taken)) { $suffix++; $try = substr($dupurls[$i]->urlid, 0, 29 - strlen($suffix)) . '-' . $suffix; } $taken[] = $try; $ids[] = $dupurls[$i]->id; array_push($values, $dupurls[$i]->id, $try); } $last = $dupurls[$i]->urlid; } $updatesql = "UPDATE {group} SET urlid = CASE id\n "; $updatesql .= join("\n ", array_fill(0, count($values) / 2, 'WHEN ? THEN ?')); $updatesql .= "\n ELSE urlid\n END\n WHERE id IN ("; $updatesql .= join(',', array_fill(0, count($ids), '?')); $updatesql .= ')'; $values = array_merge($values, $ids); execute_sql($updatesql, $values); } $table = new XMLDBTable('group'); $index = new XMLDBIndex('urliduk'); $index->setAttributes(XMLDB_INDEX_UNIQUE, array('urlid')); add_index($table, $index); // Views: set urlid based on view title. Only portfolio views need urlids, and they // only need to be unique when they're owned by the same entity. // The iconv utf8 conversion gives better results if we set the locale based on the // user's language preference, so these are pulled from the db when appropriate. execute_sql('UPDATE {view} SET urlid = NULL'); $table = new XMLDBTable('view'); $index = new XMLDBIndex('urliduk'); $index->setAttributes(XMLDB_INDEX_UNIQUE, array('urlid', 'owner', 'group', 'institution')); drop_index($table, $index); $viewcount = count_records('view', 'type', 'portfolio'); $sql = "\n SELECT v.id, v.title, ap.value AS lang\n FROM {view} v LEFT JOIN {usr_account_preference} ap ON ap.usr = v.owner AND ap.field = 'lang'\n WHERE v.id > ? AND v.type = 'portfolio'\n ORDER BY v.id"; $done = 0; $lastid = 0; $limit = 1000; while ($records = get_records_sql_array($sql, array($lastid), 0, $limit)) { $firstid = $lastid; $values = array(); foreach ($records as $r) { if (empty($r->lang) || $r->lang == 'default') { $r->lang = $sitelang; } if ($lang != $r->lang) { set_locale_for_language($r->lang); $lang = $r->lang; } $r->urlid = generate_urlid($r->title, get_config('cleanurlviewdefault'), 3, 100); array_push($values, $r->id, $r->urlid); $lastid = $r->id; } $updatesql = "UPDATE {view} SET urlid = CASE id\n "; $updatesql .= join("\n ", array_fill(0, count($records), 'WHEN ? THEN ?')); $updatesql .= "\n ELSE NULL\n END WHERE id > ? AND id <= ?"; array_push($values, $firstid, $lastid); execute_sql($updatesql, $values); $done += count($records); log_debug("Generating page urls: {$done}/{$viewcount}"); } // Reset locale set_locale_for_language($sitelang); // Fix duplicates with the same owner, group, or institution $dupurls = get_records_sql_array("\n SELECT\n v.id, dv.urlid, dv.owner, dv.group, dv.institution\n FROM\n {view} v,\n (SELECT d.urlid, d.owner, d.group, d.institution\n FROM {view} d\n WHERE d.type = 'portfolio'\n GROUP BY d.urlid, d.owner, d.group, d.institution\n HAVING COUNT(d.id) > 1) dv\n WHERE\n v.type = 'portfolio'\n AND v.urlid = dv.urlid\n AND (v.owner = dv.owner OR (v.owner IS NULL AND dv.owner IS NULL))\n AND (v.group = dv.group OR (v.group IS NULL AND dv.group IS NULL))\n AND (v.institution = dv.institution OR (v.institution IS NULL AND dv.institution IS NULL))\n ORDER BY\n dv.urlid, dv.owner, dv.group, dv.institution, v.id", array()); $last = array('urlid' => null, 'owner' => null, 'group' => null, 'institution' => null); if ($dupurls) { log_debug('Fixing ' . count($dupurls) . ' duplicate page urls'); $ids = array(); $values = array(); for ($i = 0; $i < count($dupurls); $i++) { $hasdupes = clone $dupurls[$i]; unset($hasdupes->id); if ($hasdupes != $last) { // The first view with this name can keep it // Get similar view names to check uniqueness when appending digits if (!is_null($hasdupes->owner)) { $ownersql = 'owner = ?'; $ownervalue = $hasdupes->owner; } else { if (!is_null($hasdupes->group)) { $ownersql = 'group = ?'; $ownervalue = $hasdupes->group; } else { if (!is_null($hasdupes->institution)) { $ownersql = 'institution = ?'; $ownervalue = $hasdupes->institution; } } } $taken = get_column_sql('SELECT urlid FROM {view} v WHERE urlid LIKE ? AND v.' . $ownersql, array(substr($dupurls[$i]->urlid, 0, 94), $ownervalue)); } else { // Subsequent views with this name need digits appended, keeping max length at 100 $suffix = 1; $try = substr($dupurls[$i]->urlid, 0, 98) . '-1'; while (in_array($try, $taken)) { $suffix++; $try = substr($dupurls[$i]->urlid, 0, 99 - strlen($suffix)) . '-' . $suffix; } $taken[] = $try; $ids[] = $dupurls[$i]->id; array_push($values, $dupurls[$i]->id, $try); } $last = $hasdupes; } $updatesql = "UPDATE {view} SET urlid = CASE id\n "; $updatesql .= join("\n ", array_fill(0, count($values) / 2, 'WHEN ? THEN ?')); $updatesql .= "\n ELSE urlid\n END\n WHERE id IN ("; $updatesql .= join(',', array_fill(0, count($ids), '?')); $updatesql .= ')'; $values = array_merge($values, $ids); execute_sql($updatesql, $values); } $table = new XMLDBTable('view'); $index = new XMLDBIndex('urliduk'); $index->setAttributes(XMLDB_INDEX_UNIQUE, array('urlid', 'owner', 'group', 'institution')); add_index($table, $index); // Reset in the session for this user - currently logged-in users may end up wiping theirs $USER->urlid = get_field('usr', 'urlid', 'id', $USER->get('id')); $USER->commit(); db_commit(); $SESSION->add_ok_msg(get_string('generateduserurls', 'admin', $usrcount)); $SESSION->add_ok_msg(get_string('generatedgroupurls', 'admin', $groupcount)); $SESSION->add_ok_msg(get_string('generatedviewurls', 'admin', $viewcount)); redirect('/admin/extensions/cleanurls.php'); }
/** * This function returns the current * language to use, either for a given user * or sitewide, or the default * * @return string */ function current_language() { global $USER, $CFG, $SESSION; static $userlang, $lastlang; $loggedin = $USER instanceof User && $USER->is_logged_in(); if (!isset($userlang) && $loggedin) { $userlang = $USER->get_account_preference('lang'); if ($userlang !== null && $userlang != 'default') { if (!language_installed($userlang)) { $USER->set_account_preference('lang', 'default'); $userlang = 'default'; } } } if (!empty($userlang) && $userlang != 'default') { $lang = $userlang; } else { if (!$loggedin && is_a($SESSION, 'Session')) { $sesslang = $SESSION->get('lang'); if (!empty($sesslang) && $sesslang != 'default') { $lang = $sesslang; } } } if (empty($lang)) { $lang = !empty($CFG->lang) ? $CFG->lang : 'en.utf8'; } if ($lang == $lastlang) { return $lang; } set_locale_for_language($lang); return $lastlang = $lang; }