Stealth mode and nested activities

Jump to: navigation, search

This is a proposal for something that might go into Moodle 2.0.

We have had a version of this feature in our customised OU Moodle for some time (doing available from and unavailable from dates, and a basic version of stealth mode). We are about to enhance how it works (following the design below). We would like to contribute this to Moodle core, but that would need Martin D's approval. As you can see from the requirements section, several other people want this feature.

Please discuss this proposal in this forum thread.


  1. Have an activity that is accessible to students, but not listed on the course front page. The course creator will manually put a link to the activity somewhere else in the course. This is sometimes called 'stealth mode'. (It is different to making an activity not visible, because for security reasons students will be refused access to activities that are not visible, even if they go to the URL.)
  2. Where an activity is not listed on the course page, but is instead only available via a link elsewhere, reflect the path to the stealthed activity in its navigation trail.
  3. Have an activity that does not appear to students until a given date, or which automatically disappears after a given date. This is sometimes called 'available from' and 'unavailable from' dates.


Note, the mock-ups below use the the OU Moodle theme and an OU-specific course-format, but they should be clear to people used to the standard theme too.

How it looks to users

It will still be the case that all activities have to be added to the course front page. So, when you are editing the course, things will look just like they do now:

Stealth mode - course page editing.png

Note, however, that activities that are not visible to 'students' now (assumed to be 3rd October) have red annotation text explaining this. In the previous sentence I say 'students' in inverted commas, because the hiding actually takes effect for users without the moodle:course/viewhiddenactivities capability. So with the example above students will see:

Stealth mode - course page student.png

For teachers and and administrators, when editing is tuned off, all sorts of hidden activities will be displayed in grey, as existing hidden activities are now.

How is this controlled? By some extra fields in the 'Common module settings' section of the activity settings form - the middle three settings below are new:

Stealth mode - common module settings.png

To simply hide an activity from the front page, you must assign it a parent activity. If an activity has no parent, then it will be visible on the course page. If it has a parent, then it will be hidden from the course page. In addition, when you are looking at that activity, then the navigation bar will be modified, to show where the activity fits. For example, in the example above, the resource 'Extra information used by the quiz' will have this navigation bar:

Stealth mode - navbar.png

(Just to reinforce the point, the Quizzes link is there, and the Resources link isn't.)

The Available from and Unavailable from dates do more than just hide the module from the front page. If an available from date is given, then the activity will not be visible, nor will it be accessible, even if you type the URL, before that date (unless you have the view hidden activities capability). On that date, it will appear (unless the standard visibility setting is set to hide, or it is stealthed) and it will be accessible to everyone (unless visibility is hide). If an unavailable from date is given, then it goes back to being unavailable from that date. Note that the editing form will ensure that the available from date is before the unavailable from date, if both are given.

Perhaps the new 'Common module settings' should be hidden behind the show advanced button.

Note that the stealth hiding of activities only applies to the course front page, not the activity index page. For example, in the example above, the Resources index page will look like:

Stealth mode - resource index.png

Because activities are still created on the front page in editing mode, it is clear which section and which order they appear in on the index pages. Similarly, no change will be made to any other place activities are listed (for example custom blocks).

Note that there will be no automatic navigation built from a parent activity to the child activities. As mentioned above, it will be up to the teacher to create these links. This is because the best place for the link depends on the particular activity. For example, for one quiz, you may want the link to appear in the introduction. In another quiz, you might want it to appear in the overall feedback.

If an activity that is a parent of other activities is deleted, then the child activities will not be deleted. Instead the child activities will have their parent set back to none.

Nested parent activities do not affect roles and capabilities. The parent context of each module context will still be the course context, as at present.

For performance (and sanity) reasons, we will probably limit it, in the first instance to three levels of nesting, although it would be possible to change this later.

So, to summarise: On the one hand, stealth mode/parent activities lets you hide activities from the course home page while still having them available to students; and on the other hand available and unavailable dates let you essentially automate changing visibility from hide to show and back to hide.


Database changes

The three new settings will be stored in three new columns in the course_modules table:

Field Type Default Info
availablefrom int(10) NULL a timestamp, if set, the activity is not available until this time
unavailablefrom int(10) NULL a timestamp, if set, the activity is not available after this time
parentcmid int(10) NULL if set, a reference to the id of another row in this table with the same course

When the database changes are done, these three new columns will all initially be set to their default values for all rows.

(Note that the upgrade is more complicated in OU Moodle, where some of this data already exists, sometimes in other places.)

Editing form changes

The only forms affected are the module settings forms. To change them all, we only need to change the standard_coursemodule_elements method of course/moodleform_mod.php.

To ensure the data is saved, we only need to check that the add_course_module function from course/modedit.php does the right thing. I think it already does, providing no existing module editing form uses fields called availablefrom, unavailablefrom or parentcmid.

Course page display

This involves changing print_section from course/lib.php.

For people without the moodle:course/viewhiddenactivities capability, all types of hidden activity will not be printed at all. to not print activities that should not be printed when editing is off, and to print them, but with red notices, when editing is on.

For people with moodle:course/viewhiddenactivities, all types of hidden activity will be printed with class="dimmed". In addition, they will also get a class of hidden, stealthed, notyetavailable or nolongeravailable, so themes can have more control over styling, if they want.

I will duplicate these classes on the <li> tag that surrounds each activity, in addition to having it on the <a> tag as at present. This will make it easier for themes to achieve some effects. (Or should I just move the classes, would that break any existing themes?)

Bar students from activities that are not available by date

This will be done in require_login in lib/moodlelib.php, near the existing has_capability('moodle/course:viewhiddenactivities', $COURSE->context) check.

Navigation bar generation

The change to print_navigation in Moodle 1.9, so it now uses an array of links, partially created by build_navigation, rather than a string, make this a bit easier.

At the moment, the build_navigation function only creates the site and course levels of navigation. The module index and module instance level navigation is still created by lots of duplicated code all over the place. For example in page_generic_activity::print_header in lib/pagelib.php and mod/quiz/attempt.php and ...

I will add an optional $cm parameter to the build_navigation function. If present, build navigation will add the module index and module instance levels of navigation, including all parent activities. I will then need to remove all the duplicated code that currently generates these levels of navigation.

Backup and restore

Include the new fields.


Is this a good idea?

The features proposed here are certainly open to abuse. By misusing them, it will be much easier to make courses that are totally confusing for students.

However, there are valid use-cases where correct use of these features will let people make courses that are better structured.

If people choose to ignore the three new settings on the module forms, then Moodle will continue to function exactly as it does now.

Therefore, on balance, I think these feature should be included in Moodle 2.0. We should include a discussion of appropriate use and abuse of these features in the help, or on Moodle Docs. (Not that anyone will bother to read it.)

Performance implications

I think that the performance impact will be minimal.

Some existing database queries will have to return a little more information (three integers) per row.

When calling build_navigation with a $cm that has a parent, there will need to be one extra small database query to get the information about all ancestors.

Elsewhere in the code, there will just be a few more if-statements.

See also