Moodle
  1. Moodle
  2. MDL-12855

Show hidden courses in user profile overview

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 1.8.3
    • Fix Version/s: 1.8.6
    • Component/s: Administration
    • Labels:
      None
    • Environment:
      MySQL 5.0.45
      PHP 5.2.5
      Linux Webhosting with Apache Server
    • Database:
      MySQL
    • Affected Branches:
      MOODLE_18_STABLE
    • Fixed Branches:
      MOODLE_18_STABLE
    • Rank:
      30775

      Description

      Hello,

      I am using many courses, hidden courses (for structuring of metacourses) and meta-courses.

      It is currently not possible to get an overview (as administrator) of all courses a user is member of. There are only shown visible courses. Hidden courses are left out. At the moment I have to look through all my hidden courses to find a specific user.

      For administration it would be really helpful to see also hidden courses in the user profile overview.

      Regards, Daniel

        Issue Links

          Activity

          Daniel Schimrik created issue -
          Hide
          Yolanda Ordoñez Rufat added a comment -

          We find a solution for this bug.
          In moodle/user/view.php around line 310 (for version 1.8.3) we change the block:
          if ($mycourse->visible and $mycourse->category) {
          if ($mycourse->id != $course->id)

          { $courselisting .= "<a href=\"$CFG->wwwroot/user/view.php?id=$user->id&course=$mycourse->id\">" . format_string($mycourse->fullname) . "</a>, "; }

          else

          { $courselisting .= format_string($mycourse->fullname) . ", "; }

          }

          for this one:
          if ($mycourse->category) {
          if ($mycourse->visible) {
          if ($mycourse->id != $course->id)

          { $courselisting .= "<a href=\"$CFG->wwwroot/user/view.php?id=$user->id&course=$mycourse->id\">" . format_string($mycourse->fullname) . "</a>, "; }

          else

          { $courselisting .= format_string($mycourse->fullname) . ", "; }
          } elseif (has_capability('moodle/course:viewhiddencourses', get_context_instance(CONTEXT_COURSE, $mycourse->id))) {
          if ($mycourse->id != $course->id){ $courselisting .= "<a class='dimmed' href=\"$CFG->wwwroot/user/view.php?id=$user->id&course=$mycourse->id\">" . format_string($mycourse->fullname) . "</a>, "; }
          else { $courselisting .= format_string($mycourse->fullname) . ", "; }

          }
          }

          So if you get into a user profile you will see all the courses that user has access to view even if they're hidden. Notice that you need the capability to see that hidden course too (granted if you are admin or another teacher from that hidden course).

          We test the solution on a 1.7.2 moodle and a 1.8.3 moodle, both with a 8.2.4 postgres installed in a SUSE Linux Enterprise Server 10 SP1;

          Show
          Yolanda Ordoñez Rufat added a comment - We find a solution for this bug. In moodle/user/view.php around line 310 (for version 1.8.3) we change the block: if ($mycourse->visible and $mycourse->category) { if ($mycourse->id != $course->id) { $courselisting .= "<a href=\"$CFG->wwwroot/user/view.php?id=$user->id&course=$mycourse->id\">" . format_string($mycourse->fullname) . "</a>, "; } else { $courselisting .= format_string($mycourse->fullname) . ", "; } } for this one: if ($mycourse->category) { if ($mycourse->visible) { if ($mycourse->id != $course->id) { $courselisting .= "<a href=\"$CFG->wwwroot/user/view.php?id=$user->id&course=$mycourse->id\">" . format_string($mycourse->fullname) . "</a>, "; } else { $courselisting .= format_string($mycourse->fullname) . ", "; } } elseif (has_capability('moodle/course:viewhiddencourses', get_context_instance(CONTEXT_COURSE, $mycourse->id))) { if ($mycourse->id != $course->id){ $courselisting .= "<a class='dimmed' href=\"$CFG->wwwroot/user/view.php?id=$user->id&course=$mycourse->id\">" . format_string($mycourse->fullname) . "</a>, "; } else { $courselisting .= format_string($mycourse->fullname) . ", "; } } } So if you get into a user profile you will see all the courses that user has access to view even if they're hidden. Notice that you need the capability to see that hidden course too (granted if you are admin or another teacher from that hidden course). We test the solution on a 1.7.2 moodle and a 1.8.3 moodle, both with a 8.2.4 postgres installed in a SUSE Linux Enterprise Server 10 SP1;
          Hide
          Daniel Schimrik added a comment -

          Hello,

          I just tested your solution, but it is not working as I expected.

          Take me as administrator: I am not a member of any course (except front page), I do have the capability to view hidden courses. But after applying your patch, I cannot see hidden courses from other users. Hidden courses are not listed in their profiles.

          If I am a teacher, all my hidden courses are listed in my profile with your patch.

          Maybe its my current Moodle 1.8.4+ that is doing something weird here.

          Regards, Daniel

          Show
          Daniel Schimrik added a comment - Hello, I just tested your solution, but it is not working as I expected. Take me as administrator: I am not a member of any course (except front page), I do have the capability to view hidden courses. But after applying your patch, I cannot see hidden courses from other users. Hidden courses are not listed in their profiles. If I am a teacher, all my hidden courses are listed in my profile with your patch. Maybe its my current Moodle 1.8.4+ that is doing something weird here. Regards, Daniel
          Hide
          Yolanda Ordoñez Rufat added a comment -

          I get the Latest Stable Build v. 1.8.4+ (2007021541) and installed on my local machine (windows XP and postgres 8.2) and the patch works fine for me.

          Show
          Yolanda Ordoñez Rufat added a comment - I get the Latest Stable Build v. 1.8.4+ (2007021541) and installed on my local machine (windows XP and postgres 8.2) and the patch works fine for me.
          Hide
          Patrick Pollet added a comment -

          The code in 1.9, seems corrected ; it should be backported to 1.7, 1.8 , including the "filtering off" in lib/datalib.php#get_my_courses (which is NOT done in 1.7/1.8) .

          see moodle19/user/view.php near line 325

          if ($mycourses = get_my_courses($user->id, null, null, false, 21)) {
          $shown=0;
          $courselisting = '';
          foreach ($mycourses as $mycourse) {
          if ($mycourse->category) {
          if ($mycourse->id != $course->id){
          $class = '';
          if ($mycourse->visible == 0)

          { // get_my_courses will filter courses $USER cannot see // if we get one with visible 0 it just means it's hidden // ... but not from $USER $class = 'class="dimmed"'; }

          $courselisting .= "<a href=\"{$CFG->wwwroot}/user/view.php?id={$user->id}&course={$mycourse->id}\" $class >"
          . format_string($mycourse->fullname) . "</a>, ";
          }
          else

          { $courselisting .= format_string($mycourse->fullname) . ", "; }

          }
          $shown++;
          if($shown==20)

          { $courselisting.= "..."; break; }

          }
          print_row(get_string('courses').':', rtrim($courselisting,', '));
          }

          Show
          Patrick Pollet added a comment - The code in 1.9, seems corrected ; it should be backported to 1.7, 1.8 , including the "filtering off" in lib/datalib.php#get_my_courses (which is NOT done in 1.7/1.8) . see moodle19/user/view.php near line 325 if ($mycourses = get_my_courses($user->id, null, null, false, 21)) { $shown=0; $courselisting = ''; foreach ($mycourses as $mycourse) { if ($mycourse->category) { if ($mycourse->id != $course->id){ $class = ''; if ($mycourse->visible == 0) { // get_my_courses will filter courses $USER cannot see // if we get one with visible 0 it just means it's hidden // ... but not from $USER $class = 'class="dimmed"'; } $courselisting .= "<a href=\"{$CFG->wwwroot}/user/view.php?id={$user->id}&course={$mycourse->id}\" $class >" . format_string($mycourse->fullname) . "</a>, "; } else { $courselisting .= format_string($mycourse->fullname) . ", "; } } $shown++; if($shown==20) { $courselisting.= "..."; break; } } print_row(get_string('courses').':', rtrim($courselisting,', ')); }
          Hide
          Eloy Lafuente (stronk7) added a comment -

          Hi, nice to see this has been fixed for 1.9.

          +1 to backport the code in moodle19/user/view.php to 1.8. That way, invisible courses will be showed (instead of current behaviour, being skipped) to users having 'moodle/course:viewhiddencourses' (that is correct IMO).

          -1 to backport the get_my_courses() function, because it relays in a lot of artefacts only available under Moodle 1.9 to do the whole filtering. We should keep the current version, that isn't 100% perfect but does some (slower) filtering.

          Ciao

          Show
          Eloy Lafuente (stronk7) added a comment - Hi, nice to see this has been fixed for 1.9. +1 to backport the code in moodle19/user/view.php to 1.8. That way, invisible courses will be showed (instead of current behaviour, being skipped) to users having 'moodle/course:viewhiddencourses' (that is correct IMO). -1 to backport the get_my_courses() function, because it relays in a lot of artefacts only available under Moodle 1.9 to do the whole filtering. We should keep the current version, that isn't 100% perfect but does some (slower) filtering. Ciao
          Hide
          Patrick Pollet added a comment -

          Yes but if we do not do some filtering in get_my_courses, any user can see the "title" of courses that are invisible to him by looking at another user's profile (such as an admin) . Of course he won't be able to register to these courses if he clicks on the link, but he does see title dimmed and Moodle internal number. Something he may use to try to break in ...

          So what I did on my 1.7 ( code seems the same in 1.8) :

          • applied the above patch to user/view.php

          -added an extra testing in the main loop of get_my_courses in lib/datalib.php to check that current user (as per global $USER) can see that course before adding it to the returned list ( three lines marked with PP below) :

          if ($rs && $rs->RecordCount() > 0) {
          while ($course = rs_fetch_next_record($rs)) {
          if ($course->id != SITEID) {
          // users with moodle/course:view are considered course participants
          // the course needs to be visible, or user must have moodle/course:viewhiddencourses
          // capability set to view hidden courses
          $context = get_context_instance(CONTEXT_COURSE, $course->id);
          if ( has_capability('moodle/course:view', $context, $userid, $doanything) &&
          !has_capability('moodle/legacy:guest', $context, $userid, false) &&
          ($course->visible || has_capability('moodle/course:viewhiddencourses', $context, $userid))) {
          //DO NOT SENT IT BACK IF CURRENT USER CANNOT SEE IT (i.e. is looking to someone else profile) //PP
          if ( $course->visible || has_capability('moodle/course:view', $context, $USER->id, $true)) { //PP
          $mycourses[$course->id] = $course;
          // Only return a limited number of courses if limit is set
          if($limit>0) {
          $limit--;
          if($limit==0)

          { break; }

          }
          } //PP
          }
          }
          }
          }

          It may be not efficient, but at least it works quite nicely here with a reasoanble amount of course (~200) and users (7500).

          At least admin can see all "hidden courses" for any user and any user can see its OWN hidden courses , when looking at his profile
          or to the profile of another user.

          Cheers.

          Show
          Patrick Pollet added a comment - Yes but if we do not do some filtering in get_my_courses, any user can see the "title" of courses that are invisible to him by looking at another user's profile (such as an admin) . Of course he won't be able to register to these courses if he clicks on the link, but he does see title dimmed and Moodle internal number. Something he may use to try to break in ... So what I did on my 1.7 ( code seems the same in 1.8) : applied the above patch to user/view.php -added an extra testing in the main loop of get_my_courses in lib/datalib.php to check that current user (as per global $USER) can see that course before adding it to the returned list ( three lines marked with PP below) : if ($rs && $rs->RecordCount() > 0) { while ($course = rs_fetch_next_record($rs)) { if ($course->id != SITEID) { // users with moodle/course:view are considered course participants // the course needs to be visible, or user must have moodle/course:viewhiddencourses // capability set to view hidden courses $context = get_context_instance(CONTEXT_COURSE, $course->id); if ( has_capability('moodle/course:view', $context, $userid, $doanything) && !has_capability('moodle/legacy:guest', $context, $userid, false) && ($course->visible || has_capability('moodle/course:viewhiddencourses', $context, $userid))) { //DO NOT SENT IT BACK IF CURRENT USER CANNOT SEE IT (i.e. is looking to someone else profile) //PP if ( $course->visible || has_capability('moodle/course:view', $context, $USER->id, $true)) { //PP $mycourses [$course->id] = $course; // Only return a limited number of courses if limit is set if($limit>0) { $limit--; if($limit==0) { break; } } } //PP } } } } It may be not efficient, but at least it works quite nicely here with a reasoanble amount of course (~200) and users (7500). At least admin can see all "hidden courses" for any user and any user can see its OWN hidden courses , when looking at his profile or to the profile of another user. Cheers.
          Hide
          Eloy Lafuente (stronk7) added a comment - - edited

          Ah Patrick!

          I read wrongly that part of code in 1.8 get_my_courses() !

          Wouldn't be this enough?

          if ( has_capability('moodle/course:view', $context, $userid, $doanything) &&
          !has_capability('moodle/legacy:guest', $context, $userid, false) &&
          ($course->visible || has_capability('moodle/course:viewhiddencourses', $context, $USER->id))) {

          i.e. I really think that the latest has_capability() is buggy. It's not a matter if $userid has de 'viewhiddencourses' capablity but to check if the $USER->id (the one viewing the courses) has it. In fact, that is what I imagine we were doing!

          Can anybody find any problem about that change? IMO it's a bug, isn't it?

          Ciao

          Show
          Eloy Lafuente (stronk7) added a comment - - edited Ah Patrick! I read wrongly that part of code in 1.8 get_my_courses() ! Wouldn't be this enough? if ( has_capability('moodle/course:view', $context, $userid, $doanything) && !has_capability('moodle/legacy:guest', $context, $userid, false) && ($course->visible || has_capability('moodle/course:viewhiddencourses', $context, $USER->id))) { i.e. I really think that the latest has_capability() is buggy. It's not a matter if $userid has de 'viewhiddencourses' capablity but to check if the $USER->id (the one viewing the courses) has it. In fact, that is what I imagine we were doing! Can anybody find any problem about that change? IMO it's a bug, isn't it? Ciao
          Hide
          Martin Dougiamas added a comment -

          Makes sense to check USER for the last one, for sure

          Show
          Martin Dougiamas added a comment - Makes sense to check USER for the last one, for sure
          Hide
          Eloy Lafuente (stronk7) added a comment -

          Fixed. Now, under 1.8, the list of courses is being filtered out depending of the user that request it (not based in the user we are calculating the list).

          Not needed to merge to 1.9 nor HEAD. It's fixed differently there.

          Ciao

          Show
          Eloy Lafuente (stronk7) added a comment - Fixed. Now, under 1.8, the list of courses is being filtered out depending of the user that request it (not based in the user we are calculating the list). Not needed to merge to 1.9 nor HEAD. It's fixed differently there. Ciao
          Eloy Lafuente (stronk7) made changes -
          Field Original Value New Value
          Status Open [ 1 ] Resolved [ 5 ]
          Fix Version/s 1.8.6 [ 10270 ]
          Resolution Fixed [ 1 ]
          Assignee Martin Dougiamas [ dougiamas ] Eloy Lafuente (stronk7) [ stronk7 ]
          Eloy Lafuente (stronk7) made changes -
          Affects Version/s 1.9 [ 10190 ]
          Eloy Lafuente (stronk7) made changes -
          Link This issue has been marked as being related by MDL-14282 [ MDL-14282 ]
          Hide
          Patrick Pollet added a comment -

          Ah Eloy

          lib/datalib.php do filter out courses non visible to current user but user/view.php do not display them ...
          You forgot the patch given above by Yolanda to display them in dimmed class .

          Cheers.

          Show
          Patrick Pollet added a comment - Ah Eloy lib/datalib.php do filter out courses non visible to current user but user/view.php do not display them ... You forgot the patch given above by Yolanda to display them in dimmed class . Cheers.
          Hide
          Eloy Lafuente (stronk7) added a comment -

          Ah, thanks Patrick!

          I got lost in the discussion, I'll back portcode from 1.9 user/view.php to 1.8 in order to allow users with "viewhiddencourses" to see them dimmed.Reopening....

          Thanks for pinging me! Ciao

          Show
          Eloy Lafuente (stronk7) added a comment - Ah, thanks Patrick! I got lost in the discussion, I'll back portcode from 1.9 user/view.php to 1.8 in order to allow users with "viewhiddencourses" to see them dimmed.Reopening.... Thanks for pinging me! Ciao
          Eloy Lafuente (stronk7) made changes -
          Resolution Fixed [ 1 ]
          Status Resolved [ 5 ] Reopened [ 4 ]
          Hide
          Eloy Lafuente (stronk7) added a comment -

          Sent to 18_STABLE. Now not-visible courses are shown properly dimmed once get_my_courses() have returned them.

          Resolving... thanks everybody! Ciao

          Show
          Eloy Lafuente (stronk7) added a comment - Sent to 18_STABLE. Now not-visible courses are shown properly dimmed once get_my_courses() have returned them. Resolving... thanks everybody! Ciao
          Eloy Lafuente (stronk7) made changes -
          Status Reopened [ 4 ] Resolved [ 5 ]
          Resolution Fixed [ 1 ]
          Martin Dougiamas made changes -
          Status Resolved [ 5 ] Closed [ 6 ]
          Martin Dougiamas made changes -
          Workflow jira [ 24193 ] MDL Workflow [ 58375 ]
          Martin Dougiamas made changes -
          Workflow MDL Workflow [ 58375 ] MDL Full Workflow [ 87519 ]

            People

            • Votes:
              0 Vote for this issue
              Watchers:
              4 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: