Skip to content

Commit

Permalink
MDL-65032 mod_forum: Add discussion locking functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
Peter committed Apr 24, 2019
1 parent 082740b commit 2893812
Show file tree
Hide file tree
Showing 28 changed files with 435 additions and 23 deletions.
1 change: 1 addition & 0 deletions mod/forum/amd/build/lock_toggle.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion mod/forum/amd/build/repository.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion mod/forum/amd/build/selectors.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

68 changes: 68 additions & 0 deletions mod/forum/amd/src/lock_toggle.js
@@ -0,0 +1,68 @@
// 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 the manual locking of individual discussions
*
* @module mod_forum/lock_toggle
* @package mod_forum
* @copyright 2019 Peter Dias <peter@moodle.com>
* @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.lock.toggle, function(e) {
var toggleElement = $(this);
var forumId = toggleElement.data('forumid');
var discussionId = toggleElement.data('discussionid');
var state = toggleElement.data('state');

Repository.setDiscussionLockState(forumId, discussionId, state)
.then(function(context) {
return Templates.render('mod_forum/discussion_lock_toggle', context);
})
.then(function(html, js) {
return Templates.replaceNode(toggleElement, html, js);
})
.catch(Notification.exception);

e.preventDefault();
});
};

return {
init: function(root) {
registerEventListeners(root);
}
};
});
17 changes: 15 additions & 2 deletions mod/forum/amd/src/repository.js
Expand Up @@ -14,7 +14,7 @@
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.

/**
* Forum repository class to encapsulate all of the AJAX requests that
* Forum repository class to encapsulate all of the AJAX requests thatsubscribe or unsubscribe
* can be sent for forum.
*
* @module mod_forum/repository
Expand Down Expand Up @@ -56,8 +56,21 @@ define(['core/ajax'], function(Ajax) {
return Ajax.call([request])[0];
};

var setDiscussionLockState = function(forumId, discussionId, targetState) {
var request = {
methodname: 'mod_forum_set_lock_state',
args: {
forumid: forumId,
discussionid: discussionId,
targetstate: targetState
}
};
return Ajax.call([request])[0];
};

return {
setDiscussionSubscriptionState: setDiscussionSubscriptionState,
addDiscussionPost: addDiscussionPost
addDiscussionPost: addDiscussionPost,
setDiscussionLockState: setDiscussionLockState
};
});
5 changes: 4 additions & 1 deletion mod/forum/amd/src/selectors.js
Expand Up @@ -41,7 +41,10 @@ define([], function() {
inpageReplyForm: "form[data-content='inpage-reply-form']",
inpageSubmitBtn: "[data-action='forum-inpage-submit']",
repliesContainer: "[data-region='replies-container']",
modeSelect: "select[name='mode']",
modeSelect: "select[name='mode']"
},
lock: {
toggle: "[data-action='toggle'][data-type='lock-toggle']",
}
};
});
3 changes: 2 additions & 1 deletion mod/forum/classes/local/data_mappers/legacy/discussion.php
Expand Up @@ -57,7 +57,8 @@ public function to_legacy_objects(array $discussions) : array {
'usermodified' => $discussion->get_user_modified(),
'timestart' => $discussion->get_time_start(),
'timeend' => $discussion->get_time_end(),
'pinned' => $discussion->is_pinned()
'pinned' => $discussion->is_pinned(),
'locked' => $discussion->get_locked()
];
}, $discussions);
}
Expand Down
35 changes: 34 additions & 1 deletion mod/forum/classes/local/entities/discussion.php
Expand Up @@ -61,6 +61,8 @@ class discussion {
private $timeend;
/** @var bool $pinned Is the discussion pinned? */
private $pinned;
/** @var int $locked The timestamp of when the discussion was locked */
private $timelocked;

/**
* Constructor.
Expand All @@ -78,6 +80,7 @@ class discussion {
* @param int $timestart Start time for the discussion
* @param int $timeend End time for the discussion
* @param bool $pinned Is the discussion pinned?
* @param int $locked Time this discussion was locked
*/
public function __construct(
int $id,
Expand All @@ -92,7 +95,8 @@ public function __construct(
int $usermodified,
int $timestart,
int $timeend,
bool $pinned
bool $pinned,
int $locked
) {
$this->id = $id;
$this->courseid = $courseid;
Expand All @@ -107,6 +111,7 @@ public function __construct(
$this->timestart = $timestart;
$this->timeend = $timeend;
$this->pinned = $pinned;
$this->timelocked = $locked;
}

/**
Expand Down Expand Up @@ -228,6 +233,34 @@ public function is_pinned() : bool {
return $this->pinned;
}

/**
* Check if this discussion is pinned.
*
* @return bool
*/
public function get_locked() : int {
return $this->timelocked;
}

/**
* Is this discussion locked based on it's locked attribute
*
* @return bool
*/
public function is_locked() : bool {
return ($this->timelocked ? true : false);
}

/**
* Set the locked timestamp
*
* @param int $timestamp
*/
public function toggle_locked_state(int $timestamp) {
// If it is locked already then unlock else set it to the timestamp.
$this->timelocked = ($this->timelocked ? 0 : $timestamp);
}

/**
* Check if the given post is the first post in this discussion.
*
Expand Down
4 changes: 4 additions & 0 deletions mod/forum/classes/local/entities/forum.php
Expand Up @@ -545,6 +545,10 @@ public function has_lock_discussions_after() : bool {
* @return bool
*/
public function is_discussion_locked(discussion_entity $discussion) : bool {
if ($discussion->is_locked()) {
return true;
}

if (!$this->has_lock_discussions_after()) {
return false;
}
Expand Down
10 changes: 8 additions & 2 deletions mod/forum/classes/local/exporters/discussion.php
Expand Up @@ -88,19 +88,22 @@ protected static function define_other_properties() {
'modified' => ['type' => PARAM_INT],
'start' => ['type' => PARAM_INT],
'end' => ['type' => PARAM_INT],
'locked' => ['type' => PARAM_INT],
],
],
'userstate' => [
'type' => [
'subscribed' => ['type' => PARAM_BOOL],
'locked' => ['type' => PARAM_BOOL],
],
],
'capabilities' => [
'type' => [
'subscribe' => ['type' => PARAM_BOOL],
'move' => ['type' => PARAM_BOOL],
'pin' => ['type' => PARAM_BOOL],
'post' => ['type' => PARAM_BOOL]
'post' => ['type' => PARAM_BOOL],
'manage' => ['type' => PARAM_BOOL],
]
],
'urls' => [
Expand Down Expand Up @@ -186,15 +189,18 @@ protected function get_other_values(renderer_base $output) {
'modified' => $discussion->get_time_modified(),
'start' => $discussion->get_time_start(),
'end' => $discussion->get_time_end(),
'locked' => $discussion->get_locked()
],
'userstate' => [
'subscribed' => \mod_forum\subscriptions::is_subscribed($user->id, $forumrecord, $discussion->get_id()),
'locked' => $discussion->is_locked()
],
'capabilities' => [
'subscribe' => $capabilitymanager->can_subscribe_to_discussion($user, $discussion),
'move' => $capabilitymanager->can_move_discussion($user, $discussion),
'pin' => $capabilitymanager->can_pin_discussion($user, $discussion),
'post' => $capabilitymanager->can_post_in_discussion($user, $discussion)
'post' => $capabilitymanager->can_post_in_discussion($user, $discussion),
'manage' => $capabilitymanager->can_manage_forum($user)
],
'urls' => [
'view' => $urlfactory->get_discussion_view_url_from_discussion($discussion)->out(false),
Expand Down
3 changes: 2 additions & 1 deletion mod/forum/classes/local/factories/entity.php
Expand Up @@ -126,7 +126,8 @@ public function get_discussion_from_stdclass(stdClass $record) : discussion_enti
$record->usermodified,
$record->timestart,
$record->timeend,
$record->pinned
$record->pinned,
$record->timelocked
);
}

Expand Down
22 changes: 22 additions & 0 deletions mod/forum/classes/local/renderers/discussion.php
Expand Up @@ -201,6 +201,10 @@ public function render(
$exporteddiscussion['html']['pindiscussion'] = $this->get_pin_discussion_html();
}

if ($capabilities['manage']) {
$exporteddiscussion['html']['lockdiscussion'] = $this->get_lock_discussion_button_html();
}

return $this->renderer->render_from_template('mod_forum/forum_discussion', $exporteddiscussion);
}

Expand Down Expand Up @@ -274,6 +278,24 @@ private function get_subscription_button_html() : string {
return $html;
}

/**
* Get the HTML to render the subscription button.
*
* @return string
*/
private function get_lock_discussion_button_html() : string {
global $PAGE;

$forumrecord = $this->forumrecord;
$discussionrecord = $this->discussionrecord;

$html = html_writer::div(
forum_get_lock_discussion_icon($forumrecord, $discussionrecord, null, true),
'discussionlock'
);
return $html;
}

/**
* Get the HTML to render the move discussion selector and button.
*
Expand Down
16 changes: 16 additions & 0 deletions mod/forum/classes/local/vaults/discussion.php
Expand Up @@ -125,4 +125,20 @@ public function get_count_discussions_in_forum(forum_entity $forum) : ?int {
return $this->get_db()->count_records(self::TABLE, [
'forum' => $forum->get_id()]);
}

/**
* Update the discussion
*
* @param discussion_entity $discussion
* @return discussion_entity|null
*/
public function update_discussion($discussion) : ?discussion_entity {
if ($this->get_db()->update_record('forum_discussions', $discussion)) {
$records = $this->transform_db_records_to_entities([$discussion]);

return count($records) ? array_shift($records) : null;
}

return null;
}
}
1 change: 1 addition & 0 deletions mod/forum/db/install.xml
Expand Up @@ -56,6 +56,7 @@
<FIELD NAME="timestart" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
<FIELD NAME="timeend" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
<FIELD NAME="pinned" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
<FIELD NAME="timelocked" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
Expand Down
10 changes: 10 additions & 0 deletions mod/forum/db/services.php
Expand Up @@ -134,4 +134,14 @@
'ajax' => true,
'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE),
),

'mod_forum_set_lock_state' => array(
'classname' => 'mod_forum_external',
'methodname' => 'set_lock_state',
'classpath' => 'mod/forum/externallib.php',
'description' => 'Set the lock state for the discussion',
'type' => 'write',
'ajax' => true,
'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE),
),
);
16 changes: 14 additions & 2 deletions mod/forum/db/upgrade.php
Expand Up @@ -114,7 +114,6 @@ function xmldb_forum_upgrade($oldversion) {
$dbman->add_field($table, $field);
}

// Forum savepoint reached.
upgrade_mod_savepoint(true, 2019031200, 'forum');
}

Expand All @@ -138,9 +137,22 @@ function xmldb_forum_upgrade($oldversion) {
$dbman->add_field($table, $field);
}

// Forum savepoint reached.
upgrade_mod_savepoint(true, 2019040400, 'forum');
}

if ($oldversion < 2019040401) {
// Define field deleted to be added to forum_posts.
$table = new xmldb_table('forum_discussions');
$field = new xmldb_field('timelocked', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0', 'pinned');

// Conditionally launch add field deleted.
if (!$dbman->field_exists($table, $field)) {
$dbman->add_field($table, $field);
}

// Forum savepoint reached.
upgrade_mod_savepoint(true, 2019040401, 'forum');
}

return true;
}

0 comments on commit 2893812

Please sign in to comment.