Skip to content

Commit

Permalink
MDL-22077 forum: Update post.php to respect private replies
Browse files Browse the repository at this point in the history
  • Loading branch information
andrewnicols authored and Peter committed Apr 4, 2019
1 parent bc4c733 commit 15dc885
Show file tree
Hide file tree
Showing 11 changed files with 797 additions and 291 deletions.
2 changes: 1 addition & 1 deletion mod/forum/classes/local/managers/capability.php
Expand Up @@ -346,7 +346,7 @@ public function can_view_post(stdClass $user, discussion_entity $discussion, pos
*
*/
public function can_view_post_shell(stdClass $user, post_entity $post) : bool {
if (empty($post->get_private_reply_recipient_id())) {
if (!$post->is_private_reply()) {
return true;
}

Expand Down
37 changes: 37 additions & 0 deletions mod/forum/classes/local/vaults/forum.php
Expand Up @@ -155,4 +155,41 @@ public function get_from_course_module_ids(array $ids) : array {

return $this->transform_db_records_to_entities($records);
}

/**
* Get the forum entity for the given post id.
*
* @param int $id The course module id
* @return forum_entity|null
*/
public function get_from_post_id(int $id) : ?forum_entity {
$db = $this->get_db();
$alias = $this->get_table_alias();
$tablefields = $db->get_preload_columns(self::TABLE, $alias);
$coursemodulefields = $db->get_preload_columns('course_modules', 'cm_');
$coursefields = $db->get_preload_columns('course', 'c_');

$fields = implode(', ', [
$db->get_preload_columns_sql($tablefields, $alias),
context_helper::get_preload_record_columns_sql('ctx'),
$db->get_preload_columns_sql($coursemodulefields, 'cm'),
$db->get_preload_columns_sql($coursefields, 'c'),
]);

$tables = "{forum_posts} p";
$tables .= " JOIN {forum_discussions} d ON d.id = p.discussion";
$tables .= ' JOIN {' . self::TABLE . "} {$alias} ON {$alias}.id = d.forum";
$tables .= " JOIN {modules} m ON m.name = 'forum'";
$tables .= " JOIN {course_modules} cm ON cm.module = m.id AND cm.instance = {$alias}.id";
$tables .= ' JOIN {context} ctx ON ctx.contextlevel = ' . CONTEXT_MODULE . ' AND ctx.instanceid = cm.id';
$tables .= " JOIN {course} c ON c.id = {$alias}.course";

$sql = "SELECT {$fields} FROM {$tables} WHERE p.id = :postid";
$records = $this->get_db()->get_records_sql($sql, [
'postid' => $id,
]);

$records = $this->transform_db_records_to_entities($records);
return count($records) ? array_shift($records) : null;
}
}
56 changes: 55 additions & 1 deletion mod/forum/classes/local/vaults/post.php
Expand Up @@ -265,6 +265,59 @@ public function get_reply_count_for_discussion_ids(stdClass $user, array $discus
return $this->get_db()->get_records_sql_menu($sql, array_merge($params, $privateparams));
}

/**
* Get a mapping of replies to the specified discussions.
*
* @param stdClass $user The user to check the unread count for
* @param int $postid The post to collect replies to
* @param int $discussionid The list of discussions to fetch counts for
* @param bool $canseeprivatereplies Whether this user can see all private replies or not
* @return int The number of replies for each discussion returned in an associative array
*/
public function get_reply_count_for_post_id_in_discussion_id(
stdClass $user, int $postid, int $discussionid, bool $canseeprivatereplies) : int {
[
'where' => $privatewhere,
'params' => $privateparams,
] = $this->get_private_reply_sql($user, $canseeprivatereplies);

$alias = $this->get_table_alias();
$table = self::TABLE;

$sql = "SELECT {$alias}.id, {$alias}.parent
FROM {{$table}} {$alias}
WHERE p.discussion = :discussionid {$privatewhere}";

$postparents = $this->get_db()->get_records_sql_menu($sql, array_merge([
'discussionid' => $discussionid,
], $privateparams));

return $this->count_children_from_parent_recursively($postparents, $postid);
}

/**
* Count the children whose parent matches the current record recursively.
*
* @param array $postparents The full mapping of posts.
* @param int $postid The ID to check for
* @return int $count
*/
private function count_children_from_parent_recursively(array $postparents, int $postid) : int {
if (!isset($postparents[$postid])) {
// Post not found at all.
return 0;
}

$count = 0;
foreach ($postparents as $pid => $parentid) {
if ($postid == $parentid) {
$count += $this->count_children_from_parent_recursively($postparents, $pid) + 1;
}
}

return $count;
}

/**
* Get a mapping of unread post counts for the specified discussions.
*
Expand Down Expand Up @@ -308,7 +361,8 @@ public function get_unread_count_for_discussion_ids(stdClass $user, array $discu
* @param bool $canseeprivatereplies Whether this user can see all private replies or not
* @return int[] The post id of the most recent post for each discussions returned in an associative array
*/
public function get_latest_post_id_for_discussion_ids(stdClass $user, array $discussionids, bool $canseeprivatereplies) : array {
public function get_latest_post_id_for_discussion_ids(
stdClass $user, array $discussionids, bool $canseeprivatereplies) : array {
global $CFG;

if (empty($discussionids)) {
Expand Down
30 changes: 30 additions & 0 deletions mod/forum/deprecatedlib.php
Expand Up @@ -1620,3 +1620,33 @@ function forum_print_latest_discussions($course, $forum, $maxdiscussions = -1, $
echo $OUTPUT->paging_bar($numdiscussions, $page, $perpage, "view.php?f=$forum->id");
}
}

/**
* Count the number of replies to the specified post.
*
* @param object $post
* @param bool $children
* @return int
* @deprecated since Moodle 3.7
*/
function forum_count_replies($post, $children = true) {
global $USER;
debugging('forum_count_replies has been deprecated. Please use the Post vault instead.', DEBUG_DEVELOPER);

if (!$children) {
return $DB->count_records('forum_posts', array('parent' => $post->id));
}

$entityfactory = mod_forum\local\container::get_entity_factory();
$postentity = $entityfactory->get_post_from_stdclass($post);

$vaultfactory = mod_forum\local\container::get_vault_factory();
$postvault = $vaultfactory->get_post_vault();

return $postvault->get_reply_count_for_post_id_in_discussion_id(
$USER,
$postentity->get_id(),
$postentity->get_discussion_id(),
true
);
}
1 change: 1 addition & 0 deletions mod/forum/lang/en/forum.php
Expand Up @@ -60,6 +60,7 @@
$string['cannotcreatediscussion'] = 'Could not create new discussion';
$string['cannotcreateinstanceforteacher'] = 'Could not create new course module instance for the teacher forum';
$string['cannotdeletepost'] = 'You can\'t delete this post!';
$string['cannotdeletediscussioninsinglediscussion'] = 'You cannot delete the first post in a single discussion';
$string['cannoteditposts'] = 'You can\'t edit other people\'s posts!';
$string['cannotfinddiscussion'] = 'Could not find the discussion in this forum';
$string['cannotfindfirstpost'] = 'Could not find the first post in this forum';
Expand Down
24 changes: 0 additions & 24 deletions mod/forum/lib.php
Expand Up @@ -3478,30 +3478,6 @@ function forum_trigger_content_uploaded_event($post, $cm, $name) {
return true;
}

/**
* @global object
* @param object $post
* @param bool $children
* @return int
*/
function forum_count_replies($post, $children=true) {
global $DB;
$count = 0;

if ($children) {
if ($childposts = $DB->get_records('forum_posts', array('parent' => $post->id))) {
foreach ($childposts as $childpost) {
$count ++; // For this child
$count += forum_count_replies($childpost, true);
}
}
} else {
$count += $DB->count_records('forum_posts', array('parent' => $post->id));
}

return $count;
}

/**
* Given a new post, subscribes or unsubscribes as appropriate.
* Returns some text which describes what happened.
Expand Down

0 comments on commit 15dc885

Please sign in to comment.