mirror of
https://github.com/moodle/moodle.git
synced 2025-08-05 08:56:36 +02:00
MDL-66078 mod_forum: Add webservice to pull discussion data for user
Part of MDL-66074
This commit is contained in:
parent
5123b5c9d7
commit
34e6dd2475
11 changed files with 711 additions and 7 deletions
2
mod/forum/amd/build/repository.min.js
vendored
2
mod/forum/amd/build/repository.min.js
vendored
|
@ -1,2 +1,2 @@
|
||||||
define ("mod_forum/repository",["core/ajax"],function(a){return{setDiscussionSubscriptionState:function setDiscussionSubscriptionState(b,c,d){return a.call([{methodname:"mod_forum_set_subscription_state",args:{forumid:b,discussionid:c,targetstate:d}}])[0]},addDiscussionPost:function addDiscussionPost(b,c,d,e,f,g){return a.call([{methodname:"mod_forum_add_discussion_post",args:{postid:b,message:d,messageformat:e,subject:c,options:[{name:"private",value:f},{name:"topreferredformat",value:g}]}}])[0]},setDiscussionLockState:function setDiscussionLockState(b,c,d){return a.call([{methodname:"mod_forum_set_lock_state",args:{forumid:b,discussionid:c,targetstate:d}}])[0]},setFavouriteDiscussionState:function setFavouriteDiscussionState(b,c,d){return a.call([{methodname:"mod_forum_toggle_favourite_state",args:{discussionid:c,targetstate:d}}])[0]},setPinDiscussionState:function setPinDiscussionState(b,c,d){return a.call([{methodname:"mod_forum_set_pin_state",args:{discussionid:c,targetstate:d}}])[0]}}});
|
define ("mod_forum/repository",["core/ajax"],function(a){return{setDiscussionSubscriptionState:function setDiscussionSubscriptionState(b,c,d){return a.call([{methodname:"mod_forum_set_subscription_state",args:{forumid:b,discussionid:c,targetstate:d}}])[0]},addDiscussionPost:function addDiscussionPost(b,c,d,e,f,g){return a.call([{methodname:"mod_forum_add_discussion_post",args:{postid:b,message:d,messageformat:e,subject:c,options:[{name:"private",value:f},{name:"topreferredformat",value:g}]}}])[0]},setDiscussionLockState:function setDiscussionLockState(b,c,d){return a.call([{methodname:"mod_forum_set_lock_state",args:{forumid:b,discussionid:c,targetstate:d}}])[0]},setFavouriteDiscussionState:function setFavouriteDiscussionState(b,c,d){return a.call([{methodname:"mod_forum_toggle_favourite_state",args:{discussionid:c,targetstate:d}}])[0]},setPinDiscussionState:function setPinDiscussionState(b,c,d){return a.call([{methodname:"mod_forum_set_pin_state",args:{discussionid:c,targetstate:d}}])[0]},getDiscussionByUserID:function getDiscussionByUserID(b,c){var d=2<arguments.length&&arguments[2]!==void 0?arguments[2]:"modified",e=3<arguments.length&&arguments[3]!==void 0?arguments[3]:"DESC";return a.call([{methodname:"mod_forum_get_discussion_posts_by_userid",args:{userid:b,cmid:c,sortby:d,sortdirection:e}}])[0]}}});
|
||||||
//# sourceMappingURL=repository.min.js.map
|
//# sourceMappingURL=repository.min.js.map
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -112,11 +112,34 @@ define(['core/ajax'], function(Ajax) {
|
||||||
return Ajax.call([request])[0];
|
return Ajax.call([request])[0];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the discussions for the user and cmid provided.
|
||||||
|
*
|
||||||
|
* @param {number} userid
|
||||||
|
* @param {number} cmid
|
||||||
|
* @param {string} sortby
|
||||||
|
* @param {string} sortdirection
|
||||||
|
* @return {*|Promise}
|
||||||
|
*/
|
||||||
|
var getDiscussionByUserID = function(userid, cmid, sortby = 'modified', sortdirection = 'DESC') {
|
||||||
|
var request = {
|
||||||
|
methodname: 'mod_forum_get_discussion_posts_by_userid',
|
||||||
|
args: {
|
||||||
|
userid: userid,
|
||||||
|
cmid: cmid,
|
||||||
|
sortby: sortby,
|
||||||
|
sortdirection: sortdirection,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
return Ajax.call([request])[0];
|
||||||
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
setDiscussionSubscriptionState: setDiscussionSubscriptionState,
|
setDiscussionSubscriptionState: setDiscussionSubscriptionState,
|
||||||
addDiscussionPost: addDiscussionPost,
|
addDiscussionPost: addDiscussionPost,
|
||||||
setDiscussionLockState: setDiscussionLockState,
|
setDiscussionLockState: setDiscussionLockState,
|
||||||
setFavouriteDiscussionState: setFavouriteDiscussionState,
|
setFavouriteDiscussionState: setFavouriteDiscussionState,
|
||||||
setPinDiscussionState: setPinDiscussionState
|
setPinDiscussionState: setPinDiscussionState,
|
||||||
|
getDiscussionByUserID: getDiscussionByUserID
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
|
@ -168,6 +168,7 @@ class discussion_list {
|
||||||
|
|
||||||
$forumview = [
|
$forumview = [
|
||||||
'forum' => (array) $forumexporter->export($this->renderer),
|
'forum' => (array) $forumexporter->export($this->renderer),
|
||||||
|
'cmid' => $cm->id,
|
||||||
'hasanyactions' => $hasanyactions,
|
'hasanyactions' => $hasanyactions,
|
||||||
'groupchangemenu' => groups_print_activity_menu(
|
'groupchangemenu' => groups_print_activity_menu(
|
||||||
$cm,
|
$cm,
|
||||||
|
@ -207,6 +208,9 @@ class discussion_list {
|
||||||
$exportedposts
|
$exportedposts
|
||||||
);
|
);
|
||||||
|
|
||||||
|
$firstdiscussion = reset($discussions);
|
||||||
|
$forumview['firstgradeduserid'] = $firstdiscussion->get_latest_post_author()->get_id();
|
||||||
|
|
||||||
return $this->renderer->render_from_template($this->template, $forumview);
|
return $this->renderer->render_from_template($this->template, $forumview);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -92,10 +92,10 @@ class discussion extends db_table_vault {
|
||||||
* @param forum_entity $forum
|
* @param forum_entity $forum
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function get_all_discussions_in_forum(forum_entity $forum): ?array {
|
public function get_all_discussions_in_forum(forum_entity $forum, string $sort = null): ?array {
|
||||||
$records = $this->get_db()->get_records(self::TABLE, [
|
$records = $this->get_db()->get_records(self::TABLE, [
|
||||||
'forum' => $forum->get_id(),
|
'forum' => $forum->get_id(),
|
||||||
]);
|
], $sort ?? '');
|
||||||
|
|
||||||
return $this->transform_db_records_to_entities($records);
|
return $this->transform_db_records_to_entities($records);
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,7 @@ namespace mod_forum\local\vaults;
|
||||||
|
|
||||||
defined('MOODLE_INTERNAL') || die();
|
defined('MOODLE_INTERNAL') || die();
|
||||||
|
|
||||||
|
use mod_forum\local\entities\forum as forum_entity;
|
||||||
use mod_forum\local\entities\post as post_entity;
|
use mod_forum\local\entities\post as post_entity;
|
||||||
use mod_forum\local\factories\entity as entity_factory;
|
use mod_forum\local\factories\entity as entity_factory;
|
||||||
use stdClass;
|
use stdClass;
|
||||||
|
@ -511,4 +512,75 @@ class post extends db_table_vault {
|
||||||
$records = $this->get_db()->get_records_sql($sql, $params);
|
$records = $this->get_db()->get_records_sql($sql, $params);
|
||||||
return $this->transform_db_records_to_entities($records);
|
return $this->transform_db_records_to_entities($records);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the posts for the given user.
|
||||||
|
*
|
||||||
|
* @param int[] $discussionids The list of discussions to fetch posts for
|
||||||
|
* @param int $userid
|
||||||
|
* @param bool $canseeprivatereplies Whether this user can see all private replies or not
|
||||||
|
* @param string $orderby Order the results
|
||||||
|
* @return post_entity[]
|
||||||
|
*/
|
||||||
|
public function get_posts_in_forum_for_user_id(
|
||||||
|
array $discussionids,
|
||||||
|
int $userid,
|
||||||
|
bool $canseeprivatereplies,
|
||||||
|
string $orderby = 'created ASC'
|
||||||
|
): array {
|
||||||
|
$user = $this->get_db()->get_record('user', ['id' => (int)$userid], '*', IGNORE_MISSING);
|
||||||
|
list($insql, $params) = $this->get_db()->get_in_or_equal($discussionids, SQL_PARAMS_NAMED);
|
||||||
|
|
||||||
|
$alias = $this->get_table_alias();
|
||||||
|
[
|
||||||
|
'where' => $privatewhere,
|
||||||
|
'params' => $privateparams,
|
||||||
|
] = $this->get_private_reply_sql($user, $canseeprivatereplies);
|
||||||
|
|
||||||
|
$wheresql = "{$alias}.userid = :authorid {$privatewhere}";
|
||||||
|
$orderbysql = $alias . '.' . $orderby;
|
||||||
|
|
||||||
|
$sql = $this->generate_get_records_sql($wheresql, $orderbysql);
|
||||||
|
$records = $this->get_db()->get_records_sql($sql, array_merge([
|
||||||
|
'authorid' => $userid,
|
||||||
|
], $privateparams));
|
||||||
|
|
||||||
|
return $this->transform_db_records_to_entities($records);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the posts for the given user.
|
||||||
|
*
|
||||||
|
* @param int $discussionid The discussion to fetch posts for
|
||||||
|
* @param int $userid The user to fetch posts for
|
||||||
|
* @param bool $canseeprivatereplies Whether this user can see all private replies or not
|
||||||
|
* @param string $orderby Order the results
|
||||||
|
* @return post_entity[]
|
||||||
|
*/
|
||||||
|
public function get_posts_in_discussion_for_user_id(
|
||||||
|
int $discussionid,
|
||||||
|
int $userid,
|
||||||
|
bool $canseeprivatereplies,
|
||||||
|
string $orderby = 'created ASC'
|
||||||
|
): array {
|
||||||
|
$user = $this->get_db()->get_record('user', ['id' => (int)$userid], '*', IGNORE_MISSING);
|
||||||
|
|
||||||
|
$alias = $this->get_table_alias();
|
||||||
|
[
|
||||||
|
'where' => $privatewhere,
|
||||||
|
'params' => $privateparams,
|
||||||
|
] = $this->get_private_reply_sql($user, $canseeprivatereplies);
|
||||||
|
|
||||||
|
$wheresql = "{$alias}.userid = :authorid AND
|
||||||
|
{$alias}.discussion = :discussionid {$privatewhere}";
|
||||||
|
$orderbysql = $alias . '.' . $orderby;
|
||||||
|
|
||||||
|
$sql = $this->generate_get_records_sql($wheresql, $orderbysql);
|
||||||
|
$records = $this->get_db()->get_records_sql($sql, array_merge([
|
||||||
|
'authorid' => $userid,
|
||||||
|
'discussionid' => $discussionid
|
||||||
|
], $privateparams));
|
||||||
|
|
||||||
|
return $this->transform_db_records_to_entities($records);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -175,6 +175,7 @@ $functions = array(
|
||||||
'ajax' => true,
|
'ajax' => true,
|
||||||
'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE),
|
'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE),
|
||||||
),
|
),
|
||||||
|
|
||||||
'mod_forum_delete_post' => array(
|
'mod_forum_delete_post' => array(
|
||||||
'classname' => 'mod_forum_external',
|
'classname' => 'mod_forum_external',
|
||||||
'methodname' => 'delete_post',
|
'methodname' => 'delete_post',
|
||||||
|
@ -183,4 +184,14 @@ $functions = array(
|
||||||
'type' => 'write',
|
'type' => 'write',
|
||||||
'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE),
|
'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE),
|
||||||
),
|
),
|
||||||
|
|
||||||
|
'mod_forum_get_discussion_posts_by_userid' => array(
|
||||||
|
'classname' => 'mod_forum_external',
|
||||||
|
'methodname' => 'get_discussion_posts_by_userid',
|
||||||
|
'classpath' => 'mod/forum/externallib.php',
|
||||||
|
'description' => 'Returns a list of forum posts for a discussion for a user.',
|
||||||
|
'type' => 'read',
|
||||||
|
'ajax' => true,
|
||||||
|
'capabilities' => 'mod/forum:viewdiscussion, mod/forum:viewqandawithoutposting',
|
||||||
|
),
|
||||||
);
|
);
|
||||||
|
|
|
@ -2152,4 +2152,141 @@ class mod_forum_external extends external_api {
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the forum posts in the specified forum instance.
|
||||||
|
*
|
||||||
|
* @param int $userid
|
||||||
|
* @param int $cmid
|
||||||
|
* @param string $sortby
|
||||||
|
* @param string $sortdirection
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public static function get_discussion_posts_by_userid(int $userid = 0, int $cmid, ?string $sortby, ?string $sortdirection) {
|
||||||
|
global $USER, $DB;
|
||||||
|
// Validate the parameter.
|
||||||
|
$params = self::validate_parameters(self::get_discussion_posts_by_userid_parameters(), [
|
||||||
|
'userid' => $userid,
|
||||||
|
'cmid' => $cmid,
|
||||||
|
'sortby' => $sortby,
|
||||||
|
'sortdirection' => $sortdirection,
|
||||||
|
]);
|
||||||
|
$warnings = [];
|
||||||
|
|
||||||
|
$user = $DB->get_record('user', ['id' => (int)$params['userid']], '*', IGNORE_MISSING);
|
||||||
|
|
||||||
|
$vaultfactory = mod_forum\local\container::get_vault_factory();
|
||||||
|
|
||||||
|
$forumvault = $vaultfactory->get_forum_vault();
|
||||||
|
$forum = $forumvault->get_from_course_module_id($params['cmid']);
|
||||||
|
|
||||||
|
// Validate the module context. It checks everything that affects the module visibility (including groupings, etc..).
|
||||||
|
self::validate_context($forum->get_context());
|
||||||
|
|
||||||
|
$sortby = $params['sortby'];
|
||||||
|
$sortdirection = $params['sortdirection'];
|
||||||
|
$sortallowedvalues = ['id', 'created', 'modified'];
|
||||||
|
$directionallowedvalues = ['ASC', 'DESC'];
|
||||||
|
|
||||||
|
if (!in_array(strtolower($sortby), $sortallowedvalues)) {
|
||||||
|
throw new invalid_parameter_exception('Invalid value for sortby parameter (value: ' . $sortby . '),' .
|
||||||
|
'allowed values are: ' . implode(', ', $sortallowedvalues));
|
||||||
|
}
|
||||||
|
|
||||||
|
$sortdirection = strtoupper($sortdirection);
|
||||||
|
if (!in_array($sortdirection, $directionallowedvalues)) {
|
||||||
|
throw new invalid_parameter_exception('Invalid value for sortdirection parameter (value: ' . $sortdirection . '),' .
|
||||||
|
'allowed values are: ' . implode(',', $directionallowedvalues));
|
||||||
|
}
|
||||||
|
|
||||||
|
$managerfactory = mod_forum\local\container::get_manager_factory();
|
||||||
|
$capabilitymanager = $managerfactory->get_capability_manager($forum);
|
||||||
|
|
||||||
|
$discussionvault = $vaultfactory->get_discussion_vault();
|
||||||
|
$discussions = $discussionvault->get_all_discussions_in_forum($forum, 'timemodified ASC, id ASC');
|
||||||
|
|
||||||
|
$postvault = $vaultfactory->get_post_vault();
|
||||||
|
|
||||||
|
$builderfactory = mod_forum\local\container::get_builder_factory();
|
||||||
|
$postbuilder = $builderfactory->get_exported_posts_builder();
|
||||||
|
|
||||||
|
$builtdiscussions = [];
|
||||||
|
foreach ($discussions as $id => $discussion) {
|
||||||
|
$posts = $postvault->get_posts_in_discussion_for_user_id(
|
||||||
|
$discussion->get_id(),
|
||||||
|
$user->id,
|
||||||
|
$capabilitymanager->can_view_any_private_reply($USER),
|
||||||
|
"{$sortby} {$sortdirection}"
|
||||||
|
);
|
||||||
|
if (empty($posts)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$parentids = array_filter(array_map(function($post) {
|
||||||
|
return $post->has_parent() ? $post->get_parent_id() : null;
|
||||||
|
}, $posts));
|
||||||
|
|
||||||
|
$parentposts = [];
|
||||||
|
if ($parentids) {
|
||||||
|
$parentposts = $postbuilder->build(
|
||||||
|
$user,
|
||||||
|
[$forum],
|
||||||
|
[$discussion],
|
||||||
|
$postvault->get_from_ids(array_values($parentids))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$builtdiscussions[] = [
|
||||||
|
'name' => $discussion->get_name(),
|
||||||
|
'id' => $discussion->get_id(),
|
||||||
|
'posts' => [
|
||||||
|
'userposts' => $postbuilder->build($user, [$forum], [$discussion], $posts),
|
||||||
|
'parentposts' => $parentposts,
|
||||||
|
],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
'discussions' => $builtdiscussions,
|
||||||
|
'warnings' => $warnings,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Describe the post parameters.
|
||||||
|
*
|
||||||
|
* @return external_function_parameters
|
||||||
|
*/
|
||||||
|
public static function get_discussion_posts_by_userid_parameters() {
|
||||||
|
return new external_function_parameters ([
|
||||||
|
'userid' => new external_value(
|
||||||
|
PARAM_INT, 'The ID of the user of whom to fetch posts.', VALUE_REQUIRED),
|
||||||
|
'cmid' => new external_value(
|
||||||
|
PARAM_INT, 'The ID of the module of which to fetch items.', VALUE_REQUIRED),
|
||||||
|
'sortby' => new external_value(
|
||||||
|
PARAM_ALPHA, 'Sort by this element: id, created or modified', VALUE_DEFAULT, 'created'),
|
||||||
|
'sortdirection' => new external_value(
|
||||||
|
PARAM_ALPHA, 'Sort direction: ASC or DESC', VALUE_DEFAULT, 'DESC')
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Describe the post return format.
|
||||||
|
*
|
||||||
|
* @return external_single_structure
|
||||||
|
*/
|
||||||
|
public static function get_discussion_posts_by_userid_returns() {
|
||||||
|
return new external_single_structure([
|
||||||
|
'discussions' => new external_multiple_structure(
|
||||||
|
new external_single_structure([
|
||||||
|
'name' => new external_value(PARAM_RAW, 'Name of the discussion'),
|
||||||
|
'id' => new external_value(PARAM_INT, 'ID of the discussion'),
|
||||||
|
'posts' => new external_single_structure([
|
||||||
|
'userposts' => new external_multiple_structure(\mod_forum\local\exporters\post::get_read_structure()),
|
||||||
|
'parentposts' => new external_multiple_structure(\mod_forum\local\exporters\post::get_read_structure()),
|
||||||
|
]),
|
||||||
|
])),
|
||||||
|
'warnings' => new external_warnings(),
|
||||||
|
]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2465,12 +2465,12 @@ class mod_forum_external_testcase extends externallib_advanced_testcase {
|
||||||
$discussionrecord->userid = $user1->id;
|
$discussionrecord->userid = $user1->id;
|
||||||
$discussionrecord->forum = $forum->id;
|
$discussionrecord->forum = $forum->id;
|
||||||
$discussionrecord->message = $dangeroustext;
|
$discussionrecord->message = $dangeroustext;
|
||||||
$discussionrecord->messagetrust = trusttext_trusted($context);
|
$discussionrecord->messagetrust = trusttext_trusted($context);
|
||||||
$discussion1 = self::getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($discussionrecord);
|
$discussion1 = self::getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($discussionrecord);
|
||||||
|
|
||||||
self::setAdminUser();
|
self::setAdminUser();
|
||||||
$discussionrecord->userid = $USER->id;
|
$discussionrecord->userid = $USER->id;
|
||||||
$discussionrecord->messagetrust = trusttext_trusted($context);
|
$discussionrecord->messagetrust = trusttext_trusted($context);
|
||||||
$discussion2 = self::getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($discussionrecord);
|
$discussion2 = self::getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($discussionrecord);
|
||||||
|
|
||||||
$discussions = mod_forum_external::get_forum_discussions($forum->id);
|
$discussions = mod_forum_external::get_forum_discussions($forum->id);
|
||||||
|
@ -2604,4 +2604,397 @@ class mod_forum_external_testcase extends externallib_advanced_testcase {
|
||||||
$this->expectExceptionMessage(get_string('cannotdeletepost', 'forum'));
|
$this->expectExceptionMessage(get_string('cannotdeletepost', 'forum'));
|
||||||
mod_forum_external::delete_post($post->id);
|
mod_forum_external::delete_post($post->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Test get forum posts by user id.
|
||||||
|
*/
|
||||||
|
public function test_mod_forum_get_discussion_posts_by_userid() {
|
||||||
|
$this->resetAfterTest(true);
|
||||||
|
|
||||||
|
$urlfactory = mod_forum\local\container::get_url_factory();
|
||||||
|
$entityfactory = mod_forum\local\container::get_entity_factory();
|
||||||
|
$vaultfactory = mod_forum\local\container::get_vault_factory();
|
||||||
|
$postvault = $vaultfactory->get_post_vault();
|
||||||
|
$legacydatamapper = mod_forum\local\container::get_legacy_data_mapper_factory();
|
||||||
|
$legacypostmapper = $legacydatamapper->get_post_data_mapper();
|
||||||
|
|
||||||
|
$user1 = self::getDataGenerator()->create_user();
|
||||||
|
$user1entity = $entityfactory->get_author_from_stdclass($user1);
|
||||||
|
$exporteduser1 = [
|
||||||
|
'id' => (int) $user1->id,
|
||||||
|
'fullname' => fullname($user1),
|
||||||
|
'groups' => [],
|
||||||
|
'urls' => [
|
||||||
|
'profile' => $urlfactory->get_author_profile_url($user1entity),
|
||||||
|
'profileimage' => $urlfactory->get_author_profile_image_url($user1entity),
|
||||||
|
],
|
||||||
|
'isdeleted' => false,
|
||||||
|
];
|
||||||
|
// Create a bunch of other users to post.
|
||||||
|
$user2 = self::getDataGenerator()->create_user();
|
||||||
|
$user2entity = $entityfactory->get_author_from_stdclass($user2);
|
||||||
|
$exporteduser2 = [
|
||||||
|
'id' => (int) $user2->id,
|
||||||
|
'fullname' => fullname($user2),
|
||||||
|
'groups' => [],
|
||||||
|
'urls' => [
|
||||||
|
'profile' => $urlfactory->get_author_profile_url($user2entity),
|
||||||
|
'profileimage' => $urlfactory->get_author_profile_image_url($user2entity),
|
||||||
|
],
|
||||||
|
'isdeleted' => false,
|
||||||
|
];
|
||||||
|
$user2->fullname = $exporteduser2['fullname'];
|
||||||
|
|
||||||
|
$forumgenerator = self::getDataGenerator()->get_plugin_generator('mod_forum');
|
||||||
|
|
||||||
|
// Set the first created user to the test user.
|
||||||
|
self::setUser($user1);
|
||||||
|
|
||||||
|
// Create course to add the module.
|
||||||
|
$course1 = self::getDataGenerator()->create_course();
|
||||||
|
|
||||||
|
// Forum with tracking off.
|
||||||
|
$record = new stdClass();
|
||||||
|
$record->course = $course1->id;
|
||||||
|
$forum1 = self::getDataGenerator()->create_module('forum', $record);
|
||||||
|
$forum1context = context_module::instance($forum1->cmid);
|
||||||
|
|
||||||
|
// Add discussions to the forums.
|
||||||
|
$record = new stdClass();
|
||||||
|
$record->course = $course1->id;
|
||||||
|
$record->userid = $user1->id;
|
||||||
|
$record->forum = $forum1->id;
|
||||||
|
$discussion1 = $forumgenerator->create_discussion($record);
|
||||||
|
$discussion1firstpost = $postvault->get_first_post_for_discussion_ids([$discussion1->id]);
|
||||||
|
$discussion1firstpostobject = $legacypostmapper->to_legacy_object($discussion1firstpost[$discussion1->firstpost]);
|
||||||
|
|
||||||
|
$record = new stdClass();
|
||||||
|
$record->course = $course1->id;
|
||||||
|
$record->userid = $user1->id;
|
||||||
|
$record->forum = $forum1->id;
|
||||||
|
$discussion2 = $forumgenerator->create_discussion($record);
|
||||||
|
$discussion2firstpost = $postvault->get_first_post_for_discussion_ids([$discussion2->id]);
|
||||||
|
$discussion2firstpostobject = $legacypostmapper->to_legacy_object($discussion2firstpost[$discussion2->firstpost]);
|
||||||
|
|
||||||
|
// Add 1 reply to the discussion 1 from a different user.
|
||||||
|
$record = new stdClass();
|
||||||
|
$record->discussion = $discussion1->id;
|
||||||
|
$record->parent = $discussion1->firstpost;
|
||||||
|
$record->userid = $user2->id;
|
||||||
|
$discussion1reply1 = $forumgenerator->create_post($record);
|
||||||
|
$filename = 'shouldbeanimage.jpg';
|
||||||
|
// Add a fake inline image to the post.
|
||||||
|
$filerecordinline = array(
|
||||||
|
'contextid' => $forum1context->id,
|
||||||
|
'component' => 'mod_forum',
|
||||||
|
'filearea' => 'post',
|
||||||
|
'itemid' => $discussion1reply1->id,
|
||||||
|
'filepath' => '/',
|
||||||
|
'filename' => $filename,
|
||||||
|
);
|
||||||
|
$fs = get_file_storage();
|
||||||
|
$fs->create_file_from_string($filerecordinline, 'image contents (not really)');
|
||||||
|
|
||||||
|
// Add 1 reply to the discussion 2 from a different user.
|
||||||
|
$record = new stdClass();
|
||||||
|
$record->discussion = $discussion2->id;
|
||||||
|
$record->parent = $discussion2->firstpost;
|
||||||
|
$record->userid = $user2->id;
|
||||||
|
$discussion2reply1 = $forumgenerator->create_post($record);
|
||||||
|
$filename = 'shouldbeanimage.jpg';
|
||||||
|
// Add a fake inline image to the post.
|
||||||
|
$filerecordinline = array(
|
||||||
|
'contextid' => $forum1context->id,
|
||||||
|
'component' => 'mod_forum',
|
||||||
|
'filearea' => 'post',
|
||||||
|
'itemid' => $discussion2reply1->id,
|
||||||
|
'filepath' => '/',
|
||||||
|
'filename' => $filename,
|
||||||
|
);
|
||||||
|
$fs = get_file_storage();
|
||||||
|
$fs->create_file_from_string($filerecordinline, 'image contents (not really)');
|
||||||
|
|
||||||
|
// Following line enrol and assign default role id to the user.
|
||||||
|
// So the user automatically gets mod/forum:viewdiscussion on all forums of the course.
|
||||||
|
$this->getDataGenerator()->enrol_user($user1->id, $course1->id);
|
||||||
|
$this->getDataGenerator()->enrol_user($user2->id, $course1->id);
|
||||||
|
|
||||||
|
// Create what we expect to be returned when querying the discussion.
|
||||||
|
$expectedposts = array(
|
||||||
|
'discussions' => array(),
|
||||||
|
'warnings' => array(),
|
||||||
|
);
|
||||||
|
|
||||||
|
$isolatedurluser = $urlfactory->get_discussion_view_url_from_discussion_id($discussion1reply1->discussion);
|
||||||
|
$isolatedurluser->params(['parent' => $discussion1reply1->id]);
|
||||||
|
$isolatedurlparent = $urlfactory->get_discussion_view_url_from_discussion_id($discussion1firstpostobject->discussion);
|
||||||
|
$isolatedurlparent->params(['parent' => $discussion1firstpostobject->id]);
|
||||||
|
|
||||||
|
$expectedposts['discussions'][0] = [
|
||||||
|
'name' => $discussion1->name,
|
||||||
|
'id' => $discussion1->id,
|
||||||
|
'posts' => [
|
||||||
|
'userposts' => [
|
||||||
|
[
|
||||||
|
'id' => $discussion1reply1->id,
|
||||||
|
'discussionid' => $discussion1reply1->discussion,
|
||||||
|
'parentid' => $discussion1reply1->parent,
|
||||||
|
'hasparent' => true,
|
||||||
|
'timecreated' => $discussion1reply1->created,
|
||||||
|
'subject' => $discussion1reply1->subject,
|
||||||
|
'replysubject' => get_string('re', 'mod_forum') . " {$discussion1reply1->subject}",
|
||||||
|
'message' => file_rewrite_pluginfile_urls($discussion1reply1->message, 'pluginfile.php',
|
||||||
|
$forum1context->id, 'mod_forum', 'post', $discussion1reply1->id),
|
||||||
|
'messageformat' => 1, // This value is usually changed by external_format_text() function.
|
||||||
|
'unread' => null,
|
||||||
|
'isdeleted' => false,
|
||||||
|
'isprivatereply' => false,
|
||||||
|
'haswordcount' => false,
|
||||||
|
'wordcount' => null,
|
||||||
|
'author' => $exporteduser2,
|
||||||
|
'attachments' => [],
|
||||||
|
'tags' => [],
|
||||||
|
'html' => [
|
||||||
|
'rating' => null,
|
||||||
|
'taglist' => null,
|
||||||
|
'authorsubheading' => $forumgenerator->get_author_subheading_html(
|
||||||
|
(object)$exporteduser2, $discussion1reply1->created)
|
||||||
|
],
|
||||||
|
'charcount' => null,
|
||||||
|
'capabilities' => [
|
||||||
|
'view' => true,
|
||||||
|
'edit' => true,
|
||||||
|
'delete' => true,
|
||||||
|
'split' => false,
|
||||||
|
'reply' => true,
|
||||||
|
'export' => false,
|
||||||
|
'controlreadstatus' => false,
|
||||||
|
'canreplyprivately' => false,
|
||||||
|
'selfenrol' => false
|
||||||
|
],
|
||||||
|
'urls' => [
|
||||||
|
'view' => $urlfactory->get_view_post_url_from_post_id(
|
||||||
|
$discussion1reply1->discussion, $discussion1reply1->id)->out(false),
|
||||||
|
'viewisolated' => $isolatedurluser->out(false),
|
||||||
|
'viewparent' => $urlfactory->get_view_post_url_from_post_id(
|
||||||
|
$discussion1reply1->discussion, $discussion1reply1->parent)->out(false),
|
||||||
|
'edit' => (new moodle_url('/mod/forum/post.php', [
|
||||||
|
'edit' => $discussion1reply1->id
|
||||||
|
]))->out(false),
|
||||||
|
'delete' => (new moodle_url('/mod/forum/post.php', [
|
||||||
|
'delete' => $discussion1reply1->id
|
||||||
|
]))->out(false),
|
||||||
|
'split' => null,
|
||||||
|
'reply' => (new moodle_url('/mod/forum/post.php#mformforum', [
|
||||||
|
'reply' => $discussion1reply1->id
|
||||||
|
]))->out(false),
|
||||||
|
'export' => null,
|
||||||
|
'markasread' => null,
|
||||||
|
'markasunread' => null,
|
||||||
|
'discuss' => $urlfactory->get_discussion_view_url_from_discussion_id(
|
||||||
|
$discussion1reply1->discussion)->out(false),
|
||||||
|
],
|
||||||
|
]
|
||||||
|
],
|
||||||
|
'parentposts' => [
|
||||||
|
[
|
||||||
|
'id' => $discussion1firstpostobject->id,
|
||||||
|
'discussionid' => $discussion1firstpostobject->discussion,
|
||||||
|
'parentid' => null,
|
||||||
|
'hasparent' => false,
|
||||||
|
'timecreated' => $discussion1firstpostobject->created,
|
||||||
|
'subject' => $discussion1firstpostobject->subject,
|
||||||
|
'replysubject' => get_string('re', 'mod_forum') . " {$discussion1firstpostobject->subject}",
|
||||||
|
'message' => file_rewrite_pluginfile_urls($discussion1firstpostobject->message, 'pluginfile.php',
|
||||||
|
$forum1context->id, 'mod_forum', 'post', $discussion1firstpostobject->id),
|
||||||
|
'messageformat' => 1, // This value is usually changed by external_format_text() function.
|
||||||
|
'unread' => null,
|
||||||
|
'isdeleted' => false,
|
||||||
|
'isprivatereply' => false,
|
||||||
|
'haswordcount' => false,
|
||||||
|
'wordcount' => null,
|
||||||
|
'author' => $exporteduser1,
|
||||||
|
'attachments' => [],
|
||||||
|
'tags' => [],
|
||||||
|
'html' => [
|
||||||
|
'rating' => null,
|
||||||
|
'taglist' => null,
|
||||||
|
'authorsubheading' => $forumgenerator->get_author_subheading_html(
|
||||||
|
(object)$exporteduser1, $discussion1firstpostobject->created)
|
||||||
|
],
|
||||||
|
'charcount' => null,
|
||||||
|
'capabilities' => [
|
||||||
|
'view' => true,
|
||||||
|
'edit' => false,
|
||||||
|
'delete' => false,
|
||||||
|
'split' => false,
|
||||||
|
'reply' => true,
|
||||||
|
'export' => false,
|
||||||
|
'controlreadstatus' => false,
|
||||||
|
'canreplyprivately' => false,
|
||||||
|
'selfenrol' => false
|
||||||
|
],
|
||||||
|
'urls' => [
|
||||||
|
'view' => $urlfactory->get_view_post_url_from_post_id(
|
||||||
|
$discussion1firstpostobject->discussion, $discussion1firstpostobject->id)->out(false),
|
||||||
|
'viewisolated' => $isolatedurlparent->out(false),
|
||||||
|
'viewparent' => null,
|
||||||
|
'edit' => null,
|
||||||
|
'delete' => null,
|
||||||
|
'split' => null,
|
||||||
|
'reply' => (new moodle_url('/mod/forum/post.php#mformforum', [
|
||||||
|
'reply' => $discussion1firstpostobject->id
|
||||||
|
]))->out(false),
|
||||||
|
'export' => null,
|
||||||
|
'markasread' => null,
|
||||||
|
'markasunread' => null,
|
||||||
|
'discuss' => $urlfactory->get_discussion_view_url_from_discussion_id(
|
||||||
|
$discussion1firstpostobject->discussion)->out(false),
|
||||||
|
],
|
||||||
|
]
|
||||||
|
],
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
$isolatedurluser = $urlfactory->get_discussion_view_url_from_discussion_id($discussion2reply1->discussion);
|
||||||
|
$isolatedurluser->params(['parent' => $discussion2reply1->id]);
|
||||||
|
$isolatedurlparent = $urlfactory->get_discussion_view_url_from_discussion_id($discussion2firstpostobject->discussion);
|
||||||
|
$isolatedurlparent->params(['parent' => $discussion2firstpostobject->id]);
|
||||||
|
|
||||||
|
$expectedposts['discussions'][1] = [
|
||||||
|
'name' => $discussion2->name,
|
||||||
|
'id' => $discussion2->id,
|
||||||
|
'posts' => [
|
||||||
|
'userposts' => [
|
||||||
|
[
|
||||||
|
'id' => $discussion2reply1->id,
|
||||||
|
'discussionid' => $discussion2reply1->discussion,
|
||||||
|
'parentid' => $discussion2reply1->parent,
|
||||||
|
'hasparent' => true,
|
||||||
|
'timecreated' => $discussion2reply1->created,
|
||||||
|
'subject' => $discussion2reply1->subject,
|
||||||
|
'replysubject' => get_string('re', 'mod_forum') . " {$discussion2reply1->subject}",
|
||||||
|
'message' => file_rewrite_pluginfile_urls($discussion2reply1->message, 'pluginfile.php',
|
||||||
|
$forum1context->id, 'mod_forum', 'post', $discussion2reply1->id),
|
||||||
|
'messageformat' => 1, // This value is usually changed by external_format_text() function.
|
||||||
|
'unread' => null,
|
||||||
|
'isdeleted' => false,
|
||||||
|
'isprivatereply' => false,
|
||||||
|
'haswordcount' => false,
|
||||||
|
'wordcount' => null,
|
||||||
|
'author' => $exporteduser2,
|
||||||
|
'attachments' => [],
|
||||||
|
'tags' => [],
|
||||||
|
'html' => [
|
||||||
|
'rating' => null,
|
||||||
|
'taglist' => null,
|
||||||
|
'authorsubheading' => $forumgenerator->get_author_subheading_html(
|
||||||
|
(object)$exporteduser2, $discussion2reply1->created)
|
||||||
|
],
|
||||||
|
'charcount' => null,
|
||||||
|
'capabilities' => [
|
||||||
|
'view' => true,
|
||||||
|
'edit' => true,
|
||||||
|
'delete' => true,
|
||||||
|
'split' => false,
|
||||||
|
'reply' => true,
|
||||||
|
'export' => false,
|
||||||
|
'controlreadstatus' => false,
|
||||||
|
'canreplyprivately' => false,
|
||||||
|
'selfenrol' => false
|
||||||
|
],
|
||||||
|
'urls' => [
|
||||||
|
'view' => $urlfactory->get_view_post_url_from_post_id(
|
||||||
|
$discussion2reply1->discussion, $discussion2reply1->id)->out(false),
|
||||||
|
'viewisolated' => $isolatedurluser->out(false),
|
||||||
|
'viewparent' => $urlfactory->get_view_post_url_from_post_id(
|
||||||
|
$discussion2reply1->discussion, $discussion2reply1->parent)->out(false),
|
||||||
|
'edit' => (new moodle_url('/mod/forum/post.php', [
|
||||||
|
'edit' => $discussion2reply1->id
|
||||||
|
]))->out(false),
|
||||||
|
'delete' => (new moodle_url('/mod/forum/post.php', [
|
||||||
|
'delete' => $discussion2reply1->id
|
||||||
|
]))->out(false),
|
||||||
|
'split' => null,
|
||||||
|
'reply' => (new moodle_url('/mod/forum/post.php#mformforum', [
|
||||||
|
'reply' => $discussion2reply1->id
|
||||||
|
]))->out(false),
|
||||||
|
'export' => null,
|
||||||
|
'markasread' => null,
|
||||||
|
'markasunread' => null,
|
||||||
|
'discuss' => $urlfactory->get_discussion_view_url_from_discussion_id(
|
||||||
|
$discussion2reply1->discussion)->out(false),
|
||||||
|
],
|
||||||
|
]
|
||||||
|
],
|
||||||
|
'parentposts' => [
|
||||||
|
[
|
||||||
|
'id' => $discussion2firstpostobject->id,
|
||||||
|
'discussionid' => $discussion2firstpostobject->discussion,
|
||||||
|
'parentid' => null,
|
||||||
|
'hasparent' => false,
|
||||||
|
'timecreated' => $discussion2firstpostobject->created,
|
||||||
|
'subject' => $discussion2firstpostobject->subject,
|
||||||
|
'replysubject' => get_string('re', 'mod_forum') . " {$discussion2firstpostobject->subject}",
|
||||||
|
'message' => file_rewrite_pluginfile_urls($discussion2firstpostobject->message, 'pluginfile.php',
|
||||||
|
$forum1context->id, 'mod_forum', 'post', $discussion2firstpostobject->id),
|
||||||
|
'messageformat' => 1, // This value is usually changed by external_format_text() function.
|
||||||
|
'unread' => null,
|
||||||
|
'isdeleted' => false,
|
||||||
|
'isprivatereply' => false,
|
||||||
|
'haswordcount' => false,
|
||||||
|
'wordcount' => null,
|
||||||
|
'author' => $exporteduser1,
|
||||||
|
'attachments' => [],
|
||||||
|
'tags' => [],
|
||||||
|
'html' => [
|
||||||
|
'rating' => null,
|
||||||
|
'taglist' => null,
|
||||||
|
'authorsubheading' => $forumgenerator->get_author_subheading_html(
|
||||||
|
(object)$exporteduser1, $discussion2firstpostobject->created)
|
||||||
|
],
|
||||||
|
'charcount' => null,
|
||||||
|
'capabilities' => [
|
||||||
|
'view' => true,
|
||||||
|
'edit' => false,
|
||||||
|
'delete' => false,
|
||||||
|
'split' => false,
|
||||||
|
'reply' => true,
|
||||||
|
'export' => false,
|
||||||
|
'controlreadstatus' => false,
|
||||||
|
'canreplyprivately' => false,
|
||||||
|
'selfenrol' => false
|
||||||
|
],
|
||||||
|
'urls' => [
|
||||||
|
'view' => $urlfactory->get_view_post_url_from_post_id(
|
||||||
|
$discussion2firstpostobject->discussion, $discussion2firstpostobject->id)->out(false),
|
||||||
|
'viewisolated' => $isolatedurlparent->out(false),
|
||||||
|
'viewparent' => null,
|
||||||
|
'edit' => null,
|
||||||
|
'delete' => null,
|
||||||
|
'split' => null,
|
||||||
|
'reply' => (new moodle_url('/mod/forum/post.php#mformforum', [
|
||||||
|
'reply' => $discussion2firstpostobject->id
|
||||||
|
]))->out(false),
|
||||||
|
'export' => null,
|
||||||
|
'markasread' => null,
|
||||||
|
'markasunread' => null,
|
||||||
|
'discuss' => $urlfactory->get_discussion_view_url_from_discussion_id(
|
||||||
|
$discussion2firstpostobject->discussion)->out(false),
|
||||||
|
|
||||||
|
]
|
||||||
|
],
|
||||||
|
]
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
// Test discussions with one additional post each (total 2 posts).
|
||||||
|
// Also testing that we get the parent posts too.
|
||||||
|
$discussions = mod_forum_external::get_discussion_posts_by_userid($user2->id, $forum1->cmid, 'modified', 'DESC');
|
||||||
|
$discussions = external_api::clean_returnvalue(mod_forum_external::get_discussion_posts_by_userid_returns(), $discussions);
|
||||||
|
|
||||||
|
$this->assertEquals(2, count($discussions['discussions']));
|
||||||
|
|
||||||
|
$this->assertEquals($expectedposts, $discussions);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -91,4 +91,32 @@ class mod_forum_vaults_discussion_testcase extends advanced_testcase {
|
||||||
$discussionentity = $vault->get_first_discussion_in_forum($forumentity);
|
$discussionentity = $vault->get_first_discussion_in_forum($forumentity);
|
||||||
$this->assertEquals($discussion2->id, $discussionentity->get_id());
|
$this->assertEquals($discussion2->id, $discussionentity->get_id());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test get_all_discussions_in_forum
|
||||||
|
*/
|
||||||
|
public function test_get_all_discussions_in_forum() {
|
||||||
|
$this->resetAfterTest();
|
||||||
|
|
||||||
|
$vault = $this->vault;
|
||||||
|
$entityfactory = \mod_forum\local\container::get_entity_factory();
|
||||||
|
$datagenerator = $this->getDataGenerator();
|
||||||
|
$user = $datagenerator->create_user();
|
||||||
|
$course = $datagenerator->create_course();
|
||||||
|
$forum = $datagenerator->create_module('forum', ['course' => $course->id]);
|
||||||
|
$coursemodule = get_coursemodule_from_instance('forum', $forum->id);
|
||||||
|
$context = context_module::instance($coursemodule->id);
|
||||||
|
$forumentity = $entityfactory->get_forum_from_stdclass($forum, $context, $coursemodule, $course);
|
||||||
|
|
||||||
|
$this->assertEquals([], $vault->get_all_discussions_in_forum($forumentity));
|
||||||
|
|
||||||
|
[$discussion1, $post] = $this->helper_post_to_forum($forum, $user, ['timemodified' => 2]);
|
||||||
|
[$discussion2, $post] = $this->helper_post_to_forum($forum, $user, ['timemodified' => 1]);
|
||||||
|
[$discussion3, $post] = $this->helper_post_to_forum($forum, $user, ['timemodified' => 3]);
|
||||||
|
|
||||||
|
$discussionentity = $vault->get_all_discussions_in_forum($forumentity);
|
||||||
|
$this->assertArrayHasKey($discussion1->id, $discussionentity); // Order is not guaranteed, so just verify element existence.
|
||||||
|
$this->assertArrayHasKey($discussion2->id, $discussionentity);
|
||||||
|
$this->assertArrayHasKey($discussion3->id, $discussionentity);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1127,5 +1127,41 @@ class mod_forum_vaults_post_testcase extends advanced_testcase {
|
||||||
['discussionids' => $discussionids, 'userids' => $userids], false);
|
['discussionids' => $discussionids, 'userids' => $userids], false);
|
||||||
$this->assertCount(1, $entities);
|
$this->assertCount(1, $entities);
|
||||||
$this->assertArrayHasKey($otherpost->id, $entities);
|
$this->assertArrayHasKey($otherpost->id, $entities);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test get_from_user_id.
|
||||||
|
*
|
||||||
|
* @covers ::get_posts_in_forum_for_user_id
|
||||||
|
*/
|
||||||
|
public function test_get_from_user_id() {
|
||||||
|
$this->resetAfterTest();
|
||||||
|
|
||||||
|
$datagenerator = $this->getDataGenerator();
|
||||||
|
$user = $datagenerator->create_user();
|
||||||
|
$course = $datagenerator->create_course();
|
||||||
|
$forum = $datagenerator->create_module('forum', ['course' => $course->id]);
|
||||||
|
|
||||||
|
$vaultfactory = mod_forum\local\container::get_vault_factory();
|
||||||
|
|
||||||
|
$forumvault = $vaultfactory->get_forum_vault();
|
||||||
|
$forumentity = $forumvault->get_from_course_module_id($forum->cmid);
|
||||||
|
|
||||||
|
$managerfactory = mod_forum\local\container::get_manager_factory();
|
||||||
|
$capabilitymanager = $managerfactory->get_capability_manager($forumentity);
|
||||||
|
[$discussion1, $post1] = $this->helper_post_to_forum($forum, $user);
|
||||||
|
$post2 = $this->helper_reply_to_post($post1, $user);
|
||||||
|
$post3 = $this->helper_reply_to_post($post1, $user);
|
||||||
|
[$discussion2, $post4] = $this->helper_post_to_forum($forum, $user);
|
||||||
|
$discussionkeys = [$discussion1->id, $discussion2->id];
|
||||||
|
|
||||||
|
$viewhidden = $capabilitymanager->can_view_any_private_reply($user);
|
||||||
|
$entities = $this->vault->get_posts_in_forum_for_user_id($discussionkeys, $user->id, $viewhidden, 'modified DESC');
|
||||||
|
$this->assertCount(4, $entities);
|
||||||
|
$this->assertArrayHasKey($post1->id, $entities); // Order is not guaranteed, so just verify element existence.
|
||||||
|
$this->assertArrayHasKey($post2->id, $entities);
|
||||||
|
$this->assertArrayHasKey($post3->id, $entities);
|
||||||
|
$this->assertArrayHasKey($post4->id, $entities);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue