Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Merge branch 'wip-MDL-28615-m20-squashed' of git://github.com/samheme…

…lryk/moodle into MOODLE_20_STABLE
  • Loading branch information...
commit 8e6e5adb5bcf3d3cfe54194ea0c3d0c5f0b05369 2 parents 51acffb + c9cfe78
Aparup Banerjee authored October 05, 2011
57  lib/enrollib.php
@@ -226,11 +226,35 @@ function enrol_check_plugins($user) {
226 226
  * The courses has to be visible and enrolments has to be active,
227 227
  * timestart and timeend restrictions are ignored.
228 228
  *
  229
+ * This function calls {@see enrol_get_shared_courses()} setting checkexistsonly
  230
+ * to true.
  231
+ *
229 232
  * @param stdClass|int $user1
230 233
  * @param stdClass|int $user2
231 234
  * @return bool
232 235
  */
233 236
 function enrol_sharing_course($user1, $user2) {
  237
+    return enrol_get_shared_courses($user1, $user2, false, true);
  238
+}
  239
+
  240
+/**
  241
+ * Returns any courses shared by the two users
  242
+ *
  243
+ * The courses has to be visible and enrolments has to be active,
  244
+ * timestart and timeend restrictions are ignored.
  245
+ *
  246
+ * @global moodle_database $DB
  247
+ * @param stdClass|int $user1
  248
+ * @param stdClass|int $user2
  249
+ * @param bool $preloadcontexts If set to true contexts for the returned courses
  250
+ *              will be preloaded.
  251
+ * @param bool $checkexistsonly If set to true then this function will return true
  252
+ *              if the users share any courses and false if not.
  253
+ * @return array|bool An array of courses that both users are enrolled in OR if
  254
+ *              $checkexistsonly set returns true if the users share any courses
  255
+ *              and false if not.
  256
+ */
  257
+function enrol_get_shared_courses($user1, $user2, $preloadcontexts = false, $checkexistsonly = false) {
234 258
     global $DB, $CFG;
235 259
 
236 260
     $user1 = !empty($user1->id) ? $user1->id : $user1;
@@ -251,14 +275,33 @@ function enrol_sharing_course($user1, $user2) {
251 275
     $params['user1']   = $user1;
252 276
     $params['user2']   = $user2;
253 277
 
254  
-    $sql = "SELECT DISTINCT 'x'
255  
-              FROM {enrol} e
256  
-              JOIN {user_enrolments} ue1 ON (ue1.enrolid = e.id AND ue1.status = :active1 AND ue1.userid = :user1)
257  
-              JOIN {user_enrolments} ue2 ON (ue2.enrolid = e.id AND ue2.status = :active2 AND ue2.userid = :user2)
258  
-              JOIN {course} c ON (c.id = e.courseid AND c.visible = 1)
259  
-             WHERE e.status = :enabled AND e.enrol $plugins";
  278
+    $ctxselect = '';
  279
+    $ctxjoin = '';
  280
+    if ($preloadcontexts) {
  281
+        list($ctxselect, $ctxjoin) = context_instance_preload_sql('c.id', CONTEXT_COURSE, 'ctx');
  282
+    }
260 283
 
261  
-    return $DB->record_exists_sql($sql, $params);
  284
+    $sql = "SELECT c.* $ctxselect
  285
+              FROM {course} c
  286
+              JOIN (
  287
+                SELECT DISTINCT c.id
  288
+                  FROM {enrol} e
  289
+                  JOIN {user_enrolments} ue1 ON (ue1.enrolid = e.id AND ue1.status = :active1 AND ue1.userid = :user1)
  290
+                  JOIN {user_enrolments} ue2 ON (ue2.enrolid = e.id AND ue2.status = :active2 AND ue2.userid = :user2)
  291
+                  JOIN {course} c ON (c.id = e.courseid AND c.visible = 1)
  292
+                 WHERE e.status = :enabled AND e.enrol $plugins
  293
+              ) ec ON ec.id = c.id
  294
+              $ctxjoin";
  295
+
  296
+    if ($checkexistsonly) {
  297
+        return $DB->record_exists_sql($sql, $params);
  298
+    } else {
  299
+        $courses = $DB->get_records_sql($sql, $params);
  300
+        if ($preloadcontexts) {
  301
+            array_map('context_instance_preload', $courses);
  302
+        }
  303
+        return $courses;
  304
+    }
262 305
 }
263 306
 
264 307
 /**
10  mod/forum/lang/en/forum.php
@@ -73,6 +73,7 @@
73 73
 $string['cannotunsubscribe'] = 'Could not unsubscribe you from that forum';
74 74
 $string['cannotupdatepost'] = 'You can not update this post';
75 75
 $string['cannotviewpostyet'] = 'You cannot read other students questions in this discussion yet because you haven\'t posted';
  76
+$string['cannotviewusersposts'] = 'There are no posts made by this user that you are able to view.';
76 77
 $string['cleanreadtime'] = 'Mark old posts as read hour';
77 78
 $string['completiondiscussions'] = 'Student must create discussions:';
78 79
 $string['completiondiscussionsgroup'] = 'Require discussions';
@@ -120,6 +121,7 @@
120 121
 $string['discussions'] = 'Discussions';
121 122
 $string['discussionsstartedby'] = 'Discussions started by {$a}';
122 123
 $string['discussionsstartedbyrecent'] = 'Discussions recently started by {$a}';
  124
+$string['discussionsstartedbyuserincourse'] = 'Discussions started by {$a->fullname} in {$a->coursename}';
123 125
 $string['discussthistopic'] = 'Discuss this topic';
124 126
 $string['displayend'] = 'Display end';
125 127
 $string['displayend_help'] = 'This setting specifies whether a forum post should be hidden after a certain date. Note that administrators can always view forum posts.';
@@ -134,6 +136,7 @@
134 136
 $string['emptymessage'] = 'Something was wrong with your post. Perhaps you left it blank, or the attachment was too big. Your changes have NOT been saved.';
135 137
 $string['erroremptymessage'] = 'Post message cannot be empty';
136 138
 $string['erroremptysubject'] = 'Post subject cannot be empty.';
  139
+$string['errorenrolmentrequired'] = 'You must be enrolled in this course to access this content';
137 140
 $string['errorwhiledelete'] = 'An error occurred while deleting record.';
138 141
 $string['everyonecanchoose'] = 'Everyone can choose to be subscribed';
139 142
 $string['everyonecannowchoose'] = 'Everyone can now choose to be subscribed';
@@ -238,7 +241,8 @@
238 241
 $string['newforumposts'] = 'New forum posts';
239 242
 $string['noattachments'] = 'There are no attachments to this post';
240 243
 $string['nodiscussions'] = 'There are no discussion topics yet in this forum';
241  
-$string['nodiscussionsstartedby'] = 'No discussions started by this user';
  244
+$string['nodiscussionsstartedby'] = '{$a} has not started any discussions';
  245
+$string['nodiscussionsstartedbyyou'] = 'You haven\'t started any discussions yet';
242 246
 $string['noguestpost'] = 'Sorry, guests are not allowed to post.';
243 247
 $string['noguesttracking'] = 'Sorry, guests are not allowed to set tracking options.';
244 248
 $string['nomorepostscontaining'] = 'No more posts containing \'{$a}\' were found';
@@ -248,6 +252,8 @@
248 252
 $string['nopermissiontoview'] = 'You do not have permissions to view this post';
249 253
 $string['nopostforum'] = 'Sorry, you are not allowed to post to this forum';
250 254
 $string['noposts'] = 'No posts';
  255
+$string['nopostsmadebyuser'] = '{$a} has made no posts';
  256
+$string['nopostsmadebyyou'] = 'You haven\'t made any posts';
251 257
 $string['nopostscontaining'] = 'No posts containing \'{$a}\' were found';
252 258
 $string['noquestions'] = 'There are no questions yet in this forum';
253 259
 $string['nosubscribers'] = 'There are no subscribers yet for this forum';
@@ -289,6 +295,8 @@
289 295
 $string['postrating2'] = 'Separate and connected';
290 296
 $string['postrating3'] = 'Mostly connected knowing';
291 297
 $string['posts'] = 'Posts';
  298
+$string['postsmadebyuser'] = 'Posts made by {$a}';
  299
+$string['postsmadebyuserincourse'] = 'Posts made by {$a->fullname} in {$a->coursename}';
292 300
 $string['posttoforum'] = 'Post to forum';
293 301
 $string['postupdated'] = 'Your post was updated';
294 302
 $string['potentialsubscribers'] = 'Potential subscribers';
410  mod/forum/lib.php
@@ -5069,15 +5069,9 @@ function forum_user_can_see_post($forum, $discussion, $post, $user=NULL, $cm=NUL
5069 5069
         $user = $USER;
5070 5070
     }
5071 5071
 
5072  
-    if (isset($cm->cache->caps['mod/forum:viewdiscussion'])) {
5073  
-        if (!$cm->cache->caps['mod/forum:viewdiscussion']) {
5074  
-            return false;
5075  
-        }
5076  
-    } else {
5077  
-        $modcontext = get_context_instance(CONTEXT_MODULE, $cm->id);
5078  
-        if (!has_capability('mod/forum:viewdiscussion', $modcontext, $user->id)) {
5079  
-            return false;
5080  
-        }
  5072
+    $canviewdiscussion = !empty($cm->cache->caps['mod/forum:viewdiscussion']) || has_capability('mod/forum:viewdiscussion', get_context_instance(CONTEXT_MODULE, $cm->id), $user->id);
  5073
+    if (!$canviewdiscussion && !has_all_capabilities(array('moodle/user:viewdetails', 'moodle/user:readuserposts'), get_context_instance(CONTEXT_USER, $post->userid))) {
  5074
+        return false;
5081 5075
     }
5082 5076
 
5083 5077
     if (isset($cm->uservisible)) {
@@ -7965,3 +7959,401 @@ function forum_cm_info_view(cm_info $cm) {
7965 7959
         }
7966 7960
     }
7967 7961
 }
  7962
+
  7963
+/**
  7964
+ * Return a list of page types
  7965
+ * @param string $pagetype current page type
  7966
+ * @param stdClass $parentcontext Block's parent context
  7967
+ * @param stdClass $currentcontext Current context of block
  7968
+ */
  7969
+function forum_page_type_list($pagetype, $parentcontext, $currentcontext) {
  7970
+    $forum_pagetype = array(
  7971
+        'mod-forum-*'=>get_string('page-mod-forum-x', 'forum'),
  7972
+        'mod-forum-view'=>get_string('page-mod-forum-view', 'forum'),
  7973
+        'mod-forum-discuss'=>get_string('page-mod-forum-discuss', 'forum')
  7974
+    );
  7975
+    return $forum_pagetype;
  7976
+}
  7977
+
  7978
+/**
  7979
+ * Gets all of the courses where the provided user has posted in a forum.
  7980
+ *
  7981
+ * @global moodle_database $DB The database connection
  7982
+ * @param stdClass $user The user who's posts we are looking for
  7983
+ * @param bool $discussionsonly If true only look for discussions started by the user
  7984
+ * @param bool $includecontexts If set to trye contexts for the courses will be preloaded
  7985
+ * @param int $limitfrom The offset of records to return
  7986
+ * @param int $limitnum The number of records to return
  7987
+ * @return array An array of courses
  7988
+ */
  7989
+function forum_get_courses_user_posted_in($user, $discussionsonly = false, $includecontexts = true, $limitfrom = null, $limitnum = null) {
  7990
+    global $DB;
  7991
+
  7992
+    // If we are only after discussions we need only look at the forum_discussions
  7993
+    // table and join to the userid there. If we are looking for posts then we need
  7994
+    // to join to the forum_posts table.
  7995
+    if (!$discussionsonly) {
  7996
+        $joinsql = 'JOIN {forum_discussions} fd ON fd.course = c.id
  7997
+                    JOIN {forum_posts} fp ON fp.discussion = fd.id';
  7998
+        $wheresql = 'fp.userid = :userid';
  7999
+        $params = array('userid' => $user->id);
  8000
+    } else {
  8001
+        $joinsql = 'JOIN {forum_discussions} fd ON fd.course = c.id';
  8002
+        $wheresql = 'fd.userid = :userid';
  8003
+        $params = array('userid' => $user->id);
  8004
+    }
  8005
+
  8006
+    // Join to the context table so that we can preload contexts if required.
  8007
+    if ($includecontexts) {
  8008
+        list($ctxselect, $ctxjoin) = context_instance_preload_sql('c.id', CONTEXT_COURSE, 'ctx');
  8009
+    } else {
  8010
+        $ctxselect = '';
  8011
+        $ctxjoin = '';
  8012
+    }
  8013
+
  8014
+    // Now we need to get all of the courses to search.
  8015
+    // All courses where the user has posted within a forum will be returned.
  8016
+    $sql = "SELECT DISTINCT c.* $ctxselect
  8017
+            FROM {course} c
  8018
+            $joinsql
  8019
+            $ctxjoin
  8020
+            WHERE $wheresql";
  8021
+    $courses = $DB->get_records_sql($sql, $params, $limitfrom, $limitnum);
  8022
+    if ($includecontexts) {
  8023
+        array_map('context_instance_preload', $courses);
  8024
+    }
  8025
+    return $courses;
  8026
+}
  8027
+
  8028
+/**
  8029
+ * Gets all of the forums a user has posted in for one or more courses.
  8030
+ *
  8031
+ * @global moodle_database $DB
  8032
+ * @param stdClass $user
  8033
+ * @param array $courseids An array of courseids to search or if not provided
  8034
+ *                       all courses the user has posted within
  8035
+ * @param bool $discussionsonly If true then only forums where the user has started
  8036
+ *                       a discussion will be returned.
  8037
+ * @param int $limitfrom The offset of records to return
  8038
+ * @param int $limitnum The number of records to return
  8039
+ * @return array An array of forums the user has posted within in the provided courses
  8040
+ */
  8041
+function forum_get_forums_user_posted_in($user, array $courseids = null, $discussionsonly = false, $limitfrom = null, $limitnum = null) {
  8042
+    global $DB;
  8043
+
  8044
+    $where = array("m.name = 'forum'");
  8045
+    $params = array();
  8046
+    if (!is_null($courseids)) {
  8047
+        list($coursewhere, $params) = $DB->get_in_or_equal($courseids, SQL_PARAMS_NAMED, 'courseid');
  8048
+        $where[] = 'f.course '.$coursewhere;
  8049
+    }
  8050
+    if (!$discussionsonly) {
  8051
+        $joinsql = 'JOIN {forum_discussions} fd ON fd.forum = f.id
  8052
+                    JOIN {forum_posts} fp ON fp.discussion = fd.id';
  8053
+        $where[] = 'fp.userid = :userid';
  8054
+    } else {
  8055
+        $joinsql = 'JOIN {forum_discussions} fd ON fd.forum = f.id';
  8056
+        $where[] = 'fd.userid = :userid';
  8057
+    }
  8058
+    $params['userid'] = $user->id;
  8059
+    $wheresql = join(' AND ', $where);
  8060
+
  8061
+    $sql = "SELECT DISTINCT f.*, cm.id AS cmid
  8062
+            FROM {forum} f
  8063
+            JOIN {course_modules} cm ON cm.instance = f.id
  8064
+            JOIN {modules} m ON m.id = cm.module
  8065
+            $joinsql
  8066
+            WHERE $wheresql";
  8067
+    $courseforums = $DB->get_records_sql($sql, $params, $limitfrom, $limitnum);
  8068
+    return $courseforums;
  8069
+}
  8070
+
  8071
+/**
  8072
+ * Returns posts made by the selected user in the requested courses.
  8073
+ *
  8074
+ * This method can be used to return all of the posts made by the requested user
  8075
+ * within the given courses.
  8076
+ * For each course the access of the current user and requested user is checked
  8077
+ * and then for each post access to the post and forum is checked as well.
  8078
+ *
  8079
+ * This function is safe to use with usercapabilities.
  8080
+ *
  8081
+ * @global moodle_database $DB
  8082
+ * @param stdClass $user The user whose posts we want to get
  8083
+ * @param array $courses The courses to search
  8084
+ * @param bool $musthaveaccess If set to true errors will be thrown if the user
  8085
+ *                             cannot access one or more of the courses to search
  8086
+ * @param bool $discussionsonly If set to true only discussion starting posts
  8087
+ *                              will be returned.
  8088
+ * @param int $limitfrom The offset of records to return
  8089
+ * @param int $limitnum The number of records to return
  8090
+ * @return stdClass An object the following properties
  8091
+ *               ->totalcount: the total number of posts made by the requested user
  8092
+ *                             that the current user can see.
  8093
+ *               ->courses: An array of courses the current user can see that the
  8094
+ *                          requested user has posted in.
  8095
+ *               ->forums: An array of forums relating to the posts returned in the
  8096
+ *                         property below.
  8097
+ *               ->posts: An array containing the posts to show for this request.
  8098
+ */
  8099
+function forum_get_posts_by_user($user, array $courses, $musthaveaccess = false, $discussionsonly = false, $limitfrom = 0, $limitnum = 50) {
  8100
+    global $DB, $USER;
  8101
+
  8102
+    $return = new stdClass;
  8103
+    $return->totalcount = 0;    // The total number of posts that the current user is able to view
  8104
+    $return->courses = array(); // The courses the current user can access
  8105
+    $return->forums = array();  // The forums that the current user can access that contain posts
  8106
+    $return->posts = array();   // The posts to display
  8107
+
  8108
+    // First up a small sanity check. If there are no courses to check we can
  8109
+    // return immediately, there is obviously nothing to search.
  8110
+    if (empty($courses)) {
  8111
+        return $return;
  8112
+    }
  8113
+
  8114
+    // A couple of quick setups
  8115
+    $isloggedin = isloggedin();
  8116
+    $isguestuser = $isloggedin && isguestuser();
  8117
+    $iscurrentuser = $isloggedin && $USER->id == $user->id;
  8118
+
  8119
+    // Checkout whether or not the current user has capabilities over the requested
  8120
+    // user and if so they have the capabilities required to view the requested
  8121
+    // users content.
  8122
+    $usercontext = get_context_instance(CONTEXT_USER, $user->id, MUST_EXIST);
  8123
+    $hascapsonuser = !$iscurrentuser && $DB->record_exists('role_assignments', array('userid' => $USER->id, 'contextid' => $usercontext->id));
  8124
+    $hascapsonuser = $hascapsonuser && has_all_capabilities(array('moodle/user:viewdetails', 'moodle/user:readuserposts'), $usercontext);
  8125
+
  8126
+    // Before we actually search each course we need to check the user's access to the
  8127
+    // course. If the user doesn't have the appropraite access then we either throw an
  8128
+    // error if a particular course was requested or we just skip over the course.
  8129
+    foreach ($courses as $course) {
  8130
+        $coursecontext = get_context_instance(CONTEXT_COURSE, $course->id, MUST_EXIST);
  8131
+        if ($iscurrentuser || $hascapsonuser) {
  8132
+            // If it is the current user, or the current user has capabilities to the
  8133
+            // requested user then all we need to do is check the requested users
  8134
+            // current access to the course.
  8135
+            // Note: There is no need to check group access or anything of the like
  8136
+            // as either the current user is the requested user, or has granted
  8137
+            // capabilities on the requested user. Either way they can see what the
  8138
+            // requested user posted, although its VERY unlikely in the `parent` situation
  8139
+            // that the current user will be able to view the posts in context.
  8140
+            if (!is_viewing($coursecontext, $user) && !is_enrolled($coursecontext, $user)) {
  8141
+                // Need to have full access to a course to see the rest of own info
  8142
+                if ($musthaveaccess) {
  8143
+                    print_error('errorenrolmentrequired', 'forum');
  8144
+                }
  8145
+                continue;
  8146
+            }
  8147
+        } else {
  8148
+            // Check whether the current user is enrolled or has access to view the course
  8149
+            // if they don't we immediately have a problem.
  8150
+            if (!can_access_course($coursecontext)) {
  8151
+                if ($musthaveaccess) {
  8152
+                    print_error('errorenrolmentrequired', 'forum');
  8153
+                }
  8154
+                continue;
  8155
+            }
  8156
+
  8157
+            // Check whether the requested user is enrolled or has access to view the course
  8158
+            // if they don't we immediately have a problem.
  8159
+            if (!can_access_course($coursecontext, $user)) {
  8160
+                if ($musthaveaccess) {
  8161
+                    print_error('notenrolled', 'forum');
  8162
+                }
  8163
+                continue;
  8164
+            }
  8165
+
  8166
+            // If groups are in use and enforced throughout the course then make sure
  8167
+            // we can meet in at least one course level group.
  8168
+            // Note that we check if either the current user or the requested user have
  8169
+            // the capability to access all groups. This is because with that capability
  8170
+            // a user in group A could post in the group B forum. Grrrr.
  8171
+            if (groups_get_course_groupmode($course) == SEPARATEGROUPS && $course->groupmodeforce
  8172
+              && !has_capability('moodle/site:accessallgroups', $coursecontext) && !has_capability('moodle/site:accessallgroups', $coursecontext, $user->id)) {
  8173
+                // If its the guest user to bad... the guest user cannot access groups
  8174
+                if (!$isloggedin or $isguestuser) {
  8175
+                    // do not use require_login() here because we might have already used require_login($course)
  8176
+                    if ($musthaveaccess) {
  8177
+                        redirect(get_login_url());
  8178
+                    }
  8179
+                    continue;
  8180
+                }
  8181
+                // Get the groups of the current user
  8182
+                $mygroups = array_keys(groups_get_all_groups($course->id, $USER->id, $course->defaultgroupingid, 'g.id, g.name'));
  8183
+                // Get the groups the requested user is a member of
  8184
+                $usergroups = array_keys(groups_get_all_groups($course->id, $user->id, $course->defaultgroupingid, 'g.id, g.name'));
  8185
+                // Check whether they are members of the same group. If they are great.
  8186
+                $intersect = array_intersect($mygroups, $usergroups);
  8187
+                if (empty($intersect)) {
  8188
+                    // But they're not... if it was a specific course throw an error otherwise
  8189
+                    // just skip this course so that it is not searched.
  8190
+                    if ($musthaveaccess) {
  8191
+                        print_error("groupnotamember", '', $CFG->wwwroot."/course/view.php?id=$course->id");
  8192
+                    }
  8193
+                    continue;
  8194
+                }
  8195
+            }
  8196
+        }
  8197
+        // Woo hoo we got this far which means the current user can search this
  8198
+        // this course for the requested user. Although this is only the course accessibility
  8199
+        // handling that is complete, the forum accessibility tests are yet to come.
  8200
+        $return->courses[$course->id] = $course;
  8201
+    }
  8202
+    // No longer beed $courses array - lose it not it may be big
  8203
+    unset($courses);
  8204
+
  8205
+    // Make sure that we have some courses to search
  8206
+    if (empty($return->courses)) {
  8207
+        // If we don't have any courses to search then the reality is that the current
  8208
+        // user doesn't have access to any courses is which the requested user has posted.
  8209
+        // Although we do know at this point that the requested user has posts.
  8210
+        if ($musthaveaccess) {
  8211
+            print_error('permissiondenied');
  8212
+        } else {
  8213
+            return $return;
  8214
+        }
  8215
+    }
  8216
+
  8217
+    // Next step: Collect all of the forums that we will want to search.
  8218
+    // It is important to note that this step isn't actually about searching, it is
  8219
+    // about determining which forums we can search by testing accessibility.
  8220
+    $forums = forum_get_forums_user_posted_in($user, array_keys($return->courses), $discussionsonly);
  8221
+
  8222
+    // Will be used to build the where conditions for the search
  8223
+    $forumsearchwhere = array();
  8224
+    // Will be used to store the where condition params for the search
  8225
+    $forumsearchparams = array();
  8226
+    // Will record forums where the user can freely access everything
  8227
+    $forumsearchfullaccess = array();
  8228
+    // DB caching friendly
  8229
+    $now = round(time(), -2);
  8230
+    // For each course to search we want to find the forums the user has posted in
  8231
+    // and providing the current user can access the forum create a search condition
  8232
+    // for the forum to get the requested users posts.
  8233
+    foreach ($return->courses as $course) {
  8234
+        // Now we need to get the forums
  8235
+        $modinfo = get_fast_modinfo($course);
  8236
+        if (empty($modinfo->instances['forum'])) {
  8237
+            // hmmm, no forums? well at least its easy... skip!
  8238
+            continue;
  8239
+        }
  8240
+        // Iterate
  8241
+        foreach ($modinfo->get_instances_of('forum') as $forumid => $cm) {
  8242
+            if (!$cm->uservisible or !isset($forums[$forumid])) {
  8243
+                continue;
  8244
+            }
  8245
+            // Get the forum in question
  8246
+            $forum = $forums[$forumid];
  8247
+            // This is needed for functionality later on in the forum code....
  8248
+            $forum->cm = $cm;
  8249
+
  8250
+            // Check that either the current user can view the forum, or that the
  8251
+            // current user has capabilities over the requested user and the requested
  8252
+            // user can view the discussion
  8253
+            if (!has_capability('mod/forum:viewdiscussion', $cm->context) && !($hascapsonuser && has_capability('mod/forum:viewdiscussion', $cm->context, $user->id))) {
  8254
+                continue;
  8255
+            }
  8256
+
  8257
+            // This will contain forum specific where clauses
  8258
+            $forumsearchselect = array();
  8259
+            if (!$iscurrentuser && !$hascapsonuser) {
  8260
+                // Make sure we check group access
  8261
+                if (groups_get_activity_groupmode($cm, $course) == SEPARATEGROUPS and !has_capability('moodle/site:accessallgroups', $cm->context)) {
  8262
+                    $groups = $modinfo->get_groups($cm->groupingid);
  8263
+                    $groups[] = -1;
  8264
+                    list($groupid_sql, $groupid_params) = $DB->get_in_or_equal($groups, SQL_PARAMS_NAMED, 'grps'.$forumid.'_');
  8265
+                    $forumsearchparams = array_merge($forumsearchparams, $groupid_params);
  8266
+                    $forumsearchselect[] = "d.groupid $groupid_sql";
  8267
+                }
  8268
+
  8269
+                // hidden timed discussions
  8270
+                if (!empty($CFG->forum_enabletimedposts) && !has_capability('mod/forum:viewhiddentimedposts', $cm->context)) {
  8271
+                    $forumsearchselect[] = "(d.userid = :userid{$forumid} OR (d.timestart < :timestart{$forumid} AND (d.timeend = 0 OR d.timeend > :timeend{$forumid})))";
  8272
+                    $forumsearchparams['userid'.$forumid] = $user->id;
  8273
+                    $forumsearchparams['timestart'.$forumid] = $now;
  8274
+                    $forumsearchparams['timeend'.$forumid] = $now;
  8275
+                }
  8276
+
  8277
+                // qanda access
  8278
+                if ($forum->type == 'qanda' && !has_capability('mod/forum:viewqandawithoutposting', $cm->context)) {
  8279
+                    // We need to check whether the user has posted in the qanda forum.
  8280
+                    $discussionspostedin = forum_discussions_user_has_posted_in($forum->id, $user->id);
  8281
+                    if (!empty($discussionspostedin)) {
  8282
+                        $forumonlydiscussions = array();  // Holds discussion ids for the discussions the user is allowed to see in this forum.
  8283
+                        foreach ($discussionspostedin as $d) {
  8284
+                            $forumonlydiscussions[] = $d->id;
  8285
+                        }
  8286
+                        list($discussionid_sql, $discussionid_params) = $DB->get_in_or_equal($forumonlydiscussions, SQL_PARAMS_NAMED, 'qanda'.$forumid.'_');
  8287
+                        $forumsearchparams = array_merge($forumsearchparams, $discussionid_params);
  8288
+                        $forumsearchselect[] = "(d.id $discussionid_sql OR p.parent = 0)";
  8289
+                    } else {
  8290
+                        $forumsearchselect[] = "p.parent = 0";
  8291
+                    }
  8292
+
  8293
+                }
  8294
+
  8295
+                if (count($forumsearchselect) > 0) {
  8296
+                    $forumsearchwhere[] = "(d.forum = :forum{$forumid} AND ".implode(" AND ", $forumsearchselect).")";
  8297
+                    $forumsearchparams['forum'.$forumid] = $forumid;
  8298
+                } else {
  8299
+                    $forumsearchfullaccess[] = $forumid;
  8300
+                }
  8301
+            } else {
  8302
+                // The current user/parent can see all of their own posts
  8303
+                $forumsearchfullaccess[] = $forumid;
  8304
+            }
  8305
+        }
  8306
+    }
  8307
+
  8308
+    // If we dont have any search conditions, and we don't have any forums where
  8309
+    // the user has full access then we just return the default.
  8310
+    if (empty($forumsearchwhere) && empty($forumsearchfullaccess)) {
  8311
+        return $return;
  8312
+    }
  8313
+
  8314
+    // Prepare a where condition for the full access forums.
  8315
+    if (count($forumsearchfullaccess) > 0) {
  8316
+        list($fullidsql, $fullidparams) = $DB->get_in_or_equal($forumsearchfullaccess, SQL_PARAMS_NAMED, 'fula');
  8317
+        $forumsearchparams = array_merge($forumsearchparams, $fullidparams);
  8318
+        $forumsearchwhere[] = "(d.forum $fullidsql)";
  8319
+    }
  8320
+
  8321
+    // Prepare SQL to both count and search
  8322
+    $userfields = user_picture::fields('u', null, 'userid');
  8323
+    $countsql = 'SELECT COUNT(*) ';
  8324
+    $selectsql = 'SELECT p.*, d.forum, d.name AS discussionname, '.$userfields.' ';
  8325
+    $wheresql = implode(" OR ", $forumsearchwhere);
  8326
+
  8327
+    if ($discussionsonly) {
  8328
+        if ($wheresql == '') {
  8329
+            $wheresql = 'p.parent = 0';
  8330
+        } else {
  8331
+            $wheresql = 'p.parent = 0 AND ('.$wheresql.')';
  8332
+        }
  8333
+    }
  8334
+
  8335
+    $sql = "FROM {forum_posts} p
  8336
+            JOIN {forum_discussions} d ON d.id = p.discussion
  8337
+            JOIN {user} u ON u.id = p.userid
  8338
+           WHERE ($wheresql)
  8339
+             AND p.userid = :userid ";
  8340
+    $orderby = "ORDER BY p.modified DESC";
  8341
+    $forumsearchparams['userid'] = $user->id;
  8342
+
  8343
+    // Set the total number posts made by the requested user that the current user can see
  8344
+    $return->totalcount = $DB->count_records_sql($countsql.$sql, $forumsearchparams);
  8345
+    // Set the collection of posts that has been requested
  8346
+    $return->posts = $DB->get_records_sql($selectsql.$sql.$orderby, $forumsearchparams, $limitfrom, $limitnum);
  8347
+
  8348
+    // We need to build an array of forums for which posts will be displayed.
  8349
+    // We do this here to save the caller needing to retrieve them themselves before
  8350
+    // printing these forums posts. Given we have the forums already there is
  8351
+    // practically no overhead here.
  8352
+    foreach ($return->posts as $post) {
  8353
+        if (!array_key_exists($post->forum, $return->forums)) {
  8354
+            $return->forums[$post->forum] = $forums[$post->forum];
  8355
+        }
  8356
+    }
  8357
+
  8358
+    return $return;
  8359
+}
434  mod/forum/user.php
@@ -23,203 +23,321 @@
23 23
  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24 24
  */
25 25
 
26  
-require_once('../../config.php');
27  
-require_once('lib.php');
28  
-
29  
-// Course ID
30  
-$course  = optional_param('course', SITEID, PARAM_INT);
31  
-// User ID
32  
-$id      = optional_param('id', 0, PARAM_INT);
33  
-$mode    = optional_param('mode', 'posts', PARAM_ALPHA);
34  
-$page    = optional_param('page', 0, PARAM_INT);
35  
-$perpage = optional_param('perpage', 5, PARAM_INT);
36  
-
37  
-$url = new moodle_url('/mod/forum/user.php');
38  
-if ($course !== SITEID) {
39  
-    $url->param('course', $course);
  26
+require_once(dirname(dirname(dirname(__FILE__))).'/config.php');
  27
+require_once($CFG->dirroot.'/mod/forum/lib.php');
  28
+require_once($CFG->dirroot.'/rating/lib.php');
  29
+
  30
+$courseid  = optional_param('course', null, PARAM_INT); // Limit the posts to just this course
  31
+$userid = optional_param('id', $USER->id, PARAM_INT);        // User id whose posts we want to view
  32
+$mode = optional_param('mode', 'posts', PARAM_ALPHA);   // The mode to use. Either posts or discussions
  33
+$page = optional_param('page', 0, PARAM_INT);           // The page number to display
  34
+$perpage = optional_param('perpage', 5, PARAM_INT);     // The number of posts to display per page
  35
+
  36
+if (empty($userid)) {
  37
+    if (!isloggedin()) {
  38
+        require_login();
  39
+    }
  40
+    $userid = $USER->id;
40 41
 }
41  
-if ($id !== 0) {
42  
-    $url->param('id', $id);
  42
+
  43
+$discussionsonly = ($mode !== 'posts');
  44
+$isspecificcourse = !is_null($courseid);
  45
+$iscurrentuser = ($USER->id == $userid);
  46
+
  47
+$url = new moodle_url('/mod/forum/user.php', array('id' => $userid));
  48
+if ($isspecificcourse) {
  49
+    $url->param('course', $courseid);
43 50
 }
44  
-if ($mode !== 'posts') {
45  
-    $url->param('mode', $mode);
  51
+if ($discussionsonly) {
  52
+    $url->param('mode', 'discussions');
46 53
 }
  54
+
47 55
 $PAGE->set_url($url);
48 56
 $PAGE->set_pagelayout('standard');
49 57
 
50  
-if (empty($id)) {         // See your own profile by default
51  
-    require_login();
52  
-    $id = $USER->id;
  58
+if ($page != 0) {
  59
+    $url->param('page', $page);
  60
+}
  61
+if ($perpage != 5) {
  62
+    $url->param('perpage', $perpage);
53 63
 }
54 64
 
55  
-$user = $DB->get_record("user", array("id" => $id), '*', MUST_EXIST);
56  
-$course = $DB->get_record("course", array("id" => $course), '*', MUST_EXIST);
57  
-
58  
-$syscontext = get_context_instance(CONTEXT_SYSTEM);
59  
-$usercontext   = get_context_instance(CONTEXT_USER, $id);
  65
+add_to_log(($isspecificcourse)?$courseid:SITEID, "forum", "user report", 'user.php?'.$url->get_query_string(), $userid);
60 66
 
61  
-// do not force parents to enrol
62  
-if (!$DB->get_record('role_assignments', array('userid' => $USER->id, 'contextid' => $usercontext->id))) {
63  
-    require_course_login($course);
64  
-} else {
65  
-    $PAGE->set_course($course);
  67
+$user = $DB->get_record("user", array("id" => $userid), '*', MUST_EXIST);
  68
+$usercontext = get_context_instance(CONTEXT_USER, $user->id, MUST_EXIST);
  69
+// Check if the requested user is the guest user
  70
+if (isguestuser($user)) {
  71
+    // The guest user cannot post, so it is not possible to view any posts.
  72
+    // May as well just bail aggressively here.
  73
+    print_error('invaliduserid');
66 74
 }
67  
-
  75
+// Make sure the user has not been deleted
68 76
 if ($user->deleted) {
  77
+    $PAGE->set_title(get_string('userdeleted'));
  78
+    $PAGE->set_context(get_system_context());
69 79
     echo $OUTPUT->header();
70  
-    echo $OUTPUT->heading(get_string('userdeleted'));
  80
+    echo $OUTPUT->heading($PAGE->title);
71 81
     echo $OUTPUT->footer();
72 82
     die;
73 83
 }
74 84
 
75  
-add_to_log($course->id, "forum", "user report",
76  
-        "user.php?course=$course->id&amp;id=$user->id&amp;mode=$mode", "$user->id");
77  
-
78  
-$strforumposts   = get_string('forumposts', 'forum');
79  
-$strparticipants = get_string('participants');
80  
-$strmode         = get_string($mode, 'forum');
81  
-$fullname        = fullname($user, has_capability('moodle/site:viewfullnames', $syscontext));
82  
-
83  
-$link = null;
84  
-if (has_capability('moodle/course:viewparticipants', get_context_instance(CONTEXT_COURSE, $course->id)) || has_capability('moodle/site:viewparticipants', $syscontext)) {
85  
-    $link = new moodle_url('/user/index.php',array('id'=>$course->id));
86  
-}
87  
-
88  
-$PAGE->navigation->extend_for_user($user);
89  
-$PAGE->navigation->set_userid_for_parent_checks($id); // see MDL-25805 for reasons and for full commit reference for reversal when fixed.
90  
-$PAGE->set_title("$course->shortname: $fullname: $strmode");
91  
-$PAGE->set_heading($course->fullname);
92  
-echo $OUTPUT->header();
93  
-echo $OUTPUT->heading($fullname);
94  
-
95  
-switch ($mode) {
96  
-    case 'posts' :
97  
-        $searchterms = array('userid:'.$user->id);
98  
-        $extrasql = '';
99  
-        break;
100  
-
101  
-    default:
102  
-        $searchterms = array('userid:'.$user->id);
103  
-        $extrasql = 'AND p.parent = 0';
104  
-        break;
105  
-}
106  
-
107  
-echo '<div class="user-content">';
108  
-
109  
-if ($course->id == SITEID) {
110  
-    $searchcourse = SITEID;
111  
-    if (empty($CFG->forceloginforprofiles) or (isloggedin() and !isguestuser() and !is_web_crawler())) {
112  
-        // Search throughout the whole site.
113  
-        $searchcourse = 0;
  85
+$isloggedin = isloggedin();
  86
+$isguestuser = $isloggedin && isguestuser();
  87
+$isparent = !$iscurrentuser && $DB->record_exists('role_assignments', array('userid'=>$USER->id, 'contextid'=>$usercontext->id));
  88
+$hasparentaccess = $isparent && has_all_capabilities(array('moodle/user:viewdetails', 'moodle/user:readuserposts'), $usercontext);
  89
+
  90
+// Check whether a specific course has been requested
  91
+if ($isspecificcourse) {
  92
+    // Get the requested course and its context
  93
+    $course = $DB->get_record('course', array('id' => $courseid), '*', MUST_EXIST);
  94
+    $coursecontext = get_context_instance(CONTEXT_COURSE, $courseid, MUST_EXIST);
  95
+    // We have a specific course to search, which we will also assume we are within.
  96
+    if ($hasparentaccess) {
  97
+        // A `parent` role won't likely have access to the course so we won't attempt
  98
+        // to enter it. We will however still make them jump through the normal
  99
+        // login hoops
  100
+        require_login();
  101
+        $PAGE->set_context($coursecontext);
  102
+        $PAGE->set_course($course);
  103
+    } else {
  104
+        // Enter the course we are searching
  105
+        require_login($course);
114 106
     }
  107
+    // Get the course ready for access checks
  108
+    $courses = array($courseid => $course);
115 109
 } else {
116  
-    // Search only for posts the user made in this course.
117  
-    $searchcourse = $course->id;
118  
-}
119  
-
120  
-// Get the posts.
121  
-if ($posts = forum_search_posts($searchterms, $searchcourse, $page*$perpage, $perpage, $totalcount, $extrasql)) {
122  
-
123  
-    require_once($CFG->dirroot.'/rating/lib.php');
  110
+    // We are going to search for all of the users posts in all courses!
  111
+    // a general require login here as we arn't actually within any course.
  112
+    require_login();
  113
+    $PAGE->set_context(get_system_context());
124 114
 
125  
-    $baseurl = new moodle_url('user.php', array('id' => $user->id, 'course' => $course->id, 'mode' => $mode, 'perpage' => $perpage));
126  
-    echo $OUTPUT->paging_bar($totalcount, $page, $perpage, $baseurl);
  115
+    // Now we need to get all of the courses to search.
  116
+    // All courses where the user has posted within a forum will be returned.
  117
+    $courses = forum_get_courses_user_posted_in($user, $discussionsonly);
  118
+}
127 119
 
128  
-    $discussions = array();
129  
-    $forums      = array();
130  
-    $cms         = array();
  120
+// Get the posts by the requested user that the current user can access.
  121
+$result = forum_get_posts_by_user($user, $courses, $isspecificcourse, $discussionsonly, ($page * $perpage), $perpage);
  122
+
  123
+// Check whether there are not posts to display.
  124
+if (empty($result->posts)) {
  125
+    // Ok no posts to display means that either the user has not posted or there
  126
+    // are no posts made by the requested user that the current user is able to
  127
+    // see.
  128
+    // In either case we need to decide whether we can show personal information
  129
+    // about the requested user to the current user so we will execute some checks
  130
+
  131
+    // First check the obvious, its the current user, a specific course has been
  132
+    // provided (require_login has been called), or they have a course contact role.
  133
+    // True to any of those and the current user can see the details of the
  134
+    // requested user.
  135
+    $canviewuser = ($iscurrentuser || $isspecificcourse || empty($CFG->forceloginforprofiles) || has_coursecontact_role($userid));
  136
+    // Next we'll check the caps, if the current user has the view details and a
  137
+    // specific course has been requested, or if they have the view all details
  138
+    $canviewuser = ($canviewuser || ($isspecificcourse && has_capability('moodle/user:viewdetails', $coursecontext) || has_capability('moodle/user:viewalldetails', $usercontext)));
  139
+
  140
+    // If none of the above was true the next step is to check a shared relation
  141
+    // through some course
  142
+    if (!$canviewuser) {
  143
+        // Get all of the courses that the users have in common
  144
+        $sharedcourses = enrol_get_shared_courses($USER->id, $user->id, true);
  145
+        foreach ($sharedcourses as $sharedcourse) {
  146
+            // Check the view cap within the course context
  147
+            if (has_capability('moodle/user:viewdetails', get_context_instance(CONTEXT_COURSE, $sharedcourse->id))) {
  148
+                $canviewuser = true;
  149
+                break;
  150
+            }
  151
+        }
  152
+        unset($sharedcourses);
  153
+    }
131 154
 
132  
-    //todo Rather than retrieving the ratings for each post individually it would be nice to do them in groups
133  
-    //however this requires creating arrays of posts with each array containing all of the posts from a particular forum,
134  
-    //retrieving the ratings then reassembling them all back into a single array sorted by post.modified (descending)
135  
-    $rm = new rating_manager();
136  
-    $ratingoptions = new stdclass();
137  
-    $ratingoptions->plugintype = 'mod';
138  
-    $ratingoptions->pluginname = 'forum';
  155
+    // Prepare the page title
  156
+    $pagetitle = get_string('noposts', 'mod_forum');
139 157
 
140  
-    foreach ($posts as $post) {
  158
+    // Get the page heading
  159
+    if ($isspecificcourse) {
  160
+        $pageheading = format_string($course->shortname, true, array('context' => $coursecontext));
  161
+    } else {
  162
+        $pageheading = get_string('pluginname', 'mod_forum');
  163
+    }
141 164
 
142  
-        if (!isset($discussions[$post->discussion])) {
143  
-            if (! $discussion = $DB->get_record('forum_discussions', array('id' => $post->discussion))) {
144  
-                print_error('invaliddiscussionid', 'forum');
145  
-            }
146  
-            $discussions[$post->discussion] = $discussion;
  165
+    // Next we need to set up the loading of the navigation and choose a message
  166
+    // to display to the current user.
  167
+    if ($iscurrentuser) {
  168
+        // No need to extend the navigation it happens automatically for the
  169
+        // current user.
  170
+        if ($discussionsonly) {
  171
+            $notification = get_string('nodiscussionsstartedbyyou', 'forum');
147 172
         } else {
148  
-            $discussion = $discussions[$post->discussion];
  173
+            $notification = get_string('nopostsmadebyyou', 'forum');
149 174
         }
150  
-
151  
-        if (!isset($forums[$discussion->forum])) {
152  
-            if (! $forum = $DB->get_record('forum', array('id' => $discussion->forum))) {
153  
-                print_error('invalidforumid', 'forum');
154  
-            }
155  
-            //hold onto forum cm and context for when we load ratings
156  
-            if ($forumcm = get_coursemodule_from_instance('forum', $forum->id)) {
157  
-                $forum->cm = $forumcm;
158  
-                $forumcontext = get_context_instance(CONTEXT_MODULE, $forum->cm->id);
159  
-                $forum->context = $forumcontext;
160  
-            }
161  
-            $forums[$discussion->forum] = $forum;
  175
+    } else if ($canviewuser) {
  176
+        $PAGE->navigation->extend_for_user($user);
  177
+        $PAGE->navigation->set_userid_for_parent_checks($user->id); // see MDL-25805 for reasons and for full commit reference for reversal when fixed.
  178
+        $fullname = fullname($user);
  179
+        if ($discussionsonly) {
  180
+            $notification = get_string('nodiscussionsstartedby', 'forum', $fullname);
162 181
         } else {
163  
-            $forum = $forums[$discussion->forum];
  182
+            $notification = get_string('nopostsmadebyuser', 'forum', $fullname);
164 183
         }
165  
-
166  
-        //load ratings
167  
-        if ($forum->assessed!=RATING_AGGREGATE_NONE) {
168  
-            $ratingoptions->context = $forum->context;
169  
-            $ratingoptions->component = 'mod_forum';
170  
-            $ratingoptions->items = array($post);
171  
-            $ratingoptions->aggregate = $forum->assessed;//the aggregation method
172  
-            $ratingoptions->scaleid = $forum->scale;
173  
-            $ratingoptions->userid = $user->id;
174  
-            if ($forum->type == 'single' or !$discussion->id) {
175  
-                $ratingoptions->returnurl = "$CFG->wwwroot/mod/forum/view.php?id={$forum->cm->id}";
176  
-            } else {
177  
-                $ratingoptions->returnurl = "$CFG->wwwroot/mod/forum/discuss.php?d=$discussion->id";
178  
-            }
179  
-            $ratingoptions->assesstimestart = $forum->assesstimestart;
180  
-            $ratingoptions->assesstimefinish = $forum->assesstimefinish;
181  
-
182  
-            $updatedpost = $rm->get_ratings($ratingoptions);
183  
-            //updating the array this way because we're iterating over a collection and updating them one by one
184  
-            $posts[$updatedpost[0]->id] = $updatedpost[0];
  184
+    } else {
  185
+        // Don't extend the navigation it would be giving out information that
  186
+        // the current uesr doesn't have access to.
  187
+        $notification = get_string('cannotviewusersposts', 'forum');
  188
+        if ($isspecificcourse) {
  189
+            $url = new moodle_url('/course/view.php', array('id' => $courseid));
  190
+        } else {
  191
+            $url = new moodle_url('/');
185 192
         }
  193
+        navigation_node::override_active_url($url);
  194
+    }
186 195
 
187  
-        if (!isset($cms[$forum->id])) {
188  
-            $cm = get_coursemodule_from_instance('forum', $forum->id, 0, false, MUST_EXIST);
189  
-            $cms[$forum->id] = $cm;
190  
-            unset($cm); // do not use cm directly, it would break caching
191  
-        }
  196
+    // Display a page letting the user know that there's nothing to display;
  197
+    $PAGE->set_title($pagetitle);
  198
+    $PAGE->set_heading($pageheading);
  199
+    echo $OUTPUT->header();
  200
+    echo $OUTPUT->heading($pagetitle);
  201
+    echo $OUTPUT->notification($notification);
  202
+    if (!$url->compare($PAGE->url)) {
  203
+        echo $OUTPUT->continue_button($url);
  204
+    }
  205
+    echo $OUTPUT->footer();
  206
+    die;
  207
+}
192 208
 
193  
-        $fullsubject = "<a href=\"view.php?f=$forum->id\">".format_string($forum->name,true)."</a>";
194  
-        if ($forum->type != 'single') {
195  
-            $fullsubject .= " -> <a href=\"discuss.php?d=$discussion->id\">".format_string($discussion->name,true)."</a>";
196  
-            if ($post->parent != 0) {
197  
-                $fullsubject .= " -> <a href=\"discuss.php?d=$post->discussion&amp;parent=$post->id\">".format_string($post->subject,true)."</a>";
198  
-            }
199  
-        }
  209
+// Post output will contain an entry containing HTML to display each post by the
  210
+// time we are done.
  211
+$postoutput = array();
200 212
 
201  
-        if ($course->id == SITEID && has_capability('moodle/site:config', $syscontext)) {
202  
-            $postcoursename = $DB->get_field('course', 'shortname', array('id'=>$forum->course));
203  
-            $fullsubject = '<a href="'.$CFG->wwwroot.'/course/view.php?id='.$forum->course.'">'.$postcoursename.'</a> -> '. $fullsubject;
  213
+$discussions = array();
  214
+foreach ($result->posts as $post) {
  215
+    $discussions[] = $post->discussion;
  216
+}
  217
+$discussions = $DB->get_records_list('forum_discussions', 'id', array_unique($discussions));
  218
+
  219
+//todo Rather than retrieving the ratings for each post individually it would be nice to do them in groups
  220
+//however this requires creating arrays of posts with each array containing all of the posts from a particular forum,
  221
+//retrieving the ratings then reassembling them all back into a single array sorted by post.modified (descending)
  222
+$rm = new rating_manager();
  223
+$ratingoptions = new stdClass;
  224
+$ratingoptions->component = 'mod_forum';
  225
+$ratingoptions->ratingarea = 'post';
  226
+foreach ($result->posts as $post) {
  227
+    if (!isset($result->forums[$post->forum]) || !isset($discussions[$post->discussion])) {
  228
+        // Something very VERY dodgy has happened if we end up here
  229
+        continue;
  230
+    }
  231
+    $forum = $result->forums[$post->forum];
  232
+    $cm = $forum->cm;
  233
+    $discussion = $discussions[$post->discussion];
  234
+    $course = $result->courses[$discussion->course];
  235
+
  236
+    $forumurl = new moodle_url('/mod/forum/view.php', array('id' => $cm->id));
  237
+    $discussionurl = new moodle_url('/mod/forum/discuss.php', array('d' => $post->discussion));
  238
+
  239
+    // load ratings
  240
+    if ($forum->assessed != RATING_AGGREGATE_NONE) {
  241
+        $ratingoptions->context = $cm->context;
  242
+        $ratingoptions->items = array($post);
  243
+        $ratingoptions->aggregate = $forum->assessed;//the aggregation method
  244
+        $ratingoptions->scaleid = $forum->scale;
  245
+        $ratingoptions->userid = $user->id;
  246
+        $ratingoptions->assesstimestart = $forum->assesstimestart;
  247
+        $ratingoptions->assesstimefinish = $forum->assesstimefinish;
  248
+        if ($forum->type == 'single' or !$post->discussion) {
  249
+            $ratingoptions->returnurl = $forumurl;
  250
+        } else {
  251
+            $ratingoptions->returnurl = "$CFG->wwwroot/mod/forum/discuss.php?d=$discussion->id";
204 252
         }
  253
+        $ratingoptions->assesstimestart = $forum->assesstimestart;
  254
+        $ratingoptions->assesstimefinish = $forum->assesstimefinish;
205 255
 
206  
-        $post->subject = $fullsubject;
  256
+        $updatedpost = $rm->get_ratings($ratingoptions);
  257
+        //updating the array this way because we're iterating over a collection and updating them one by one
  258
+        $result->posts[$updatedpost[0]->id] = $updatedpost[0];
  259
+    }
207 260
 
208  
-        $fulllink = "<a href=\"discuss.php?d=$post->discussion#p$post->id\">".
209  
-            get_string("postincontext", "forum")."</a>";
  261
+    $courseshortname = format_string($course->shortname, true, array('context' => get_context_instance(CONTEXT_COURSE, $course->id)));
  262
+    $forumname = format_string($forum->name, true, array('context' => $cm->context));
210 263
 
211  
-        forum_print_post($post, $discussion, $forum, $cms[$forum->id], $course, false, false, false, $fulllink);
212  
-        echo "<br />";
  264
+    $fullsubjects = array();
  265
+    if (!$isspecificcourse && !$hasparentaccess) {
  266
+        $fullsubjects[] = html_writer::link(new moodle_url('/course/view.php', array('id' => $course->id)), $courseshortname);
  267
+        $fullsubjects[] = html_writer::link($forumurl, $forumname);
  268
+    } else {
  269
+        $fullsubjects[] = html_writer::tag('span', $courseshortname);
  270
+        $fullsubjects[] = html_writer::tag('span', $forumname);
  271
+    }
  272
+    if ($forum->type != 'single') {
  273
+        $discussionname = format_string($discussion->name, true, array('context' => $cm->context));
  274
+        if (!$isspecificcourse && !$hasparentaccess) {
  275
+            $fullsubjects[] .= html_writer::link($discussionurl, $discussionname);
  276
+        } else {
  277
+            $fullsubjects[] .= html_writer::tag('span', $discussionname);
  278
+        }
  279
+        if ($post->parent != 0) {
  280
+            $postname = format_string($post->subject, true, array('context' => $cm->context));
  281
+            if (!$isspecificcourse && !$hasparentaccess) {
  282
+                $fullsubjects[] .= html_writer::link(new moodle_url('/mod/forum/discuss.php', array('d' => $post->discussion, 'parent' => $post->id)), $postname);
  283
+            } else {
  284
+                $fullsubjects[] .= html_writer::tag('span', $postname);
  285
+            }
  286
+        }
213 287
     }
  288
+    $post->subject = join(' -> ', $fullsubjects);
  289
+    // This is really important, if the strings are formatted again all the links
  290
+    // we've added will be lost.
  291
+    $post->subjectnoformat = true;
  292
+    $discussionurl->set_anchor('p'.$post->id);
  293
+    $fulllink = html_writer::link($discussionurl, get_string("postincontext", "forum"));
  294
+
  295
+    $postoutput[] = forum_print_post($post, $discussion, $forum, $cm, $course, false, false, false, $fulllink, '', null, true, null, true);
  296
+}
  297
+
  298
+$userfullname = fullname($user);
214 299
 
215  
-    echo $OUTPUT->paging_bar($totalcount, $page, $perpage, $baseurl);
  300
+if ($discussionsonly) {
  301
+    $inpageheading = get_string('discussionsstartedby', 'mod_forum', $userfullname);
216 302
 } else {
217  
-    if ($mode == 'posts') {
218  
-        echo $OUTPUT->heading(get_string('noposts', 'forum'));
  303
+    $inpageheading = get_string('postsmadebyuser', 'mod_forum', $userfullname);
  304
+}
  305
+if ($isspecificcourse) {
  306
+    $a = new stdClass;
  307
+    $a->fullname = $userfullname;
  308
+    $a->coursename = format_string($course->shortname, true, array('context' => $coursecontext));
  309
+    $pageheading = $a->coursename;
  310
+    if ($discussionsonly) {
  311
+        $pagetitle = get_string('discussionsstartedbyuserincourse', 'mod_forum', $a);
219 312
     } else {
220  
-        echo $OUTPUT->heading(get_string('nodiscussionsstartedby', 'forum'));
  313
+        $pagetitle = get_string('postsmadebyuserincourse', 'mod_forum', $a);
  314
+    }
  315
+} else {
  316
+    $pagetitle = $inpageheading;
  317
+    $pageheading = $userfullname;
  318
+}
  319
+
  320
+$PAGE->set_title($pagetitle);
  321
+$PAGE->set_heading($pagetitle);
  322
+$PAGE->navigation->extend_for_user($user);
  323
+$PAGE->navigation->set_userid_for_parent_checks($user->id); // see MDL-25805 for reasons and for full commit reference for reversal when fixed.
  324
+
  325
+echo $OUTPUT->header();
  326
+echo $OUTPUT->heading($inpageheading);
  327
+echo html_writer::start_tag('div', array('class' => 'user-content'));
  328
+
  329
+if (!empty($postoutput)) {
  330
+    echo $OUTPUT->paging_bar($result->totalcount, $page, $perpage, $url);
  331
+    foreach ($postoutput as $post) {
  332
+        echo $post;
  333
+        echo html_writer::empty_tag('br');
221 334
     }
  335
+    echo $OUTPUT->paging_bar($result->totalcount, $page, $perpage, $url);
  336
+} else if ($discussionsonly) {
  337
+    echo $OUTPUT->heading(get_string('nodiscussionsstartedby', 'forum', $userfullname));
  338
+} else {
  339
+    echo $OUTPUT->heading(get_string('noposts', 'forum'));
222 340
 }
223  
-echo '</div>';
224  
-echo $OUTPUT->footer();
225 341
 
  342
+echo html_writer::end_tag('div');
  343
+echo $OUTPUT->footer();
6  user/view.php
@@ -58,10 +58,6 @@
58 58
 
59 59
 if (!empty($CFG->forceloginforprofiles)) {
60 60
     require_login(); // we can not log in to course due to the parent hack bellow
61  
-    if (isguestuser()) {
62  
-        $SESSION->wantsurl = $PAGE->url->out(false);
63  
-        redirect(get_login_url());
64  
-    }
65 61
 }
66 62
 
67 63
 $PAGE->set_context($coursecontext);
@@ -96,7 +92,7 @@
96 92
 /// Now test the actual capabilities and enrolment in course
97 93
 if ($currentuser) {
98 94
     // me
99  
-    if (!is_enrolled($coursecontext) and !is_viewing($coursecontext)) { // Need to have full access to a course to see the rest of own info
  95
+    if (!is_viewing($coursecontext) && !is_enrolled($coursecontext)) { // Need to have full access to a course to see the rest of own info
100 96
         echo $OUTPUT->header();
101 97
         echo $OUTPUT->heading(get_string('notenrolled', '', $fullname));
102 98
         if (!empty($_SERVER['HTTP_REFERER'])) {

0 notes on commit 8e6e5ad

Please sign in to comment.
Something went wrong with that request. Please try again.