MDL-64820 forum: add subscription toggling to discussion list

This commit is contained in:
Ryan Wyllie 2019-03-11 09:43:13 +08:00
parent 47d38303cf
commit 2646e9d6d2
13 changed files with 350 additions and 4 deletions

View File

@ -0,0 +1 @@
define(["mod_forum/subscription_toggle"],function(a){return{init:function(b){a.init(b)}}});

1
mod/forum/amd/build/repository.min.js vendored Normal file
View File

@ -0,0 +1 @@
define(["core/ajax"],function(a){var b=function(b,c,d){var e={methodname:"mod_forum_set_subscription_state",args:{forumid:b,discussionid:c,targetstate:d}};return a.call([e])[0]};return{setDiscussionSubscriptionState:b}});

1
mod/forum/amd/build/selectors.min.js vendored Normal file
View File

@ -0,0 +1 @@
define([],function(){return{subscription:{toggle:"[data-type='subscription-toggle'][data-action='toggle']"}}});

View File

@ -0,0 +1 @@
define(["jquery","core/templates","core/notification","mod_forum/repository","mod_forum/selectors"],function(a,b,c,d,e){var f=function(f){f.on("click",e.subscription.toggle,function(e){var f=a(this),g=f.data("forumid"),h=f.data("discussionid"),i=f.data("targetstate");d.setDiscussionSubscriptionState(g,h,i).then(function(a){return b.render("mod_forum/discussion_subscription_toggle",a)}).then(function(a,c){return b.replaceNode(f,a,c)})["catch"](c.exception),e.preventDefault()})};return{init:function(a){f(a)}}});

View File

@ -0,0 +1,30 @@
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Module for the list of discussions on when viewing a forum.
*
* @module mod_forum/discussion_list
* @package mod_forum
* @copyright 2019 Andrew Nicols <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
define(['mod_forum/subscription_toggle'], function(SubscriptionToggle) {
return {
init: function(root) {
SubscriptionToggle.init(root);
}
};
});

View File

@ -0,0 +1,49 @@
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Forum repository class to encapsulate all of the AJAX requests that
* can be sent for forum.
*
* @module mod_forum/repository
* @package mod_forum
* @copyright 2019 Andrew Nicols <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
define(['core/ajax'], function(Ajax) {
/**
* Set the subscription state for a discussion in a forum.
*
* @param {number} forumId ID of the forum the discussion belongs to
* @param {number} discussionId ID of the discussion with the subscription state
* @param {boolean} targetState Set the subscribed state. True == subscribed; false == unsubscribed.
* @return {object} jQuery promise
*/
var setDiscussionSubscriptionState = function(forumId, discussionId, targetState) {
var request = {
methodname: 'mod_forum_set_subscription_state',
args: {
forumid: forumId,
discussionid: discussionId,
targetstate: targetState
}
};
return Ajax.call([request])[0];
};
return {
setDiscussionSubscriptionState: setDiscussionSubscriptionState,
};
});

View File

@ -0,0 +1,30 @@
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Common CSS selectors for the forum UI.
*
* @module mod_forum/selectors
* @package mod_forum
* @copyright 2019 Andrew Nicols <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
define([], function() {
return {
subscription: {
toggle: "[data-type='subscription-toggle'][data-action='toggle']",
}
};
});

View File

@ -0,0 +1,69 @@
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Handle discussion subscription toggling on a discussion list in
* the forum view.
*
* @module mod_forum/subscription_toggle
* @package mod_forum
* @copyright 2019 Andrew Nicols <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
define([
'jquery',
'core/templates',
'core/notification',
'mod_forum/repository',
'mod_forum/selectors',
], function(
$,
Templates,
Notification,
Repository,
Selectors
) {
/**
* Register event listeners for the subscription toggle.
*
* @param {object} root The discussion list root element
*/
var registerEventListeners = function(root) {
root.on('click', Selectors.subscription.toggle, function(e) {
var toggleElement = $(this);
var forumId = toggleElement.data('forumid');
var discussionId = toggleElement.data('discussionid');
var subscriptionState = toggleElement.data('targetstate');
Repository.setDiscussionSubscriptionState(forumId, discussionId, subscriptionState)
.then(function(context) {
return Templates.render('mod_forum/discussion_subscription_toggle', context);
})
.then(function(html, js) {
return Templates.replaceNode(toggleElement, html, js);
})
.catch(Notification.exception);
e.preventDefault();
});
};
return {
init: function(root) {
registerEventListeners(root);
}
};
});

View File

@ -113,4 +113,14 @@ $functions = array(
'type' => 'read',
'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE),
),
'mod_forum_set_subscription_state' => array(
'classname' => 'mod_forum_external',
'methodname' => 'set_subscription_state',
'classpath' => 'mod/forum/externallib.php',
'description' => 'Set the subscription state',
'type' => 'write',
'ajax' => true,
'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE),
),
);

View File

