Merge branch 'MDL-74623_master_v2' of https://github.com/TomoTsuyuki/moodle

This commit is contained in:
Jun Pataleta 2022-06-23 11:55:30 +08:00
commit fc76c284b1
16 changed files with 120 additions and 14 deletions

View File

@ -44,7 +44,7 @@ class backup_forum_activity_structure_step extends backup_activity_structure_ste
'maxbytes', 'maxattachments', 'forcesubscribe', 'trackingtype',
'rsstype', 'rssarticles', 'timemodified', 'warnafter',
'blockafter', 'blockperiod', 'completiondiscussions', 'completionreplies',
'completionposts', 'displaywordcount', 'lockdiscussionafter', 'grade_forum'));
'completionposts', 'displaywordcount', 'lockdiscussionafter', 'grade_forum', 'usecoursefullname'));
$discussions = new backup_nested_element('discussions');

View File

@ -73,7 +73,8 @@ class forum {
'displaywordcount' => $forum->should_display_word_count(),
'lockdiscussionafter' => $forum->get_lock_discussions_after(),
'duedate' => $forum->get_due_date(),
'cutoffdate' => $forum->get_cutoff_date()
'cutoffdate' => $forum->get_cutoff_date(),
'usecoursefullname' => $forum->use_course_fullname()
];
}, $forums);
}

View File

