Compare commits
47 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 0bd0ee444a | |||
| 887f2449a2 | |||
| 40adce7f08 | |||
| 27795d1eed | |||
| 5743df7428 | |||
| c31d886c8f | |||
| 943c9c3c9a | |||
| 6b2d3d3e6a | |||
| a8b89c6120 | |||
| cbfee05d7f | |||
| 0833e7cfc7 | |||
| 10d80cd64c | |||
| 024f0b702a | |||
| 68529165cd | |||
| 87f6a483c3 | |||
| c4fabc91e1 | |||
| 25c75f9b99 | |||
| 517cc1f9a7 | |||
| 00e928271b | |||
| 824965d5dc | |||
| ae375cfcdc | |||
| 1c25f894ef | |||
| ef7442df5b | |||
| a1fadacb86 | |||
| 8f6cefd57d | |||
| f7b04c388e | |||
| a6ec5b6ff6 | |||
| 589c0fbd88 | |||
| fe5264217d | |||
| fdaea8ad64 | |||
| 4f22f01fe4 | |||
| 842db4fd37 | |||
| f2066cb88f | |||
| 0ae9cfc1c2 | |||
| 8dfbc3a822 | |||
| 6c0d5df3a2 | |||
| fb92dba76f | |||
| b80b3d0237 | |||
| a0f554f012 | |||
| 44c7ab2121 | |||
| 8690bb8068 | |||
| 60b566037a | |||
| 7d6c55bfc1 | |||
| 1cf01e8add | |||
| dd9f8fae09 | |||
| 2a3c0ef415 | |||
| c6135d8d46 |
@@ -1870,4 +1870,180 @@
|
||||
</CUSTOM_CHECK>
|
||||
</CUSTOM_CHECKS>
|
||||
</MOODLE>
|
||||
<MOODLE version="3.3" requires="2.7">
|
||||
<UNICODE level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="unicoderequired" />
|
||||
</FEEDBACK>
|
||||
</UNICODE>
|
||||
<DATABASE level="required">
|
||||
<VENDOR name="mariadb" version="5.5.31" />
|
||||
<VENDOR name="mysql" version="5.5.31" />
|
||||
<VENDOR name="postgres" version="9.3" />
|
||||
<VENDOR name="mssql" version="10.0" />
|
||||
<VENDOR name="oracle" version="10.2" />
|
||||
</DATABASE>
|
||||
<PHP version="5.6.5" level="required">
|
||||
</PHP>
|
||||
<PCREUNICODE level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="pcreunicodewarning" />
|
||||
</FEEDBACK>
|
||||
</PCREUNICODE>
|
||||
<PHP_EXTENSIONS>
|
||||
<PHP_EXTENSION name="iconv" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="iconvrequired" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="mbstring" level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="mbstringrecommended" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="curl" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="curlrequired" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="openssl" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="opensslrequired" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="tokenizer" level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="tokenizerrecommended" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="xmlrpc" level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="xmlrpcrecommended" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="soap" level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="soaprecommended" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="ctype" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="ctyperequired" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="zip" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="ziprequired" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="zlib" level="required">
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="gd" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="gdrequired" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="simplexml" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="simplexmlrequired" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="spl" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="splrequired" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="pcre" level="required">
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="dom" level="required">
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="xml" level="required">
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="xmlreader" level="required">
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="intl" level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="intlrecommended" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="json" level="required">
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="hash" level="required"/>
|
||||
<PHP_EXTENSION name="fileinfo" level="required"/>
|
||||
</PHP_EXTENSIONS>
|
||||
<PHP_SETTINGS>
|
||||
<PHP_SETTING name="memory_limit" value="96M" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="settingmemorylimit" />
|
||||
</FEEDBACK>
|
||||
</PHP_SETTING>
|
||||
<PHP_SETTING name="file_uploads" value="1" level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="settingfileuploads" />
|
||||
</FEEDBACK>
|
||||
</PHP_SETTING>
|
||||
<PHP_SETTING name="opcache.enable" value="1" level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="opcacherecommended" />
|
||||
</FEEDBACK>
|
||||
</PHP_SETTING>
|
||||
</PHP_SETTINGS>
|
||||
<CUSTOM_CHECKS>
|
||||
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_database_storage_engine" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="unsupporteddbstorageengine" />
|
||||
</FEEDBACK>
|
||||
</CUSTOM_CHECK>
|
||||
<CUSTOM_CHECK file="question/engine/upgrade/upgradelib.php" function="quiz_attempts_upgraded" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="quizattemptsupgradedmessage" />
|
||||
</FEEDBACK>
|
||||
</CUSTOM_CHECK>
|
||||
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_slasharguments" level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="slashargumentswarning" />
|
||||
</FEEDBACK>
|
||||
</CUSTOM_CHECK>
|
||||
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_database_tables_row_format" level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="unsupporteddbtablerowformat" />
|
||||
</FEEDBACK>
|
||||
</CUSTOM_CHECK>
|
||||
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_unoconv_version" level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="unoconvwarning" />
|
||||
</FEEDBACK>
|
||||
</CUSTOM_CHECK>
|
||||
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_libcurl_version" level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="libcurlwarning" />
|
||||
</FEEDBACK>
|
||||
</CUSTOM_CHECK>
|
||||
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_mysql_file_format" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="unsupporteddbfileformat" />
|
||||
</FEEDBACK>
|
||||
</CUSTOM_CHECK>
|
||||
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_mysql_file_per_table" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="unsupporteddbfilepertable" />
|
||||
</FEEDBACK>
|
||||
</CUSTOM_CHECK>
|
||||
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_mysql_large_prefix" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="unsupporteddblargeprefix" />
|
||||
</FEEDBACK>
|
||||
</CUSTOM_CHECK>
|
||||
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_is_https" level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="ishttpswarning" />
|
||||
</FEEDBACK>
|
||||
</CUSTOM_CHECK>
|
||||
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_mysql_incomplete_unicode_support" level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="incompleteunicodesupport" />
|
||||
</FEEDBACK>
|
||||
</CUSTOM_CHECK>
|
||||
</CUSTOM_CHECKS>
|
||||
</MOODLE>
|
||||
</COMPATIBILITY_MATRIX>
|
||||
|
||||
@@ -27,9 +27,12 @@ if ($primaryadmin) {
|
||||
$primaryadminemail = NULL;
|
||||
$primaryadminname = NULL;
|
||||
}
|
||||
$temp->add(new admin_setting_configtext('supportname', new lang_string('supportname', 'admin'), new lang_string('configsupportname', 'admin'), $primaryadminname, PARAM_NOTAGS));
|
||||
$temp->add(new admin_setting_configtext('supportemail', new lang_string('supportemail', 'admin'), new lang_string('configsupportemail', 'admin'), $primaryadminemail, PARAM_NOTAGS));
|
||||
$temp->add(new admin_setting_configtext('supportpage', new lang_string('supportpage', 'admin'), new lang_string('configsupportpage', 'admin'), '', PARAM_URL));
|
||||
$temp->add(new admin_setting_configtext('supportname', new lang_string('supportname', 'admin'),
|
||||
new lang_string('configsupportname', 'admin'), $primaryadminname, PARAM_NOTAGS));
|
||||
$temp->add(new admin_setting_configtext('supportemail', new lang_string('supportemail', 'admin'),
|
||||
new lang_string('configsupportemail', 'admin'), $primaryadminemail, PARAM_EMAIL));
|
||||
$temp->add(new admin_setting_configtext('supportpage', new lang_string('supportpage', 'admin'),
|
||||
new lang_string('configsupportpage', 'admin'), '', PARAM_URL));
|
||||
$ADMIN->add('server', $temp);
|
||||
|
||||
|
||||
|
||||
+21
-17
@@ -302,18 +302,24 @@ class auth_plugin_db extends auth_plugin_base {
|
||||
|
||||
// Find obsolete users.
|
||||
if (count($userlist)) {
|
||||
$remove_users = array();
|
||||
// All the drivers can cope with chunks of 10,000. See line 4491 of lib/dml/tests/dml_est.php
|
||||
$userlistchunks = array_chunk($userlist , 10000);
|
||||
foreach($userlistchunks as $userlistchunk) {
|
||||
list($notin_sql, $params) = $DB->get_in_or_equal($userlistchunk, SQL_PARAMS_NAMED, 'u', false);
|
||||
$params['authtype'] = $this->authtype;
|
||||
$sql = "SELECT u.id, u.username
|
||||
$removeusers = array();
|
||||
$params['authtype'] = $this->authtype;
|
||||
$sql = "SELECT u.id, u.username
|
||||
FROM {user} u
|
||||
WHERE u.auth=:authtype AND u.deleted=0 AND u.mnethostid=:mnethostid $suspendselect AND u.username $notin_sql";
|
||||
$params['mnethostid'] = $CFG->mnet_localhost_id;
|
||||
$remove_users = $remove_users + $DB->get_records_sql($sql, $params);
|
||||
WHERE u.auth=:authtype
|
||||
AND u.deleted=0
|
||||
AND u.mnethostid=:mnethostid
|
||||
$suspendselect";
|
||||
$params['mnethostid'] = $CFG->mnet_localhost_id;
|
||||
$internalusersrs = $DB->get_recordset_sql($sql, $params);
|
||||
|
||||
$usernamelist = array_flip($userlist);
|
||||
foreach ($internalusersrs as $internaluser) {
|
||||
if (!array_key_exists($internaluser->username, $usernamelist)) {
|
||||
$removeusers[] = $internaluser;
|
||||
}
|
||||
}
|
||||
$internalusersrs->close();
|
||||
} else {
|
||||
$sql = "SELECT u.id, u.username
|
||||
FROM {user} u
|
||||
@@ -321,13 +327,13 @@ class auth_plugin_db extends auth_plugin_base {
|
||||
$params = array();
|
||||
$params['authtype'] = $this->authtype;
|
||||
$params['mnethostid'] = $CFG->mnet_localhost_id;
|
||||
$remove_users = $DB->get_records_sql($sql, $params);
|
||||
$removeusers = $DB->get_records_sql($sql, $params);
|
||||
}
|
||||
|
||||
if (!empty($remove_users)) {
|
||||
$trace->output(get_string('auth_dbuserstoremove','auth_db', count($remove_users)));
|
||||
if (!empty($removeusers)) {
|
||||
$trace->output(get_string('auth_dbuserstoremove', 'auth_db', count($removeusers)));
|
||||
|
||||
foreach ($remove_users as $user) {
|
||||
foreach ($removeusers as $user) {
|
||||
if ($this->config->removeuser == AUTH_REMOVEUSER_FULLDELETE) {
|
||||
delete_user($user);
|
||||
$trace->output(get_string('auth_dbdeleteuser', 'auth_db', array('name'=>$user->username, 'id'=>$user->id)), 1);
|
||||
@@ -341,7 +347,7 @@ class auth_plugin_db extends auth_plugin_base {
|
||||
}
|
||||
}
|
||||
}
|
||||
unset($remove_users);
|
||||
unset($removeusers);
|
||||
}
|
||||
|
||||
if (!count($userlist)) {
|
||||
@@ -950,5 +956,3 @@ class auth_plugin_db extends auth_plugin_base {
|
||||
return $user;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ class block_course_overview extends block_base {
|
||||
$content = array();
|
||||
|
||||
$updatemynumber = optional_param('mynumber', -1, PARAM_INT);
|
||||
if ($updatemynumber >= 0) {
|
||||
if ($updatemynumber >= 0 && optional_param('sesskey', '', PARAM_RAW) && confirm_sesskey()) {
|
||||
block_course_overview_update_mynumber($updatemynumber);
|
||||
}
|
||||
|
||||
|
||||
@@ -86,7 +86,7 @@ function block_course_overview_get_myorder() {
|
||||
// If preference was not found, look in the old location and convert if found.
|
||||
$order = array();
|
||||
if ($value = get_user_preferences('course_overview_course_order')) {
|
||||
$order = unserialize($value);
|
||||
$order = unserialize_array($value);
|
||||
block_course_overview_update_myorder($order);
|
||||
unset_user_preference('course_overview_course_order');
|
||||
}
|
||||
|
||||
@@ -213,7 +213,7 @@ class block_course_overview_renderer extends plugin_renderer_base {
|
||||
for ($i = 1; $i <= $max; $i++) {
|
||||
$options[$i] = $i;
|
||||
}
|
||||
$url = new moodle_url('/my/index.php');
|
||||
$url = new moodle_url('/my/index.php', ['sesskey' => sesskey()]);
|
||||
$select = new single_select($url, 'mynumber', $options, block_course_overview_get_max_user_courses(), array());
|
||||
$select->set_label(get_string('numtodisplay', 'block_course_overview'));
|
||||
$output .= $this->output->render($select);
|
||||
|
||||
@@ -53,11 +53,11 @@ $action = (empty($id)) ? 'add' : 'edit';
|
||||
|
||||
$external = new stdClass();
|
||||
|
||||
// Check that this id exists.
|
||||
if (!empty($id) && !$DB->record_exists('blog_external', array('id' => $id))) {
|
||||
print_error('wrongexternalid', 'blog');
|
||||
} else if (!empty($id)) {
|
||||
$external = $DB->get_record('blog_external', array('id' => $id));
|
||||
// Retrieve the external blog record.
|
||||
if (!empty($id)) {
|
||||
if (!$external = $DB->get_record('blog_external', array('id' => $id, 'userid' => $USER->id))) {
|
||||
print_error('wrongexternalid', 'blog');
|
||||
}
|
||||
}
|
||||
|
||||
$strformheading = ($action == 'edit') ? get_string('editexternalblog', 'blog') : get_string('addnewexternalblog', 'blog');
|
||||
|
||||
+1
-1
@@ -873,7 +873,7 @@ function blog_get_headers($courseid=null, $groupid=null, $userid=null, $tagid=nu
|
||||
}
|
||||
|
||||
// Append Search info.
|
||||
if (!empty($search)) {
|
||||
if (!empty($search) && has_capability('moodle/blog:search', $sitecontext)) {
|
||||
$headers['filters']['search'] = $search;
|
||||
$blogurl->param('search', $search);
|
||||
$PAGE->navbar->add(get_string('searchterm', 'blog', $search), $blogurl->out());
|
||||
|
||||
@@ -1758,7 +1758,7 @@ class grade_report_grader extends grade_report {
|
||||
|
||||
// Try looking for old location of user setting that used to store all courses in one serialized user preference.
|
||||
if (($oldcollapsedpref = get_user_preferences('grade_report_grader_collapsed_categories')) !== null) {
|
||||
if ($collapsedall = @unserialize($oldcollapsedpref)) {
|
||||
if ($collapsedall = unserialize_array($oldcollapsedpref)) {
|
||||
// We found the old-style preference, filter out only categories that belong to this course and update the prefs.
|
||||
$collapsed = static::filter_collapsed_categories($courseid, $collapsedall);
|
||||
if (!empty($collapsed['aggregatesonly']) || !empty($collapsed['gradesonly'])) {
|
||||
|
||||
@@ -69,9 +69,15 @@ $string['pathshead'] = 'Potvrdit cesty';
|
||||
$string['pathsrodataroot'] = 'Do datového adresáře nelze zapisovat.';
|
||||
$string['pathsroparentdataroot'] = 'Do nadřazeného adresáře ({$a->parent}) nelze zapisovat. Datový adresář ({$a->dataroot}) nemůže být tímto průvodcem instalací vytvořen.';
|
||||
$string['pathssubadmindir'] = 'Na některých serverech je URL adresa /admin vyhrazena pro speciální účely (např. pro ovládací panel). Na takových serverech může dojít ke kolizi se standardním umístěním stránek pro správu Moodle. Máte-li tento problém, přejmenujte adresář <eM>admin</em> ve vaší instalaci Moodle a sem zadejte jeho nový název - například <em>moodleadmin</em>. Všechny generované odkazy na stránky správy Moodle budou používat tento nový název.';
|
||||
$string['pathssubdataroot'] = 'Moodle potřebuje prostor, kam si bude ukládat nahrané soubory a další údaje. K tomuto adresáři musí mít proces webového serveru právo ke čtení i k zápisu (webový server bývá většinou spouštěn pod uživatelem "www-data" nebo "apache"). Tento adresář ale zároveň nesmí být dostupný přímo přes webové rozhraní. Instalační skript se pokusí tento adresář vytvořit, pokud nebude existovat.';
|
||||
$string['pathssubdataroot'] = '<p>Moodle potřebuje prostor, kam si bude ukládat nahrané soubory a další údaje. .</p>
|
||||
<p>K tomuto adresáři musí mít proces webového serveru právo ke čtení i k zápisu (webový server bývá většinou spouštěn pod uživatelem "www-data" nebo "apache"). .</p>
|
||||
<p>Tento adresář ale zároveň nesmí být dostupný přímo přes webové rozhraní. .</p>
|
||||
<p>Instalační skript se pokusí tento adresář vytvořit, pokud nebude existovat..</p>';
|
||||
$string['pathssubdirroot'] = 'Absolutní cesta k adresáři s instalací Moodle';
|
||||
$string['pathssubwwwroot'] = 'Zadejte úplnou webovou adresu, na níž bude Moodle dostupný. Moodle potřebuje jedinečnou adresu, není možné jej provozovat na několika URL současně. Používáte-li několik veřejných domén, musíte si sami nastavit permanentní přesměrování na jednu z nich a tu pak použít. Pokud je váš server dostupný z vnější a z vnitřní sítě pod různými IP adresami, použijte jeho veřejnou adresu a nastavte si váš DNS server tak, že ji mohou používat i uživatelé z vnitřní sítě.';
|
||||
$string['pathssubwwwroot'] = '<p>Zadejte úplnou webovou adresu, na níž bude Moodle dostupný, t.j. adresa, kterou zadají uživatelé do adresního řádku svého prohlížeče, aby spustili Moodle.</p>
|
||||
<p>Moodle potřebuje jedinečnou adresu, není možné jej provozovat na několika URL současně. Používáte-li několik veřejných domén, musíte si sami nastavit permanentní přesměrování na jednu z nich a tu pak použít.</p>
|
||||
<p> Pokud je váš server dostupný z vnější a z vnitřní sítě pod různými IP adresami, použijte jeho veřejnou adresu a nastavte si váš DNS server tak, že ji mohou používat i uživatelé z vnitřní sítě.</p>
|
||||
<p>Pokud aktuální adresa není správná, změňte URL adresu v adresním řádku prohlížeče a spusťte instalaci.</p>';
|
||||
$string['pathsunsecuredataroot'] = 'Umístění datového adresáře není bezpečné';
|
||||
$string['pathswrongadmindir'] = 'Adresář pro správu serveru (admin) neexistuje';
|
||||
$string['phpextension'] = '{$a} PHP rozšíření';
|
||||
|
||||
+13
-11
@@ -72,13 +72,15 @@ $string['pathshead'] = 'Bekræft stier';
|
||||
$string['pathsrodataroot'] = 'Datamappen er skrivebeskyttet.';
|
||||
$string['pathsroparentdataroot'] = 'Den overordnede mappe ({$a->parent}) er skrivebeskyttet. Datamappen ({$a->dataroot}) kan ikke oprettes af installationsprogrammet.';
|
||||
$string['pathssubadmindir'] = 'Enkelte webhoteller bruger /admin som speciel URL til kontrolpanelet el. lign. Desværre konflikter det med Moodles standardplacering af admin-sider. Du kan klare dette ved at give admin-mappen et andet navn i din installation og skrive det her. Det kan f.eks. være <em>moodleadmin</em>. Det vil fikse admin-links i Moodle.';
|
||||
$string['pathssubdataroot'] = 'Du har brug for et sted, hvor Moodle kan gemme uploadede filer. Denne mappe skal kunne læses OG SKRIVES I af webserverbrugeren (oftest \'ingen\' eller \'apache\'), men må ikke være tilgængelig direkte via internettet. Installationsprogrammet vil forsøge at oprette mappen, hvis ikke den allerede eksisterer.';
|
||||
$string['pathssubdirroot'] = 'Den fulde sti til Moodleinstallationen.';
|
||||
$string['pathssubwwwroot'] = 'Moodles fulde web-adresse.
|
||||
Det er ikke muligt at komme ind på Moodle fra mere end en adresse.
|
||||
Hvis dit websted har flere offentlige adresser skal du opsætte permanent viderestilling til dem alle undtagen denne.
|
||||
Hvis dit websted er tilgængeligt fra både internet og intranet skal du bruge internetadressen her og opsætte din DNS sådan at intranet-brugerne kan bruge den offentlige adresse også.
|
||||
Hvis ikke adressen er korrekt må du ændre URL\'en i din browser og genstarte installationen med den rigtige adresse.';
|
||||
$string['pathssubdataroot'] = '<p>En mappe hvori Moodle kan gemme uploadede filer.</p>
|
||||
<p>Webserver-brugeren (som regel \'www-data\', \'nobody\', eller \'apache\') skal have læse- og skriveadgang til den.</p>
|
||||
<p>Mappen må ikke være tilgængelig direkte fra internettet.</p>
|
||||
<p>Hvis ikke den allerede eksisterer, vil Installationsprogrammet forsøge at oprette den</p>';
|
||||
$string['pathssubdirroot'] = '<p>Den fulde sti mappen med til Moodlekoden.</p>';
|
||||
$string['pathssubwwwroot'] = '<p>Moodles fulde web-adresse, dvs. adressen som den skal stå i browserens adressefelt for at komme ind på Moodle.</p>
|
||||
<p>Moodle kan ikke bruges fra flere adresser. Hvis dit websted kan tilgås fra flere adresser, skal du vælge den enkleste og opsætte permanent viderestilling for hver af de øvrige.</p>
|
||||
<p>Hvis dit websted er tilgængeligt fra både internettet og et internt net (nogen gange kaldet intranet), skal du bruge den offentlige adresse her</p>
|
||||
<p>Hvis ikke adressen er korrekt, skal du ændre URL\'en i din browser og genstarte installationen.</p>';
|
||||
$string['pathsunsecuredataroot'] = 'Datamappen er ikke sikret';
|
||||
$string['pathswrongadmindir'] = 'Adminmappe eksisterer ikke';
|
||||
$string['phpextension'] = '{$a} PHP-extension';
|
||||
@@ -88,11 +90,11 @@ $string['phpversionhelp'] = '<p>Moodle kræver mindst PHP version 4.3.0. eller 5
|
||||
<p>Du bliver nødt til at opdatere PHP eller flytte systemet over på en anden webserver der har en nyere version af PHP!</p>
|
||||
(Har du ver. 5.0.x kan du også nedgradere til 4.4.x)</p>';
|
||||
$string['welcomep10'] = '{$a->installername} ({$a->installerversion})';
|
||||
$string['welcomep20'] = 'Du ser denne side fordi du med succes har installeret og åbnet pakken <strong>{$a->packname} {$a->packversion}</strong> på din computer.
|
||||
$string['welcomep20'] = 'Du ser denne side fordi du har installeret og åbnet pakken <strong>{$a->packname} {$a->packversion}</strong> på din computer.
|
||||
Tillykke med det!';
|
||||
$string['welcomep30'] = 'Denne udgave af <strong>{$a->installername}</strong> indeholder programmerne til at oprette et miljø, hvori <strong>Moodle</strong> vil operere, nemlig:';
|
||||
$string['welcomep30'] = 'Denne version af <strong>{$a->installername}</strong> indeholder programmerne til at oprette et miljø, hvori <strong>Moodle</strong> vil operere, nemlig:';
|
||||
$string['welcomep40'] = 'Pakken indeholder også <strong>Moodle {$a->moodlerelease} ({$a->moodleversion})</strong>.';
|
||||
$string['welcomep50'] = 'Brugen af programmerne i denne pakke er styret af deres respektive licenser. Hele <strong>{$a->installername}</strong>-pakken er <a href="http://www.opensource.org/docs/definition_plain.html">open source</a> og distribueret under <a href="http://www.gnu.org/copyleft/gpl.html">GPL</a>-licensen.';
|
||||
$string['welcomep60'] = 'De følgende sider vil hjælpe dig gennem nogle nemme trin til konfiguration og opsætning af <strong>Moodle</strong> på din computer. Du kan acceptere standardindstillingerne eller vælge at ændre dem så de bedre svarer til dine egne behov.';
|
||||
$string['welcomep50'] = 'Brugen af programmerne i denne pakke reguleres af deres respektive licenser. Hele <strong>{$a->installername}</strong>-pakken er <a href="http://www.opensource.org/docs/definition_plain.html">open source</a> og distribueret under <a href="http://www.gnu.org/copyleft/gpl.html">GPL</a>-licensen.';
|
||||
$string['welcomep60'] = 'De følgende sider vil hjælpe dig gennem nogle nemme trin til konfiguration og opsætning af <strong>Moodle</strong> på din computer. Du kan acceptere standardindstillingerne, eller vælge at ændre dem så de bedre svarer til dine egne behov.';
|
||||
$string['welcomep70'] = 'Klik på "Næste" herunder for at forsætte opsætningen af <strong>Moodle</strong>.';
|
||||
$string['wwwroot'] = 'Webadresse';
|
||||
|
||||
@@ -88,6 +88,6 @@ $string['welcomep30'] = 'Deze uitgave van <strong>{$a->installername}</strong> b
|
||||
$string['welcomep40'] = 'Dit pakket bevat ook <strong>Moodle {$a->moodlerelease} ({$a->moodleversion})</strong>.';
|
||||
$string['welcomep50'] = 'Het gebruik van alle programma\'s in dit pakket wordt geregeld door hun respectievelijke licenties. Het complete <strong>{$a->installername}</strong> pakket is
|
||||
<a href="http://www.opensource.org/docs/definition_plain.html">open source</a> en wordt verdeeld onder de <a href="http://www.gnu.org/copyleft/gpl.html">GPL</a> licentie.';
|
||||
$string['welcomep60'] = 'De volgende pagina\'s leiden je door een aantal makkelijk te volgen stappen om <strong>Moodle</strong> te installeren op je computer. Je kunt de standaardinstellingen overnemen of, optionneel, ze aanpassen aan je noden.';
|
||||
$string['welcomep60'] = 'De volgende pagina\'s leiden je door een aantal makkelijk te volgen stappen om <strong>Moodle</strong> te installeren op je computer. Je kunt de standaardinstellingen overnemen of, optioneel, ze aanpassen aan je noden.';
|
||||
$string['welcomep70'] = 'Klik op de "volgende"-knop om verder te gaan met de installatie van <strong>Moodle</strong>';
|
||||
$string['wwwroot'] = 'Web adres';
|
||||
|
||||
@@ -34,8 +34,8 @@ $string['admindirname'] = 'Katalog admin';
|
||||
$string['availablelangs'] = 'Dostępne paczki językowe';
|
||||
$string['chooselanguagehead'] = 'Wybierz język';
|
||||
$string['chooselanguagesub'] = 'Proszę wybrać język do instalacji. Ten język będzie również użyty jako domyślny język witryny, przy czym może być później zmieniony.';
|
||||
$string['clialreadyconfigured'] = 'Plik config.php już istnieje, użyj admin/cli/install_database.php jeśli chcesz zainstalować tę witrynę.';
|
||||
$string['clialreadyinstalled'] = 'Plik config.php już istnieje, użyj admin/cli/upgrade.php, jeśli chcesz uaktualnić witrynę.';
|
||||
$string['clialreadyconfigured'] = 'Plik config.php już istnieje. Użyj admin/cli/install_database.php jeśli chcesz zainstalować Moodle dla tej strony.';
|
||||
$string['clialreadyinstalled'] = 'Plik config.php już istnieje. Użyj admin/cli/install_database.php jeśli chcesz zaktualizować Moodle dla tej strony.';
|
||||
$string['cliinstallheader'] = 'Program instalacyjny Moodle {$a} z linii poleceń';
|
||||
$string['databasehost'] = 'Host bazy danych';
|
||||
$string['databasename'] = 'Nazwa bazy danych';
|
||||
|
||||
@@ -54,6 +54,10 @@ $string['paths'] = 'Căi';
|
||||
$string['pathserrcreatedataroot'] = 'Data directory ({$a->dataroot}) nu poate fi creat de către installer.';
|
||||
$string['pathshead'] = 'Confirmare căi';
|
||||
$string['pathsrodataroot'] = 'Directorul dataroot nu poate fi scris.';
|
||||
$string['pathssubdataroot'] = '<p>Un director unde Moodle va stoca tot conținutul unui fișier încărcat de către utilizatori.</p>
|
||||
<p>Acest director trebuie să poată fi citit și scris de către utilizatrii serverului web (de obicei \'www-data\', \'nobody\', or \'apache\').</p>
|
||||
<p>Nu trebuie să fie direct accesibil de pe web.</p>
|
||||
<p>Dacă directorul nu există în prezent, procesul de instalare va încerca să îl creeze.</p>';
|
||||
$string['pathssubdirroot'] = '<p>Calea completă către directorul care conține codul Moodle .</p>';
|
||||
$string['pathsunsecuredataroot'] = 'Locația dataroot nu este sigură';
|
||||
$string['pathswrongadmindir'] = 'Directorul admin nu există';
|
||||
@@ -65,5 +69,8 @@ $string['phpversionhelp'] = '<p>Moodle necesită o versiune PHP de cel puțin 4
|
||||
(În cazul 5.0.x puteți, de asemenea, să downgradați la versiunea 4.4.x)</p>';
|
||||
$string['welcomep10'] = '{$a->installername} ({$a->installerversion})';
|
||||
$string['welcomep20'] = 'Vedeți această pagină deoarece ați instalat și lansat cu succes pachetul <strong>{$a->packname} {$a->packversion}</strong> în computerul dumneavoastră. Felicitări!';
|
||||
$string['welcomep30'] = 'Lansarea <strong>{$a->installername}</strong> include aplicațiile
|
||||
pentru a crea un mediu în care <strong>Moodle</strong> va funcționa, și anume:';
|
||||
$string['welcomep40'] = 'Pachetul include și <strong>Moodle {$a->moodlerelease} ({$a->moodleversion})</strong>.';
|
||||
$string['welcomep70'] = 'Click pe butonul "Next" de mai jos pentru a continua setarea <strong>Moodle</strong>.';
|
||||
$string['wwwroot'] = 'Adresă Web';
|
||||
|
||||
@@ -769,6 +769,7 @@ $string['numberofmissingstrings'] = 'Number of missing strings: {$a}';
|
||||
$string['numberofstrings'] = 'Total number of strings: {$a->strings}<br />Missing: {$a->missing} ({$a->missingpercent} %)';
|
||||
$string['opcacherecommended'] = 'PHP opcode caching improves performance and lowers memory requirements, OPcache extension is recommended and fully supported.';
|
||||
$string['opensslrecommended'] = 'Installing the optional OpenSSL library is highly recommended -- it enables Moodle Networking functionality.';
|
||||
$string['opensslrequired'] = 'The OpenSSL PHP extension is now required by Moodle to provide stronger cryptographic services.';
|
||||
$string['opentogoogle'] = 'Open to Google';
|
||||
$string['optionalmaintenancemessage'] = 'Optional maintenance message';
|
||||
$string['order1'] = 'First';
|
||||
|
||||
@@ -180,6 +180,7 @@ $string['viewmyentriesaboutcourse'] = 'View my entries about this course';
|
||||
$string['viewsiteentries'] = 'View all entries';
|
||||
$string['viewuserentries'] = 'View all entries by {$a}';
|
||||
$string['worldblogs'] = 'The world can read entries set to be world-accessible';
|
||||
$string['wrongexternalid'] = 'Wrong external blog id';
|
||||
$string['wrongpostid'] = 'Wrong blog post id';
|
||||
$string['page-blog-edit'] = 'Blog editing pages';
|
||||
$string['page-blog-index'] = 'Blog listing pages';
|
||||
|
||||
Vendored
+1
-1
@@ -1 +1 @@
|
||||
define(["core/yui"],function(a){return{alert:function(b,c,d){a.use("moodle-core-notification-alert",function(){var a=new M.core.alert({title:b,message:c,yesLabel:d});a.show()})},confirm:function(b,c,d,e,f){a.use("moodle-core-notification-confirm",function(){var a=new M.core.confirm({title:b,question:c,yesLabel:d,noLabel:e});a.on("complete-yes",function(){f()}),a.show()})},exception:function(b){b.backtrace&&(b.lineNumber=b.backtrace[0].line,b.fileName=b.backtrace[0].file,b.fileName="..."+b.fileName.substr(b.fileName.length-20),b.stack=b.debuginfo,b.name=b.errorcode),a.use("moodle-core-notification-exception",function(){var a=new M.core.exception(b);a.show()})}}});
|
||||
define(["core/yui"],function(a){return{alert:function(b,c,d){a.use("moodle-core-notification-alert",function(){var a=new M.core.alert({title:b,message:c,yesLabel:d});a.show()})},confirm:function(b,c,d,e,f){a.use("moodle-core-notification-confirm",function(){var a=new M.core.confirm({title:b,question:c,yesLabel:d,noLabel:e});a.on("complete-yes",function(){f()}),a.show()})},exception:function(b){if("undefined"==typeof b.stack&&(b.stack=""),b.debuginfo&&(b.stack+=b.debuginfo+"\n"),b.backtrace){b.stack+=b.backtrace;var c=b.backtrace.match(/line ([^ ]*) of/),d=b.backtrace.match(/ of ([^:]*): /);c&&c[1]&&(b.lineNumber=c[1]),d&&d[1]&&(b.fileName=d[1],b.fileName.length>30&&(b.fileName="..."+b.fileName.substr(b.fileName.length-27)))}"undefined"==typeof b.name&&b.errorcode&&(b.name=b.errorcode),a.use("moodle-core-notification-exception",function(){var a=new M.core.exception(b);a.show()})}}});
|
||||
@@ -88,14 +88,31 @@ define(['core/yui'], function(Y) {
|
||||
*/
|
||||
exception: function(ex) {
|
||||
// Fudge some parameters.
|
||||
if (typeof ex.stack == 'undefined') {
|
||||
ex.stack = '';
|
||||
}
|
||||
if (ex.debuginfo) {
|
||||
ex.stack += ex.debuginfo + '\n';
|
||||
}
|
||||
if (ex.backtrace) {
|
||||
ex.lineNumber = ex.backtrace[0].line;
|
||||
ex.fileName = ex.backtrace[0].file;
|
||||
ex.fileName = '...' + ex.fileName.substr(ex.fileName.length - 20);
|
||||
ex.stack = ex.debuginfo;
|
||||
ex.stack += ex.backtrace;
|
||||
var ln = ex.backtrace.match(/line ([^ ]*) of/);
|
||||
var fn = ex.backtrace.match(/ of ([^:]*): /);
|
||||
if (ln && ln[1]) {
|
||||
ex.lineNumber = ln[1];
|
||||
}
|
||||
if (fn && fn[1]) {
|
||||
ex.fileName = fn[1];
|
||||
if (ex.fileName.length > 30) {
|
||||
ex.fileName = '...' + ex.fileName.substr(ex.fileName.length - 27);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (typeof ex.name == 'undefined' && ex.errorcode) {
|
||||
ex.name = ex.errorcode;
|
||||
}
|
||||
Y.use('moodle-core-notification-exception', function () {
|
||||
|
||||
Y.use('moodle-core-notification-exception', function() {
|
||||
var modal = new M.core.exception(ex);
|
||||
|
||||
modal.show();
|
||||
|
||||
@@ -114,6 +114,9 @@ class behat_util extends testing_util {
|
||||
// Enable web cron.
|
||||
set_config('cronclionly', 0);
|
||||
|
||||
// Set noreplyaddress to an example domain, as it should be valid email address and test site can be a localhost.
|
||||
set_config('noreplyaddress', 'noreply@example.com');
|
||||
|
||||
// Keeps the current version of database and dataroot.
|
||||
self::store_versions_hash();
|
||||
|
||||
|
||||
+78
-3
@@ -5579,6 +5579,18 @@ function email_to_user($user, $from, $subject, $messagetext, $messagehtml = '',
|
||||
$tempreplyto = array();
|
||||
|
||||
$supportuser = core_user::get_support_user();
|
||||
$noreplyaddressdefault = 'noreply@' . get_host_from_url($CFG->wwwroot);
|
||||
$noreplyaddress = empty($CFG->noreplyaddress) ? $noreplyaddressdefault : $CFG->noreplyaddress;
|
||||
|
||||
if (!validate_email($noreplyaddress)) {
|
||||
debugging('email_to_user: Invalid noreply-email '.s($noreplyaddress));
|
||||
$noreplyaddress = $noreplyaddressdefault;
|
||||
}
|
||||
|
||||
if (!validate_email($supportuser->email)) {
|
||||
debugging('email_to_user: Invalid support-email '.s($supportuser->email));
|
||||
$supportuser->email = $noreplyaddress;
|
||||
}
|
||||
|
||||
// Make up an email address for handling bounces.
|
||||
if (!empty($CFG->handlebounces)) {
|
||||
@@ -5596,17 +5608,28 @@ function email_to_user($user, $from, $subject, $messagetext, $messagehtml = '',
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure that the explicit replyto is valid, fall back to the implicit one.
|
||||
if (!empty($replyto) && !validate_email($replyto)) {
|
||||
debugging('email_to_user: Invalid replyto-email '.s($replyto));
|
||||
$replyto = $noreplyaddress;
|
||||
}
|
||||
|
||||
if (is_string($from)) { // So we can pass whatever we want if there is need.
|
||||
$mail->From = $CFG->noreplyaddress;
|
||||
$mail->From = $noreplyaddress;
|
||||
$mail->FromName = $from;
|
||||
} else if ($usetrueaddress and $from->maildisplay) {
|
||||
if (!validate_email($from->email)) {
|
||||
debugging('email_to_user: Invalid from-email '.s($from->email).' - not sending');
|
||||
// Better not to use $noreplyaddress in this case.
|
||||
return false;
|
||||
}
|
||||
$mail->From = $from->email;
|
||||
$mail->FromName = fullname($from);
|
||||
} else {
|
||||
$mail->From = $CFG->noreplyaddress;
|
||||
$mail->From = $noreplyaddress;
|
||||
$mail->FromName = fullname($from);
|
||||
if (empty($replyto)) {
|
||||
$tempreplyto[] = array($CFG->noreplyaddress, get_string('noreplyname'));
|
||||
$tempreplyto[] = array($noreplyaddress, get_string('noreplyname'));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9489,6 +9512,58 @@ function get_course_display_name_for_list($course) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Safe analogue of unserialize() that can only parse arrays
|
||||
*
|
||||
* Arrays may contain only integers or strings as both keys and values. Nested arrays are allowed.
|
||||
* Note: If any string (key or value) has semicolon (;) as part of the string parsing will fail.
|
||||
* This is a simple method to substitute unnecessary unserialize() in code and not intended to cover all possible cases.
|
||||
*
|
||||
* @param string $expression
|
||||
* @return array|bool either parsed array or false if parsing was impossible.
|
||||
*/
|
||||
function unserialize_array($expression) {
|
||||
$subs = [];
|
||||
// Find nested arrays, parse them and store in $subs , substitute with special string.
|
||||
while (preg_match('/([\^;\}])(a:\d+:\{[^\{\}]*\})/', $expression, $matches) && strlen($matches[2]) < strlen($expression)) {
|
||||
$key = '--SUB' . count($subs) . '--';
|
||||
$subs[$key] = unserialize_array($matches[2]);
|
||||
if ($subs[$key] === false) {
|
||||
return false;
|
||||
}
|
||||
$expression = str_replace($matches[2], $key . ';', $expression);
|
||||
}
|
||||
|
||||
// Check the expression is an array.
|
||||
if (!preg_match('/^a:(\d+):\{([^\}]*)\}$/', $expression, $matches1)) {
|
||||
return false;
|
||||
}
|
||||
// Get the size and elements of an array (key;value;key;value;....).
|
||||
$parts = explode(';', $matches1[2]);
|
||||
$size = intval($matches1[1]);
|
||||
if (count($parts) < $size * 2 + 1) {
|
||||
return false;
|
||||
}
|
||||
// Analyze each part and make sure it is an integer or string or a substitute.
|
||||
$value = [];
|
||||
for ($i = 0; $i < $size * 2; $i++) {
|
||||
if (preg_match('/^i:(\d+)$/', $parts[$i], $matches2)) {
|
||||
$parts[$i] = (int)$matches2[1];
|
||||
} else if (preg_match('/^s:(\d+):"(.*)"$/', $parts[$i], $matches3) && strlen($matches3[2]) == (int)$matches3[1]) {
|
||||
$parts[$i] = $matches3[2];
|
||||
} else if (preg_match('/^--SUB\d+--$/', $parts[$i])) {
|
||||
$parts[$i] = $subs[$parts[$i]];
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// Combine keys and values.
|
||||
for ($i = 0; $i < $size * 2; $i += 2) {
|
||||
$value[$parts[$i]] = $parts[$i+1];
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* The lang_string class
|
||||
*
|
||||
|
||||
@@ -3013,4 +3013,57 @@ class core_moodlelib_testcase extends advanced_testcase {
|
||||
$this->assertSame('', $result);
|
||||
$this->assertDebuggingCalled();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that generate_email_processing_address() returns valid email address.
|
||||
*/
|
||||
public function test_generate_email_processing_address() {
|
||||
global $CFG;
|
||||
$this->resetAfterTest();
|
||||
|
||||
$data = (object)[
|
||||
'id' => 42,
|
||||
'email' => 'my.email+from_moodle@example.com',
|
||||
];
|
||||
|
||||
$modargs = 'B'.base64_encode(pack('V', $data->id)).substr(md5($data->email), 0, 16);
|
||||
|
||||
$CFG->maildomain = 'example.com';
|
||||
$CFG->mailprefix = 'mdl+';
|
||||
$this->assertEquals(1, validate_email(generate_email_processing_address(0, $modargs)));
|
||||
|
||||
$CFG->maildomain = 'mail.example.com';
|
||||
$CFG->mailprefix = 'mdl-';
|
||||
$this->assertEquals(1, validate_email(generate_email_processing_address(23, $modargs)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test safe method unserialize_array().
|
||||
*/
|
||||
public function test_unserialize_array() {
|
||||
$a = [1, 2, 3];
|
||||
$this->assertEquals($a, unserialize_array(serialize($a)));
|
||||
$this->assertEquals($a, unserialize_array(serialize($a)));
|
||||
$a = ['a' => 1, 2 => 2, 'b' => 'cde'];
|
||||
$this->assertEquals($a, unserialize_array(serialize($a)));
|
||||
$this->assertEquals($a, unserialize_array(serialize($a)));
|
||||
$a = ['a' => 1, 2 => 2, 'b' => 'c"d"e'];
|
||||
$this->assertEquals($a, unserialize_array(serialize($a)));
|
||||
$a = ['a' => 1, 2 => ['c' => 'd', 'e' => 'f'], 'b' => 'cde'];
|
||||
$this->assertEquals($a, unserialize_array(serialize($a)));
|
||||
|
||||
// Can not unserialize if any string contains semicolons.
|
||||
$a = ['a' => 1, 2 => 2, 'b' => 'c"d";e'];
|
||||
$this->assertEquals(false, unserialize_array(serialize($a)));
|
||||
|
||||
// Can not unserialize if there are any objects.
|
||||
$a = (object)['a' => 1, 2 => 2, 'b' => 'cde'];
|
||||
$this->assertEquals(false, unserialize_array(serialize($a)));
|
||||
$a = ['a' => 1, 2 => 2, 'b' => (object)['a' => 'cde']];
|
||||
$this->assertEquals(false, unserialize_array(serialize($a)));
|
||||
|
||||
// Array used in the grader report.
|
||||
$a = array('aggregatesonly' => [51, 34], 'gradesonly' => [21, 45, 78]);
|
||||
$this->assertEquals($a, unserialize_array(serialize($a)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -583,4 +583,19 @@ EXPECTED;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests for validate_email() function.
|
||||
*/
|
||||
public function test_validate_email() {
|
||||
|
||||
$this->assertEquals(1, validate_email('moodle@example.com'));
|
||||
$this->assertEquals(1, validate_email('moodle@localhost.local'));
|
||||
$this->assertEquals(1, validate_email('verp_email+is=mighty@moodle.org'));
|
||||
$this->assertEquals(1, validate_email("but_potentially'dangerous'too@example.org"));
|
||||
$this->assertEquals(1, validate_email('posts+AAAAAAAAAAIAAAAAAAAGQQAAAAABFSXz1eM/P/lR2bYyljM+@posts.moodle.org'));
|
||||
|
||||
$this->assertEquals(0, validate_email('moodle@localhost'));
|
||||
$this->assertEquals(0, validate_email('"attacker\\" -oQ/tmp/ -X/var/www/vhost/moodle/backdoor.php some"@email.com'));
|
||||
$this->assertEquals(0, validate_email("moodle@example.com>\r\nRCPT TO:<victim@example.com"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2453,6 +2453,12 @@ function upgrade_install_plugins(array $installable, $confirmed, $heading='', $c
|
||||
*/
|
||||
function check_libcurl_version(environment_results $result) {
|
||||
|
||||
if (!function_exists('curl_version')) {
|
||||
$result->setInfo('cURL PHP extension is not installed');
|
||||
$result->setStatus(false);
|
||||
return $result;
|
||||
}
|
||||
|
||||
// Supported version and version number.
|
||||
$supportedversion = 0x071304;
|
||||
$supportedversionstring = "7.19.4";
|
||||
|
||||
@@ -33,7 +33,8 @@ if ($ADMIN->fulltree) {
|
||||
$settings->add(new admin_setting_configtext('smtpuser', get_string('smtpuser', 'message_email'), get_string('configsmtpuser', 'message_email'), '', PARAM_NOTAGS));
|
||||
$settings->add(new admin_setting_configpasswordunmask('smtppass', get_string('smtppass', 'message_email'), get_string('configsmtpuser', 'message_email'), ''));
|
||||
$settings->add(new admin_setting_configtext('smtpmaxbulk', get_string('smtpmaxbulk', 'message_email'), get_string('configsmtpmaxbulk', 'message_email'), 1, PARAM_INT));
|
||||
$settings->add(new admin_setting_configtext('noreplyaddress', get_string('noreplyaddress', 'message_email'), get_string('confignoreplyaddress', 'message_email'), 'noreply@' . get_host_from_url($CFG->wwwroot), PARAM_NOTAGS));
|
||||
$settings->add(new admin_setting_configtext('noreplyaddress', get_string('noreplyaddress', 'message_email'),
|
||||
get_string('confignoreplyaddress', 'message_email'), 'noreply@' . get_host_from_url($CFG->wwwroot), PARAM_EMAIL));
|
||||
$settings->add(new admin_setting_configcheckbox('emailonlyfromnoreplyaddress',
|
||||
get_string('emailonlyfromnoreplyaddress', 'message_email'),
|
||||
get_string('configemailonlyfromnoreplyaddress', 'message_email'), 0));
|
||||
|
||||
@@ -825,7 +825,7 @@ class mod_assign_external extends external_api {
|
||||
'locked' => new external_value(PARAM_INT, 'locked', VALUE_OPTIONAL),
|
||||
'mailed' => new external_value(PARAM_INT, 'mailed', VALUE_OPTIONAL),
|
||||
'extensionduedate' => new external_value(PARAM_INT, 'extension due date', VALUE_OPTIONAL),
|
||||
'workflowstate' => new external_value(PARAM_TEXT, 'marking workflow state', VALUE_OPTIONAL),
|
||||
'workflowstate' => new external_value(PARAM_ALPHA, 'marking workflow state', VALUE_OPTIONAL),
|
||||
'allocatedmarker' => new external_value(PARAM_INT, 'allocated marker', VALUE_OPTIONAL)
|
||||
)
|
||||
)
|
||||
@@ -1081,7 +1081,7 @@ class mod_assign_external extends external_api {
|
||||
'locked' => new external_value(PARAM_INT, 'locked'),
|
||||
'mailed' => new external_value(PARAM_INT, 'mailed'),
|
||||
'extensionduedate' => new external_value(PARAM_INT, 'extension due date'),
|
||||
'workflowstate' => new external_value(PARAM_TEXT, 'marking workflow state', VALUE_OPTIONAL),
|
||||
'workflowstate' => new external_value(PARAM_ALPHA, 'marking workflow state', VALUE_OPTIONAL),
|
||||
'allocatedmarker' => new external_value(PARAM_INT, 'allocated marker')
|
||||
)
|
||||
)
|
||||
|
||||
@@ -1329,7 +1329,6 @@ class assign {
|
||||
|
||||
static $scalegrades = array();
|
||||
|
||||
$decimals = $this->get_grade_item()->get_decimals();
|
||||
$o = '';
|
||||
|
||||
if ($this->get_instance()->grade >= 0) {
|
||||
@@ -1338,7 +1337,7 @@ class assign {
|
||||
if ($grade < 0) {
|
||||
$displaygrade = '';
|
||||
} else {
|
||||
$displaygrade = format_float($grade, $decimals);
|
||||
$displaygrade = format_float($grade, $this->get_grade_item()->get_decimals());
|
||||
}
|
||||
$o .= '<label class="accesshide" for="quickgrade_' . $userid . '">' .
|
||||
get_string('usergrade', 'assign') .
|
||||
@@ -1350,7 +1349,7 @@ class assign {
|
||||
size="6"
|
||||
maxlength="10"
|
||||
class="quickgrade"/>';
|
||||
$o .= ' / ' . format_float($this->get_instance()->grade, $decimals);
|
||||
$o .= ' / ' . format_float($this->get_instance()->grade, $this->get_grade_item()->get_decimals());
|
||||
return $o;
|
||||
} else {
|
||||
if ($grade == -1 || $grade === null) {
|
||||
@@ -1360,7 +1359,7 @@ class assign {
|
||||
$o .= grade_format_gradevalue($grade, $item);
|
||||
if ($item->get_displaytype() == GRADE_DISPLAY_TYPE_REAL) {
|
||||
// If displaying the raw grade, also display the total value.
|
||||
$o .= ' / ' . format_float($this->get_instance()->grade, $decimals);
|
||||
$o .= ' / ' . format_float($this->get_instance()->grade, $item->get_decimals());
|
||||
}
|
||||
}
|
||||
return $o;
|
||||
@@ -2298,7 +2297,7 @@ class assign {
|
||||
$o = '';
|
||||
|
||||
$pluginsubtype = required_param('pluginsubtype', PARAM_ALPHA);
|
||||
$plugintype = required_param('plugin', PARAM_TEXT);
|
||||
$plugintype = required_param('plugin', PARAM_PLUGIN);
|
||||
$pluginaction = required_param('pluginaction', PARAM_ALPHA);
|
||||
|
||||
$plugin = $this->get_plugin_by_type($pluginsubtype, $plugintype);
|
||||
@@ -2372,7 +2371,7 @@ class assign {
|
||||
|
||||
$submissionid = optional_param('sid', 0, PARAM_INT);
|
||||
$gradeid = optional_param('gid', 0, PARAM_INT);
|
||||
$plugintype = required_param('plugin', PARAM_TEXT);
|
||||
$plugintype = required_param('plugin', PARAM_PLUGIN);
|
||||
$item = null;
|
||||
if ($pluginsubtype == 'assignsubmission') {
|
||||
$plugin = $this->get_submission_plugin_by_type($plugintype);
|
||||
@@ -5381,7 +5380,7 @@ class assign {
|
||||
$record->userid = $userid;
|
||||
if ($modified >= 0) {
|
||||
$record->grade = unformat_float(optional_param('quickgrade_' . $record->userid, -1, PARAM_TEXT));
|
||||
$record->workflowstate = optional_param('quickgrade_' . $record->userid.'_workflowstate', false, PARAM_TEXT);
|
||||
$record->workflowstate = optional_param('quickgrade_' . $record->userid.'_workflowstate', false, PARAM_ALPHA);
|
||||
$record->allocatedmarker = optional_param('quickgrade_' . $record->userid.'_allocatedmarker', false, PARAM_INT);
|
||||
} else {
|
||||
// This user was not in the grading table.
|
||||
@@ -6511,7 +6510,7 @@ class assign {
|
||||
$mform->setType('userid', PARAM_INT);
|
||||
|
||||
$mform->addElement('hidden', 'action', 'savesubmission');
|
||||
$mform->setType('action', PARAM_TEXT);
|
||||
$mform->setType('action', PARAM_ALPHA);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+2
-2
@@ -37,7 +37,7 @@ require_capability('mod/assign:view', $context);
|
||||
|
||||
$assign = new assign($context, $cm, $course);
|
||||
$urlparams = array('id' => $id,
|
||||
'action' => optional_param('action', '', PARAM_TEXT),
|
||||
'action' => optional_param('action', '', PARAM_ALPHA),
|
||||
'rownum' => optional_param('rownum', 0, PARAM_INT),
|
||||
'useridlistid' => optional_param('useridlistid', $assign->get_useridlist_key_id(), PARAM_ALPHANUM));
|
||||
|
||||
@@ -49,4 +49,4 @@ $completion->set_module_viewed($cm);
|
||||
|
||||
// Get the assign class to
|
||||
// render the page.
|
||||
echo $assign->view(optional_param('action', '', PARAM_TEXT));
|
||||
echo $assign->view(optional_param('action', '', PARAM_ALPHA));
|
||||
|
||||
@@ -254,9 +254,6 @@ class mod_forum_post_form extends moodleform {
|
||||
$mform->addElement('hidden', 'parent');
|
||||
$mform->setType('parent', PARAM_INT);
|
||||
|
||||
$mform->addElement('hidden', 'userid');
|
||||
$mform->setType('userid', PARAM_INT);
|
||||
|
||||
$mform->addElement('hidden', 'groupid');
|
||||
$mform->setType('groupid', PARAM_INT);
|
||||
|
||||
|
||||
+26
-11
@@ -4341,41 +4341,56 @@ function forum_add_new_post($post, $mform, $unused = null) {
|
||||
/**
|
||||
* Update a post.
|
||||
*
|
||||
* @param stdClass $post The post to update
|
||||
* @param stdClass $newpost The post to update
|
||||
* @param mixed $mform The submitted form
|
||||
* @param string $unused
|
||||
* @return bool
|
||||
*/
|
||||
function forum_update_post($post, $mform, $unused = null) {
|
||||
global $DB;
|
||||
function forum_update_post($newpost, $mform, $unused = null) {
|
||||
global $DB, $USER;
|
||||
|
||||
$post = $DB->get_record('forum_posts', array('id' => $newpost->id));
|
||||
$discussion = $DB->get_record('forum_discussions', array('id' => $post->discussion));
|
||||
$forum = $DB->get_record('forum', array('id' => $discussion->forum));
|
||||
$cm = get_coursemodule_from_instance('forum', $forum->id);
|
||||
$context = context_module::instance($cm->id);
|
||||
|
||||
// Allowed modifiable fields.
|
||||
$modifiablefields = [
|
||||
'subject',
|
||||
'message',
|
||||
'messageformat',
|
||||
'messagetrust',
|
||||
'timestart',
|
||||
'timeend',
|
||||
'pinned',
|
||||
'attachments',
|
||||
];
|
||||
foreach ($modifiablefields as $field) {
|
||||
if (isset($newpost->{$field})) {
|
||||
$post->{$field} = $newpost->{$field};
|
||||
}
|
||||
}
|
||||
$post->modified = time();
|
||||
|
||||
$DB->update_record('forum_posts', $post);
|
||||
|
||||
$discussion->timemodified = $post->modified; // last modified tracking
|
||||
$discussion->usermodified = $post->userid; // last modified tracking
|
||||
// Last post modified tracking.
|
||||
$discussion->timemodified = $post->modified;
|
||||
$discussion->usermodified = $post->userid;
|
||||
|
||||
if (!$post->parent) { // Post is a discussion starter - update discussion title and times too
|
||||
$discussion->name = $post->subject;
|
||||
$discussion->timestart = $post->timestart;
|
||||
$discussion->timeend = $post->timeend;
|
||||
}
|
||||
$post->message = file_save_draft_area_files($post->itemid, $context->id, 'mod_forum', 'post', $post->id,
|
||||
$post->message = file_save_draft_area_files($newpost->itemid, $context->id, 'mod_forum', 'post', $post->id,
|
||||
mod_forum_post_form::editor_options($context, $post->id), $post->message);
|
||||
$DB->set_field('forum_posts', 'message', $post->message, array('id'=>$post->id));
|
||||
|
||||
$DB->update_record('forum_posts', $post);
|
||||
$DB->update_record('forum_discussions', $discussion);
|
||||
|
||||
forum_add_attachment($post, $forum, $cm, $mform);
|
||||
|
||||
if (forum_tp_can_track_forums($forum) && forum_tp_is_tracked($forum)) {
|
||||
forum_tp_mark_post_read($post->userid, $post, $post->forum);
|
||||
forum_tp_mark_post_read($USER->id, $post, $forum->id);
|
||||
}
|
||||
|
||||
// Let Moodle know that assessable content is uploaded (eg for plagiarism detection)
|
||||
|
||||
@@ -2690,4 +2690,58 @@ class mod_forum_lib_testcase extends advanced_testcase {
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that {@link forum_update_post()} keeps correct forum_discussions usermodified.
|
||||
*/
|
||||
public function test_forum_update_post_keeps_discussions_usermodified() {
|
||||
global $DB;
|
||||
|
||||
$this->resetAfterTest();
|
||||
|
||||
// Let there be light.
|
||||
$teacher = self::getDataGenerator()->create_user();
|
||||
$student = self::getDataGenerator()->create_user();
|
||||
$course = self::getDataGenerator()->create_course();
|
||||
|
||||
$forum = self::getDataGenerator()->create_module('forum', (object)[
|
||||
'course' => $course->id,
|
||||
]);
|
||||
|
||||
$generator = self::getDataGenerator()->get_plugin_generator('mod_forum');
|
||||
|
||||
// Let the teacher start a discussion.
|
||||
$discussion = $generator->create_discussion((object)[
|
||||
'course' => $course->id,
|
||||
'userid' => $teacher->id,
|
||||
'forum' => $forum->id,
|
||||
]);
|
||||
|
||||
// On this freshly created discussion, the teacher is the author of the last post.
|
||||
$this->assertEquals($teacher->id, $DB->get_field('forum_discussions', 'usermodified', ['id' => $discussion->id]));
|
||||
|
||||
// Let the student reply to the teacher's post.
|
||||
$reply = $generator->create_post((object)[
|
||||
'course' => $course->id,
|
||||
'userid' => $student->id,
|
||||
'forum' => $forum->id,
|
||||
'discussion' => $discussion->id,
|
||||
'parent' => $discussion->firstpost,
|
||||
]);
|
||||
|
||||
// The student should now be the last post's author.
|
||||
$this->assertEquals($student->id, $DB->get_field('forum_discussions', 'usermodified', ['id' => $discussion->id]));
|
||||
|
||||
// Let the teacher edit the student's reply.
|
||||
$this->setUser($teacher->id);
|
||||
$newpost = (object)[
|
||||
'id' => $reply->id,
|
||||
'itemid' => 0,
|
||||
'subject' => 'Amended subject',
|
||||
];
|
||||
forum_update_post($newpost, null);
|
||||
|
||||
// The student should be still the last post's author.
|
||||
$this->assertEquals($student->id, $DB->get_field('forum_discussions', 'usermodified', ['id' => $discussion->id]));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -651,4 +651,26 @@ class repository_dropbox_legacy extends repository {
|
||||
} catch (moodle_exception $e) {}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get dropbox options
|
||||
* @param string $config
|
||||
* @return mixed
|
||||
*/
|
||||
public function get_option($config = '') {
|
||||
if ($config === 'dropbox_key') {
|
||||
return trim(get_config('dropbox', 'dropbox_key'));
|
||||
} else if ($config === 'dropbox_secret') {
|
||||
return trim(get_config('dropbox', 'dropbox_secret'));
|
||||
} else if ($config === 'dropbox_cachelimit') {
|
||||
return $this->max_cache_bytes();
|
||||
} else {
|
||||
$options = parent::get_option();
|
||||
$options['dropbox_key'] = trim(get_config('dropbox', 'dropbox_key'));
|
||||
$options['dropbox_secret'] = trim(get_config('dropbox', 'dropbox_secret'));
|
||||
$options['dropbox_cachelimit'] = $this->max_cache_bytes();
|
||||
}
|
||||
|
||||
return $options;
|
||||
}
|
||||
}
|
||||
|
||||
+32
-3
@@ -217,8 +217,8 @@ class core_user_external extends external_api {
|
||||
profile_save_data((object) $user);
|
||||
}
|
||||
|
||||
$userobject = (object)$user;
|
||||
if ($createpassword) {
|
||||
$userobject = (object)$user;
|
||||
setnew_password_and_mail($userobject);
|
||||
unset_user_preference('create_password', $userobject);
|
||||
set_user_preference('auth_forcepasswordchange', 1, $userobject);
|
||||
@@ -230,7 +230,7 @@ class core_user_external extends external_api {
|
||||
// Preferences.
|
||||
if (!empty($user['preferences'])) {
|
||||
foreach ($user['preferences'] as $preference) {
|
||||
set_user_preference($preference['type'], $preference['value'], $user['id']);
|
||||
self::set_user_preference($preference['type'], $preference['value'], $userobject);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -459,7 +459,7 @@ class core_user_external extends external_api {
|
||||
// Preferences.
|
||||
if (!empty($user['preferences'])) {
|
||||
foreach ($user['preferences'] as $preference) {
|
||||
set_user_preference($preference['type'], $preference['value'], $user['id']);
|
||||
self::set_user_preference($preference['type'], $preference['value'], $existinguser);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1453,6 +1453,35 @@ class core_user_external extends external_api {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates preference value and updates the user preference
|
||||
*
|
||||
* @param string $name
|
||||
* @param string $value
|
||||
* @param stdClass $user
|
||||
*/
|
||||
protected static function set_user_preference($name, $value, $user) {
|
||||
$preferences = array(
|
||||
'auth_forcepasswordchange' => PARAM_BOOL,
|
||||
'htmleditor' => PARAM_COMPONENT,
|
||||
'usemodchooser' => PARAM_BOOL,
|
||||
'badgeprivacysetting' => PARAM_BOOL,
|
||||
'blogpagesize' => PARAM_INT,
|
||||
'forum_markasreadonnotification' => PARAM_INT,
|
||||
'calendar_timeformat' => PARAM_NOTAGS,
|
||||
'calendar_startwday' => PARAM_INT,
|
||||
'calendar_maxevents' => PARAM_INT,
|
||||
'calendar_lookahead' => PARAM_INT,
|
||||
'calendar_persistflt' => PARAM_INT
|
||||
);
|
||||
if (isset($preferences[$name])) {
|
||||
$value = clean_param($value, $preferences[$name]);
|
||||
if ($preferences[$name] == PARAM_BOOL) {
|
||||
$value = (int)$value;
|
||||
}
|
||||
set_user_preference($name, $value, $user);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -497,7 +497,14 @@ class core_user_externallib_testcase extends externallib_advanced_testcase {
|
||||
'email' => 'usertest1@example.com',
|
||||
'description' => 'This is a description for user 1',
|
||||
'city' => 'Perth',
|
||||
'country' => 'au'
|
||||
'country' => 'au',
|
||||
'preferences' => [[
|
||||
'type' => 'htmleditor',
|
||||
'value' => 'atto'
|
||||
], [
|
||||
'type' => 'invalidpreference',
|
||||
'value' => 'abcd'
|
||||
]]
|
||||
);
|
||||
|
||||
$context = context_system::instance();
|
||||
@@ -522,6 +529,8 @@ class core_user_externallib_testcase extends externallib_advanced_testcase {
|
||||
$this->assertEquals($dbuser->description, $user1['description']);
|
||||
$this->assertEquals($dbuser->city, $user1['city']);
|
||||
$this->assertEquals($dbuser->country, $user1['country']);
|
||||
$this->assertEquals('atto', get_user_preferences('htmleditor', null, $dbuser));
|
||||
$this->assertEquals(null, get_user_preferences('invalidpreference', null, $dbuser));
|
||||
}
|
||||
|
||||
// Call without required capability
|
||||
@@ -676,7 +685,14 @@ class core_user_externallib_testcase extends externallib_advanced_testcase {
|
||||
'email' => 'usertest1@example.com',
|
||||
'description' => 'This is a description for user 1',
|
||||
'city' => 'Perth',
|
||||
'country' => 'au'
|
||||
'country' => 'au',
|
||||
'preferences' => [[
|
||||
'type' => 'htmleditor',
|
||||
'value' => 'atto'
|
||||
], [
|
||||
'type' => 'invalidpreference',
|
||||
'value' => 'abcd'
|
||||
]]
|
||||
);
|
||||
|
||||
$context = context_system::instance();
|
||||
@@ -712,6 +728,8 @@ class core_user_externallib_testcase extends externallib_advanced_testcase {
|
||||
$this->assertEquals($dbuser->description, $user1['description']);
|
||||
$this->assertEquals($dbuser->city, $user1['city']);
|
||||
$this->assertEquals($dbuser->country, $user1['country']);
|
||||
$this->assertEquals('atto', get_user_preferences('htmleditor', null, $dbuser));
|
||||
$this->assertEquals(null, get_user_preferences('invalidpreference', null, $dbuser));
|
||||
|
||||
// Call without required capability.
|
||||
$this->unassignUserCapability('moodle/user:update', $context->id, $roleid);
|
||||
|
||||
+2
-2
@@ -29,11 +29,11 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$version = 2015111607.00; // 20151116 = branching date YYYYMMDD - do not modify!
|
||||
$version = 2015111610.00; // 20151116 = branching date YYYYMMDD - do not modify!
|
||||
// RR = release increments - 00 in DEV branches.
|
||||
// .XX = incremental changes.
|
||||
|
||||
$release = '3.0.7 (Build: 20161114)'; // Human-friendly version name
|
||||
$release = '3.0.10 (Build: 20170508)'; // Human-friendly version name
|
||||
|
||||
$branch = '30'; // This version's branch.
|
||||
$maturity = MATURITY_STABLE; // This version's maturity level.
|
||||
|
||||
Reference in New Issue
Block a user