@ -1258,4 +1258,89 @@ class mod_forum_external extends external_api {
return new external_single_structure($structure);
}
/**
* Set the subscription state.
*
* @param int $forumid
* @param int $discussionid
* @param bool $targetstate
* @return \stdClass
*/
public static function set_subscription_state($forumid, $discussionid, $targetstate) {
global $DB, $PAGE, $USER;
$params = self::validate_parameters(self::set_subscription_state_parameters(), [
'forumid' => $forumid,
'discussionid' => $discussionid,
'targetstate' => $targetstate
]);
$vaultfactory = mod_forum\local\container::get_vault_factory();
$forumvault = $vaultfactory->get_forum_vault();
$forum = $forumvault->get_from_id($params['forumid']);
$course = $forum->get_course_record();
$coursemodule = $forum->get_course_module_record();
self::validate_context($forum->get_context());
$managerfactory = mod_forum\local\container::get_manager_factory();
$capabilitymanager = $managerfactory->get_capability_manager($forum);
$discussionvault = $vaultfactory->get_discussion_vault();
$discussion = $discussionvault->get_from_id($params['discussionid']);
$legacydatamapperfactory = mod_forum\local\container::get_legacy_data_mapper_factory();
$forumrecord = $legacydatamapperfactory->get_forum_data_mapper()->to_legacy_object($forum);
$discussionrecord = $legacydatamapperfactory->get_discussion_data_mapper()->to_legacy_object($discussion);
if (!\mod_forum\subscriptions::is_subscribable($forumrecord)) {
// Nothing to do. We won't actually output any content here though.
throw new \moodle_exception('cannotsubscribe', 'mod_forum');
}
$issubscribed = \mod_forum\subscriptions::is_subscribed(
$USER->id,
$forumrecord,
$discussion->get_id(),
$coursemodule
);
// If the current state doesn't equal the desired state then update the current
// state to the desired state.
if ($issubscribed != (bool) $params['targetstate']) {
if ($params['targetstate']) {
\mod_forum\subscriptions::subscribe_user_to_discussion($USER->id, $discussionrecord, $context);
} else {
\mod_forum\subscriptions::unsubscribe_user_from_discussion($USER->id, $discussionrecord, $context);
}
}
$exporterfactory = mod_forum\local\container::get_exporter_factory();
$exporter = $exporterfactory->get_discussion_exporter($USER, $forum, $discussion);
return $exporter->export($PAGE->get_renderer('mod_forum'));
}
/**
* Returns description of method parameters.
*
* @return external_function_parameters
*/
public static function set_subscription_state_parameters() {
return new external_function_parameters(
[
'forumid' => new external_value(PARAM_INT, 'Forum that the discussion is in'),
'discussionid' => new external_value(PARAM_INT, 'The discussion to subscribe or unsubscribe'),
'targetstate' => new external_value(PARAM_BOOL, 'The target state')
]
);
}
/**
* Returns description of method result value.
*
* @return external_description
*/
public static function set_subscription_state_returns() {
return \mod_forum\local\exporters\discussion::get_read_structure();
}
}

View File

@ -32,7 +32,7 @@
{
}
}}
<span id="{{uniqid}}">
<div id="discussion-list-{{uniqid}}">
{{{groupchangemenu}}}
{{#notifications}}
@ -70,6 +70,9 @@
{{/forum.userstate.tracked}}
{{/forum.capabilities.viewdiscussions}}
<th scope="col" class="lastpost">{{#str}}lastpost, mod_forum{{/str}}</th>
{{#forum.capabilities.subscribe}}
<th scope="col" class="discussionsubscription"></th>
{{/forum.capabilities.subscribe}}
</tr>
</thead>
{{/discussion_list_header}}
@ -176,6 +179,11 @@
</div>
{{/latestpostid}}
</td>
<td scope="col" class="p-0 align-middle">
{{#discussion}}
{{> mod_forum/discussion_subscription_toggle}}
{{/discussion}}
</td>
</tr>
{{/summaries}}
</tbody>
@ -201,5 +209,10 @@
</div>
{{/state.hasdiscussions}}
</span>
</div>
{{#js}}
require(['jquery', 'mod_forum/discussion_list'], function($, View) {
var root = $('#discussion-list-{{uniqid}}');
View.init(root);
});
{{/js}}

View File

@ -0,0 +1,56 @@
{{!
This file is part of Moodle - http://moodle.org/
Moodle is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Moodle is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Moodle. If not, see <http://www.gnu.org/licenses/>.
}}
{{!
@template mod_forum/discussion_subscription_toggle
Template to display the discussion subscription toggle.
Classes required for JS:
* none
Data attributes required for JS:
* none
Context variables required for this template:
* TODO
Example context (json):
{
}
}}
{{#capabilities.subscribe}}
<button
class="p-3 btn btn-link"
data-type="subscription-toggle"
data-action="toggle"
data-discussionid="{{id}}"
data-forumid="{{forumid}}"
{{#userstate.subscribed}}
data-targetstate="0"
{{/userstate.subscribed}}
{{^userstate.subscribed}}
data-targetstate="1"
{{/userstate.subscribed}}
>
{{#userstate.subscribed}}
{{#pix}}t/subscribed, mod_forum, {{#str}}clicktounsubscribe, mod_forum{{/str}}{{/pix}}
{{/userstate.subscribed}}
{{^userstate.subscribed}}
{{#pix}}t/unsubscribed, mod_forum, {{#str}}clicktosubscribe, mod_forum{{/str}}{{/pix}}
{{/userstate.subscribed}}
</button>
{{/capabilities.subscribe}}

View File

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