@ -107,6 +107,8 @@ class forum {
private $duedate;
/** @var int $cutoffdate Timestamp after which forum posts will no longer be accepted */
private $cutoffdate;
/** @var bool $usecoursefullname Whether to use course full name instead of short name in notifications */
private $usecoursefullname;
/**
* Constructor
@ -144,6 +146,7 @@ class forum {
* @param int $lockdiscussionafter Timestamp after which discussions should be locked
* @param int $duedate Timestamp that represents the due date for forum posts
* @param int $cutoffdate Timestamp after which forum posts will no longer be accepted
* @param bool $usecoursefullname Whether to use course full name instead of short name in notifications
*/
public function __construct(
context $context,
@ -178,7 +181,8 @@ class forum {
bool $displaywordcount,
int $lockdiscussionafter,
int $duedate,
int $cutoffdate
int $cutoffdate,
bool $usecoursefullname = false
) {
$this->context = $context;
$this->coursemodule = $coursemodule;
@ -213,6 +217,7 @@ class forum {
$this->lockdiscussionafter = $lockdiscussionafter;
$this->duedate = $duedate;
$this->cutoffdate = $cutoffdate;
$this->usecoursefullname = $usecoursefullname;
}
/**
@ -669,4 +674,13 @@ class forum {
return $this->is_discussion_time_locked($discussion);
}
/**
* Should use course full name instead of short name in notifications?
*
* @return bool
*/
public function use_course_fullname(): bool {
return $this->usecoursefullname;
}
}

View File

@ -104,7 +104,8 @@ class entity {
$record->displaywordcount,
$record->lockdiscussionafter,
$record->duedate,
$record->cutoffdate
$record->cutoffdate,
$record->usecoursefullname ?? false
);
}

View File

@ -155,7 +155,7 @@ class forum_post implements \renderable, \templatable {
$data = $this->export_for_template_shared($renderer);
return $data + array(
'id' => html_entity_decode($this->post->id),
'coursename' => html_entity_decode($this->get_coursename()),
'coursename' => html_entity_decode($this->get_forum_coursename()),
'courselink' => html_entity_decode($this->get_courselink()),
'forumname' => html_entity_decode($this->get_forumname()),
'showdiscussionname' => html_entity_decode($this->get_showdiscussionname()),
@ -197,7 +197,7 @@ class forum_post implements \renderable, \templatable {
$data = $this->export_for_template_shared($renderer);
return $data + array(
'id' => $this->post->id,
'coursename' => $this->get_coursename(),
'coursename' => $this->get_forum_coursename(),
'courselink' => $this->get_courselink(),
'forumname' => $this->get_forumname(),
'showdiscussionname' => $this->get_showdiscussionname(),
@ -485,6 +485,19 @@ class forum_post implements \renderable, \templatable {
));
}
/**
* The name of the course that the forum is in, based on forum setting.
*
* @return string
*/
public function get_forum_coursename() {
if ($this->forum->usecoursefullname) {
return $this->get_coursefullname();
} else {
return $this->get_coursename();
}
}
/**
* The name of the forum.
*

View File

@ -327,8 +327,7 @@ class send_user_notifications extends \core\task\adhoc_task {
'sitefullname' => format_string($site->fullname),
'siteshortname' => format_string($site->shortname),
'courseidnumber' => $data->get_courseidnumber(),
'coursefullname' => $data->get_coursefullname(),
'courseshortname' => $data->get_coursename(),
'coursename' => $data->get_forum_coursename(),
];
$postsubject = html_to_text(get_string('postmailsubject', 'forum', $a), 0);

View File

@ -35,6 +35,7 @@
<FIELD NAME="completionposts" TYPE="int" LENGTH="9" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="Nonzero if a certain number of posts or replies (total) are required to mark this forum complete for a user."/>
<FIELD NAME="displaywordcount" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
<FIELD NAME="lockdiscussionafter" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
<FIELD NAME="usecoursefullname" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>

View File

@ -338,5 +338,18 @@ function xmldb_forum_upgrade($oldversion) {
// Automatically generated Moodle v4.0.0 release upgrade line.
// Put any upgrade step following this.
if ($oldversion < 2022041901) {
// Define field usecoursefullname to be added to forum.
$table = new xmldb_table('forum');
$field = new xmldb_field('usecoursefullname', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '0',
'lockdiscussionafter');
// Conditionally launch add field usecoursefullname.
if (!$dbman->field_exists($table, $field)) {
$dbman->add_field($table, $field);
}
upgrade_mod_savepoint(true, 2022041901, 'forum');
}
return true;
}

View File

@ -159,6 +159,7 @@ class mod_forum_external extends external_api {
'numdiscussions' => new external_value(PARAM_INT, 'Number of discussions in the forum', VALUE_OPTIONAL),
'cancreatediscussions' => new external_value(PARAM_BOOL, 'If the user can create discussions', VALUE_OPTIONAL),
'lockdiscussionafter' => new external_value(PARAM_INT, 'After what period a discussion is locked', VALUE_OPTIONAL),
'usecoursefullname' => new external_value(PARAM_INT, 'Whether to use course full name for notifications'),
'istracked' => new external_value(PARAM_BOOL, 'If the user is tracking the forum', VALUE_OPTIONAL),
'unreadpostscount' => new external_value(PARAM_INT, 'The number of unread posts for tracked forums',
VALUE_OPTIONAL),

View File

@ -138,6 +138,7 @@ $string['configsubscriptiontype'] = 'Default setting for subscription mode.';
$string['configshortpost'] = 'Any post under this length (in characters not including HTML) is considered short (see below).';
$string['configtrackingtype'] = 'Default setting for read tracking.';
$string['configtrackreadposts'] = 'Set to \'yes\' if you want to track read/unread for each user.';
$string['configusecoursefullname'] = 'Default setting to use course full name instead of course short name for notifications.';
$string['configusermarksread'] = 'If \'yes\', the user must manually mark a post as read. If \'no\', when the post is viewed it is marked as read.';
$string['confirmsubscribediscussion'] = 'Do you really want to subscribe to discussion \'{$a->discussion}\' in forum \'{$a->forum}\'?';
$string['confirmunsubscribediscussion'] = 'Do you really want to unsubscribe from discussion \'{$a->discussion}\' in forum \'{$a->forum}\'?';
@ -524,7 +525,7 @@ $string['postincontext'] = 'See this post in context';
$string['postmailinfo'] = 'This is a copy of a message posted in {$a}.';
$string['postmailnow'] = '<p>This post will be mailed out immediately to all forum subscribers.</p>';
$string['postmailreply'] = 'To reply click on this link: {$a}';
$string['postmailsubject'] = '{$a->courseshortname}: {$a->subject}';
$string['postmailsubject'] = '{$a->coursename}: {$a->subject}';
$string['postrating1'] = 'Mostly separate knowing';
$string['postrating2'] = 'Separate and connected';
$string['postrating3'] = 'Mostly connected knowing';
@ -743,6 +744,8 @@ $string['unsubscribealldone'] = 'All optional forum subscriptions were removed.
$string['unsubscribeallempty'] = 'You are not subscribed to any forums. To disable all notifications from this server go to Messaging in My Profile Settings.';
$string['unsubscribed'] = 'Unsubscribed';
$string['unsubscribeshort'] = 'Unsubscribe';
$string['usecoursefullname'] = 'Use course full name in notifications';
$string['usecoursefullname_help'] = 'Use course full name instead of course short name for notifications.';
$string['useexperimentalui'] = 'Use experimental nested discussion view';
$string['usermarksread'] = 'Manual message read marking';
$string['usernavigation'] = 'User navigation';

View File

@ -184,6 +184,10 @@ function forum_update_instance($forum, $mform) {
$forum->assesstimefinish = 0;
}
if (empty($forum->usecoursefullname)) {
$forum->usecoursefullname = 0;
}
$oldforum = $DB->get_record('forum', array('id'=>$forum->id));
// MDL-3942 - if the aggregation type or scale (i.e. max grade) changes then recalculate the grades for the entire forum
@ -592,7 +596,7 @@ function forum_print_recent_activity($course, $viewfullnames, $timestart) {
f.scale, f.grade_forum, f.maxbytes, f.maxattachments, f.forcesubscribe,
f.trackingtype, f.rsstype, f.rssarticles, f.timemodified, f.warnafter, f.blockafter,
f.blockperiod, f.completiondiscussions, f.completionreplies, f.completionposts,
f.displaywordcount, f.lockdiscussionafter, f.grade_forum_notify,
f.displaywordcount, f.lockdiscussionafter, f.grade_forum_notify, f.usecoursefullname,
d.name AS discussionname, d.firstpost, d.userid AS discussionstarter,
d.assessed AS discussionassessed, d.timemodified, d.usermodified, d.forum, d.groupid,
d.timestart, d.timeend, d.pinned, d.timelocked,
@ -684,7 +688,8 @@ function forum_print_recent_activity($course, $viewfullnames, $timestart) {
'completionposts' => $post->completionposts,
'displaywordcount' => $post->displaywordcount,
'lockdiscussionafter' => $post->lockdiscussionafter,
'grade_forum_notify' => $post->grade_forum_notify
'grade_forum_notify' => $post->grade_forum_notify,
'usecoursefullname' => $post->usecoursefullname
];
// Build the forum entity from the factory.
$forumentity = $entityfactory->get_forum_from_stdclass($forumrecord, $context, $coursemodule, $course);

View File

@ -126,6 +126,10 @@ class mod_forum_mod_form extends moodleform_mod {
}
$mform->setDefault('trackingtype', $default);
$mform->addElement('checkbox', 'usecoursefullname', get_string('usecoursefullname', 'forum'), null);
$mform->addHelpButton('usecoursefullname', 'usecoursefullname', 'forum');
$mform->setDefault('usecoursefullname', $CFG->forum_usecoursefullname);
if ($CFG->enablerssfeeds && isset($CFG->forum_enablerssfeeds) && $CFG->forum_enablerssfeeds) {
//-------------------------------------------------------------------------------
$mform->addElement('header', 'rssheader', get_string('rss'));

View File

@ -95,6 +95,10 @@ if ($ADMIN->fulltree) {
$settings->add(new admin_setting_configselect('digestmailtime', get_string('digestmailtime', 'forum'),
get_string('configdigestmailtime', 'forum'), 17, $options));
// Use full course name for notification.
$settings->add(new admin_setting_configcheckbox('forum_usecoursefullname', get_string('usecoursefullname', 'forum'),
get_string('configusecoursefullname', 'forum'), 0));
if (empty($CFG->enablerssfeeds)) {
$options = array(0 => get_string('rssglobaldisabled', 'admin'));
$str = get_string('configenablerssfeeds', 'forum').'<br />'.get_string('configenablerssfeedsdisabled2', 'admin');

View File

@ -90,6 +90,7 @@ class entities_forum_test extends \advanced_testcase {
$lockdiscussionafter = 0;
$duedate = 0;
$cutoffdate = 0;
$usecoursefullname = 0;
$sendnotification = false;
$forum = new forum_entity(
$context,
@ -124,7 +125,8 @@ class entities_forum_test extends \advanced_testcase {
$displaywordcount,
$lockdiscussionafter,
$duedate,
$cutoffdate
$cutoffdate,
$usecoursefullname
);
$this->assertEquals($context, $forum->get_context());
@ -167,5 +169,6 @@ class entities_forum_test extends \advanced_testcase {
$this->assertEquals(false, $forum->is_due_date_reached());
$this->assertEquals(false, $forum->has_cutoff_date());
$this->assertEquals(false, $forum->is_cutoff_date_reached());
$this->assertEquals(false, $forum->use_course_fullname());
}
}

View File

@ -910,7 +910,7 @@ class mail_test extends \advanced_testcase {
// Post a discussion to the forum.
$subject = 'This is the very long forum post subject that somebody was very kind of leaving, it is intended to check if long subject comes in mail correctly. Thank you.';
$a = (object)array('courseshortname' => $course->shortname, 'forumname' => $forum->name, 'subject' => $subject);
$a = (object)array('coursename' => $course->shortname, 'forumname' => $forum->name, 'subject' => $subject);
$expectedsubject = get_string('postmailsubject', 'forum', $a);
list($discussion, $post) = $this->helper_post_to_forum($forum, $author, array('name' => $subject));
@ -930,6 +930,50 @@ class mail_test extends \advanced_testcase {
$this->assertEquals($expectedsubject, $message->subject);
}
/**
* Test usecoursefullname option for notification.
*
* @covers \mod_forum\task\send_user_notifications
*/
public function test_usecoursefullname() {
$this->resetAfterTest();
$record = [];
$record['fullname'] = 'Test Course Full Name';
$record['shortname'] = 'Shortname';
// Create a course, with a forum.
$course = $this->getDataGenerator()->create_course($record);
$options = array('course' => $course->id, 'forcesubscribe' => FORUM_FORCESUBSCRIBE, 'usecoursefullname' => true);
$forum = $this->getDataGenerator()->create_module('forum', $options);
// Create a user enrolled in the course as student.
list($author) = $this->helper_create_users($course, 1);
// Post a discussion to the forum.
$subject = 'This is the forum post subject.';
// Expect coursefullname instead of shortname.
$a = (object)array('coursename' => $course->fullname, 'subject' => $subject);
$expectedsubject = get_string('postmailsubject', 'forum', $a);
list($discussion, $post) = $this->helper_post_to_forum($forum, $author, array('name' => $subject));
// Run cron and check that the expected number of users received the notification.
$expect = [
'author' => (object) [
'userid' => $author->id,
'messages' => 1,
],
];
$this->queue_tasks_and_assert($expect);
$this->send_notifications_and_assert($author, [$post]);
$messages = $this->messagesink->get_messages();
$this->assertEquals($expectedsubject, $messages[0]->subject);
$this->assertStringContainsString($course->fullname, $messages[0]->fullmessage);
$this->assertStringContainsString($course->fullname, $messages[0]->fullmessagehtml);
}
/**
* Test inital email and reply email subjects
*/

View File

@ -24,6 +24,6 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2022041900; // The current module version (Date: YYYYMMDDXX).
$plugin->version = 2022041901; // The current module version (Date: YYYYMMDDXX).
$plugin->requires = 2022041200; // Requires this Moodle version.
$plugin->component = 'mod_forum'; // Full name of the plugin (used for diagnostics)