Compare commits
25 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 008248c5b1 | |||
| b34eca2f9e | |||
| 1f2a60e458 | |||
| 7f54185c69 | |||
| 54b3003c92 | |||
| 43235c6236 | |||
| 3bb94d6919 | |||
| d6cf0e56d1 | |||
| 6ee6517142 | |||
| d88aa76c77 | |||
| 3f3e62e4fc | |||
| 7815c64b0c | |||
| a444a47d14 | |||
| 9267c05fb1 | |||
| 172d31e9a5 | |||
| 76523cdfa9 | |||
| 4733c7050b | |||
| 98bb032ead | |||
| 12eeadd914 | |||
| 1504e9b81e | |||
| 7bef8b0693 | |||
| 4120362395 | |||
| 8c35f12a8f | |||
| f81c6fdec8 | |||
| d92b0800d4 |
@@ -27,9 +27,12 @@ if (isloggedin()) {
|
||||
$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);
|
||||
|
||||
|
||||
|
||||
@@ -82,7 +82,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');
|
||||
}
|
||||
|
||||
@@ -1605,7 +1605,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í';
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -111,6 +111,9 @@ class behat_util extends testing_util {
|
||||
// Disable some settings that are not wanted on test sites.
|
||||
set_config('noemailever', 1);
|
||||
|
||||
// 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
@@ -5838,6 +5838,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)) {
|
||||
@@ -5855,17 +5867,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'));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9647,6 +9670,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
|
||||
*
|
||||
|
||||
@@ -2949,4 +2949,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)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -567,4 +567,19 @@ EXPECTED;
|
||||
$this->assertSame($expected, strip_pluginfile_content($source));
|
||||
}
|
||||
|
||||
/**
|
||||
* 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"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2275,6 +2275,12 @@ function check_database_tables_row_format(environment_results $result) {
|
||||
*/
|
||||
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";
|
||||
|
||||
@@ -31,7 +31,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));
|
||||
|
||||
@@ -780,7 +780,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)
|
||||
)
|
||||
)
|
||||
@@ -1036,7 +1036,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')
|
||||
)
|
||||
)
|
||||
|
||||
@@ -2212,7 +2212,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);
|
||||
@@ -2268,7 +2268,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);
|
||||
@@ -5119,7 +5119,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.
|
||||
@@ -6213,7 +6213,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
@@ -28,7 +28,7 @@ require_once($CFG->dirroot . '/mod/assign/locallib.php');
|
||||
$id = required_param('id', PARAM_INT);
|
||||
|
||||
$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('action', 0, PARAM_INT));
|
||||
|
||||
@@ -50,4 +50,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));
|
||||
|
||||
@@ -218,9 +218,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);
|
||||
|
||||
|
||||
+24
-10
@@ -4483,41 +4483,55 @@ function forum_add_new_post($post, $mform, &$message) {
|
||||
* @global object
|
||||
* @global object
|
||||
* @global object
|
||||
* @param object $post
|
||||
* @param object $newpost
|
||||
* @param mixed $mform
|
||||
* @param string $message
|
||||
* @return bool
|
||||
*/
|
||||
function forum_update_post($post, $mform, &$message) {
|
||||
function forum_update_post($newpost, $mform, &$message) {
|
||||
global $USER, $CFG, $DB;
|
||||
|
||||
$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',
|
||||
'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, $message);
|
||||
|
||||
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)
|
||||
|
||||
@@ -940,4 +940,56 @@ 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, $message);
|
||||
|
||||
// The student should be still the last post's author.
|
||||
$this->assertEquals($student->id, $DB->get_field('forum_discussions', 'usermodified', ['id' => $discussion->id]));
|
||||
}
|
||||
}
|
||||
|
||||
+32
-2
@@ -203,8 +203,9 @@ class core_user_external extends external_api {
|
||||
|
||||
// Preferences.
|
||||
if (!empty($user['preferences'])) {
|
||||
$userobject = (object)$user;
|
||||
foreach ($user['preferences'] as $preference) {
|
||||
set_user_preference($preference['type'], $preference['value'], $user['id']);
|
||||
self::set_user_preference($preference['type'], $preference['value'], $userobject);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -433,7 +434,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1176,6 +1177,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -478,7 +478,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();
|
||||
@@ -503,6 +510,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
|
||||
@@ -657,7 +666,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();
|
||||
@@ -693,6 +709,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 = 2014051217.00; // 20140512 = branching date YYYYMMDD - do not modify!
|
||||
$version = 2014051219.00; // 20140512 = branching date YYYYMMDD - do not modify!
|
||||
// RR = release increments - 00 in DEV branches.
|
||||
// .XX = incremental changes.
|
||||
|
||||
$release = '2.7.17 (Build: 20161114)'; // Human-friendly version name
|
||||
$release = '2.7.19 (Build: 20170313)'; // Human-friendly version name
|
||||
|
||||
$branch = '27'; // This version's branch.
|
||||
$maturity = MATURITY_STABLE; // This version's maturity level.
|
||||
|
||||
Reference in New Issue
Block a user