Merge branch 'test-48374' of git://github.com/rajeshtaneja/moodle
authorEloy Lafuente (stronk7) <stronk7@moodle.org>
Wed, 3 Dec 2014 01:57:24 +0000 (02:57 +0100)
committerDan Poltawski <dan@moodle.com>
Thu, 4 Dec 2014 12:14:30 +0000 (12:14 +0000)
50 files changed:
admin/settings/appearance.php
blocks/navigation/tests/behat/expand_courses_node.feature
blocks/site_main_menu/block_site_main_menu.php
blocks/site_main_menu/styles.css
cache/forms.php
cache/renderer.php
calendar/externallib.php
calendar/upgrade.txt
course/classes/management/helper.php
course/edit.php
course/edit_form.php
course/format/lib.php
course/format/topics/lib.php
course/format/weeks/lib.php
course/tests/behat/activities_group_icons.feature
course/tests/behat/behat_course.php
course/tests/behat/course_creation.feature
course/tests/behat/create_delete_course.feature
course/tests/behat/edit_settings.feature
course/tests/behat/force_group_mode.feature
course/tests/behat/move_activities.feature
course/tests/behat/move_sections.feature
course/tests/behat/rename_roles.feature
lang/en/admin.php
lang/en/cache.php
lang/en/deprecated.txt
lang/en/moodle.php
mod/feedback/backup/moodle1/lib.php
mod/imscp/backup/moodle1/lib.php
mod/imscp/backup/moodle2/backup_imscp_activity_task.class.php
mod/imscp/backup/moodle2/backup_imscp_stepslib.php
mod/imscp/backup/moodle2/restore_imscp_activity_task.class.php
mod/imscp/backup/moodle2/restore_imscp_stepslib.php
mod/imscp/db/install.php
mod/imscp/db/log.php
mod/imscp/db/upgrade.php
mod/imscp/index.php
mod/imscp/lang/en/imscp.php
mod/imscp/lib.php
mod/imscp/locallib.php
mod/imscp/mod_form.php
mod/imscp/module.js
mod/imscp/settings.php
mod/imscp/styles.css
mod/imscp/tests/generator_test.php
mod/imscp/version.php
mod/imscp/view.php
question/format/gift/tests/behat/import_export.feature
question/format/xml/tests/behat/import_export.feature
version.php

index b904da2..062df28 100644 (file)
@@ -144,6 +144,7 @@ mybadges,badges|/badges/mybadges.php|award',
     $temp->add(new admin_setting_configtext('navcourselimit',new lang_string('navcourselimit','admin'),new lang_string('confignavcourselimit', 'admin'),20,PARAM_INT));
     $temp->add(new admin_setting_configcheckbox('usesitenameforsitepages', new lang_string('usesitenameforsitepages', 'admin'), new lang_string('configusesitenameforsitepages', 'admin'), 0));
     $temp->add(new admin_setting_configcheckbox('linkadmincategories', new lang_string('linkadmincategories', 'admin'), new lang_string('linkadmincategories_help', 'admin'), 0));
+    $temp->add(new admin_setting_configcheckbox('linkcoursesections', new lang_string('linkcoursesections', 'admin'), new lang_string('linkcoursesections_help', 'admin'), 0));
     $temp->add(new admin_setting_configcheckbox('navshowfrontpagemods', new lang_string('navshowfrontpagemods', 'admin'), new lang_string('navshowfrontpagemods_help', 'admin'), 1));
     $temp->add(new admin_setting_configcheckbox('navadduserpostslinks', new lang_string('navadduserpostslinks', 'admin'), new lang_string('navadduserpostslinks_help', 'admin'), 1));
 
index 2fd28ca..9ebf78e 100644 (file)
@@ -40,7 +40,7 @@ Feature: Expand the courses nodes within the navigation block
     And I click on "Edit settings" "link" in the "Administration" "block"
     And I set the following fields to these values:
       | Allow guest access | Yes |
-    And I press "Save changes"
+    And I press "Save and return"
     And I set the following administration settings values:
       | Show all courses | 1 |
     And I log out
index a84e3d1..e28c75b 100644 (file)
@@ -56,26 +56,36 @@ class block_site_main_menu extends block_list {
         if (!$isediting) {
             $modinfo = get_fast_modinfo($course);
             if (!empty($modinfo->sections[0])) {
-                $options = array('overflowdiv'=>true);
                 foreach($modinfo->sections[0] as $cmid) {
                     $cm = $modinfo->cms[$cmid];
                     if (!$cm->uservisible) {
                         continue;
                     }
 
-                    $content = $cm->get_formatted_content(array('overflowdiv' => true, 'noclean' => true));
-                    $instancename = $cm->get_formatted_name();
-
-                    if (!($url = $cm->url)) {
-                        $this->content->items[] = $content;
-                        $this->content->icons[] = '';
+                    if ($cm->indent > 0) {
+                        $indent = '<div class="mod-indent mod-indent-'.$cm->indent.'"></div>';
                     } else {
-                        $linkcss = $cm->visible ? '' : ' class="dimmed" ';
-                        //Accessibility: incidental image - should be empty Alt text
+                        $indent = '';
+                    }
+
+                    if (!empty($cm->url)) {
+                        $attrs = array();
+                        $attrs['title'] = $cm->modfullname;
+                        $attrs['class'] = $cm->extraclasses . ' activity-action';
+                        if ($cm->onclick) {
+                            $attrs['id'] = html_writer::random_id('onclick');
+                            $OUTPUT->add_action_handler(new component_action('click', $cm->onclick), $attrs['id']);
+                        }
+                        if (!$cm->visible) {
+                            $attrs['class'] .= ' dimmed';
+                        }
                         $icon = '<img src="' . $cm->get_icon_url() . '" class="icon" alt="" />';
-                        $this->content->items[] = '<a title="'.$cm->modplural.'" '.$linkcss.' '.$cm->extra.
-                                ' href="' . $url . '">' . $icon . $instancename . '</a>';
+                        $content = html_writer::link($cm->url, $icon . $cm->get_formatted_name(), $attrs);
+                    } else {
+                        $content = $cm->get_formatted_content(array('overflowdiv' => true, 'noclean' => true));
                     }
+
+                    $this->content->items[] = $indent.html_writer::div($content, 'main-menu-content');
                 }
             }
             return $this->content;
@@ -112,7 +122,7 @@ class block_site_main_menu extends block_list {
                     continue;
                 }
                 if (!$ismoving) {
-                    $actions = course_get_cm_edit_actions($mod, -1);
+                    $actions = course_get_cm_edit_actions($mod, $mod->indent);
 
                     // Prepend list of actions with the 'move' action.
                     $actions = array('move' => new action_menu_link_primary(
@@ -137,19 +147,31 @@ class block_site_main_menu extends block_list {
                             '<img style="height:16px; width:80px; border:0px" src="'.$OUTPUT->pix_url('movehere') . '" alt="'.$strmovehere.'" /></a>';
                         $this->content->icons[] = '';
                     }
-                    $content = $mod->get_formatted_content(array('overflowdiv' => true, 'noclean' => true));
-                    $instancename = $mod->get_formatted_name();
-                    $linkcss = $mod->visible ? '' : ' class="dimmed" ';
-
-                    if (!($url = $mod->url)) {
-                        $this->content->items[] = $content . $editbuttons;
-                        $this->content->icons[] = '';
+                    if ($mod->indent > 0) {
+                        $indent = '<div class="mod-indent mod-indent-'.$mod->indent.'"></div>';
+                    } else {
+                        $indent = '';
+                    }
+                    $url = $mod->url;
+                    if (!$url) {
+                        $content = $mod->get_formatted_content(array('overflowdiv' => true, 'noclean' => true));
                     } else {
                         //Accessibility: incidental image - should be empty Alt text
+                        $attrs = array();
+                        $attrs['title'] = $mod->modfullname;
+                        $attrs['class'] = $mod->extraclasses . ' activity-action';
+                        if ($mod->onclick) {
+                            $attrs['id'] = html_writer::random_id('onclick');
+                            $OUTPUT->add_action_handler(new component_action('click', $mod->onclick), $attrs['id']);
+                        }
+                        if (!$mod->visible) {
+                            $attrs['class'] .= ' dimmed';
+                        }
+
                         $icon = '<img src="' . $mod->get_icon_url() . '" class="icon" alt="" />';
-                        $this->content->items[] = '<a title="' . $mod->modfullname . '" ' . $linkcss . ' ' . $mod->extra .
-                            ' href="' . $url . '">' . $icon . $instancename . '</a>' . $editbuttons;
+                        $content = html_writer::link($url, $icon . $mod->get_formatted_name(), $attrs);
                     }
+                    $this->content->items[] = $indent.html_writer::div($content . $editbuttons, 'main-menu-content');
                 }
             }
         }
index dd8f92f..0e15ab7 100644 (file)
@@ -5,3 +5,6 @@
 .block_site_main_menu li .buttons a img{ vertical-align: text-bottom;}
 .block_site_main_menu .footer { margin-top: 1em; }
 .block_site_main_menu .section_add_menus noscript div { display: inline;}
+.block_site_main_menu .mod-indent,
+.block_site_main_menu .main-menu-content { display: table-cell; }
+.block_site_main_menu .main-menu-content > .activity-action { display: block; }
index 2abfabc..5a2ef3b 100644 (file)
@@ -65,13 +65,13 @@ class cachestore_addinstance_form extends moodleform {
         }
 
         if (is_array($locks)) {
-            $form->addElement('select', 'lock', get_string('lockmethod', 'cache'), $locks);
-            $form->addHelpButton('lock', 'lockmethod', 'cache');
+            $form->addElement('select', 'lock', get_string('locking', 'cache'), $locks);
+            $form->addHelpButton('lock', 'locking', 'cache');
             $form->setType('lock', PARAM_ALPHANUMEXT);
         } else {
             $form->addElement('hidden', 'lock', '');
             $form->setType('lock', PARAM_ALPHANUMEXT);
-            $form->addElement('static', 'lock-value', get_string('lockmethod', 'cache'),
+            $form->addElement('static', 'lock-value', get_string('locking', 'cache'),
                     '<em>'.get_string('nativelocking', 'cache').'</em>');
         }
 
index 1ccb4bb..f6ceb1d 100644 (file)
@@ -53,7 +53,7 @@ class core_cache_renderer extends plugin_renderer_base {
             get_string('mappings', 'cache'),
             get_string('modes', 'cache'),
             get_string('supports', 'cache'),
-            get_string('lockingmeans', 'cache'),
+            get_string('locking', 'cache') . ' ' . $this->output->help_icon('locking', 'cache'),
             get_string('actions', 'cache'),
         );
         $table->colclasses = array(
index ac5917e..902693d 100644 (file)
@@ -142,8 +142,8 @@ class core_calendar_external extends external_api {
                                              "Time from which events should be returned",
                                              VALUE_DEFAULT, 0, NULL_ALLOWED),
                                     'timeend' => new external_value(PARAM_INT,
-                                             "Time to which the events should be returned",
-                                             VALUE_DEFAULT, time(), NULL_ALLOWED),
+                                             "Time to which the events should be returned. We treat 0 and null as no end",
+                                             VALUE_DEFAULT, 0, NULL_ALLOWED),
                                     'ignorehidden' => new external_value(PARAM_BOOL,
                                              "Ignore hidden events or not",
                                              VALUE_DEFAULT, true, NULL_ALLOWED),
@@ -215,6 +215,11 @@ class core_calendar_external extends external_api {
             $funcparam['courses'][] = $SITE->id;
         }
 
+        // We treat 0 and null as no end.
+        if (empty($params['options']['timeend'])) {
+            $params['options']['timeend'] = PHP_INT_MAX;
+        }
+
         $eventlist = calendar_get_events($params['options']['timestart'], $params['options']['timeend'], $funcparam['users'], $funcparam['groups'],
                 $funcparam['courses'], true, $params['options']['ignorehidden']);
         // WS expects arrays.
index 72a666a..a5d31af 100644 (file)
@@ -1,6 +1,11 @@
 This files describes API changes in /calendar/* ,
 information provided here is intended especially for developers.
 
+=== 2.9 ===
+default values changes in code:
+* core_calendar_external::get_calendar_events_parameters() 'timeend' default option changed; now, by default,
+  all events are returned, not only the past ones.
+
 === 2.5 ===
 required changes in code:
 * calendar_add_icalendar_event() now requires a valid subscriptionid
index f13757b..b553923 100644 (file)
@@ -315,7 +315,7 @@ class helper {
         // Edit.
         if ($course->can_edit()) {
             $actions[] = array(
-                'url' => new \moodle_url('/course/edit.php', array('id' => $course->id)),
+                'url' => new \moodle_url('/course/edit.php', array('id' => $course->id, 'returnto' => 'catmanage')),
                 'icon' => new \pix_icon('t/edit', \get_string('edit')),
                 'attributes' => array('class' => 'action-edit')
             );
index f21ca88..2b4c30d 100644 (file)
@@ -29,6 +29,38 @@ require_once('edit_form.php');
 $id = optional_param('id', 0, PARAM_INT); // Course id.
 $categoryid = optional_param('category', 0, PARAM_INT); // Course category - can be changed in edit form.
 $returnto = optional_param('returnto', 0, PARAM_ALPHANUM); // Generic navigation return page switch.
+$returnurl = optional_param('returnurl', '', PARAM_LOCALURL); // A return URL. returnto must also be set to 'url'.
+
+if ($returnto === 'url' && confirm_sesskey() && $returnurl) {
+    // If returnto is 'url' then $returnurl may be used as the destination to return to after saving or cancelling.
+    // Sesskey must be specified, and would be set by the form anyway.
+    $returnurl = new moodle_url($returnurl);
+} else {
+    switch ($returnto) {
+        case 'category':
+            $returnurl = new moodle_url($CFG->wwwroot.'/course/index.php', array('categoryid' => $categoryid));
+            break;
+        case 'catmanage':
+            $returnurl = new moodle_url($CFG->wwwroot.'/course/management.php', array('categoryid' => $categoryid));
+            break;
+        case 'topcatmanage':
+            $returnurl = new moodle_url($CFG->wwwroot.'/course/management.php');
+            break;
+        case 'topcat':
+            $returnurl = new moodle_url($CFG->wwwroot.'/course/');
+            break;
+        case 'url':
+            // You may be wondering about this, but the url case should be dealt with above.
+            // If we get here than either sesskey was not given or returnurl was not provided.
+        default:
+            if (!empty($course->id)) {
+                $returnurl = new moodle_url($CFG->wwwroot.'/course/view.php', array('id' => $course->id));
+            } else {
+                $returnurl = new moodle_url($CFG->wwwroot.'/course/');
+            }
+            break;
+    }
+}
 
 $PAGE->set_pagelayout('admin');
 if ($id) {
@@ -36,6 +68,12 @@ if ($id) {
 } else {
     $pageparams = array('category' => $categoryid);
 }
+if ($returnto !== 0) {
+    $pageparams['returnto'] = $returnto;
+    if ($returnto === 'url' && $returnurl) {
+        $pageparams['returnurl'] = $returnurl;
+    }
+}
 $PAGE->set_url('/course/edit.php', $pageparams);
 
 // Basic access control checks.
@@ -98,31 +136,17 @@ if (!empty($course)) {
 }
 
 // First create the form.
-$editform = new course_edit_form(NULL, array('course'=>$course, 'category'=>$category, 'editoroptions'=>$editoroptions, 'returnto'=>$returnto));
+$args = array(
+    'course' => $course,
+    'category' => $category,
+    'editoroptions' => $editoroptions,
+    'returnto' => $returnto,
+    'returnurl' => $returnurl
+);
+$editform = new course_edit_form(null, $args);
 if ($editform->is_cancelled()) {
-        switch ($returnto) {
-            case 'category':
-                $url = new moodle_url($CFG->wwwroot.'/course/index.php', array('categoryid' => $categoryid));
-                break;
-            case 'catmanage':
-                $url = new moodle_url($CFG->wwwroot.'/course/management.php', array('categoryid' => $categoryid));
-                break;
-            case 'topcatmanage':
-                $url = new moodle_url($CFG->wwwroot.'/course/management.php');
-                break;
-            case 'topcat':
-                $url = new moodle_url($CFG->wwwroot.'/course/');
-                break;
-            default:
-                if (!empty($course->id)) {
-                    $url = new moodle_url($CFG->wwwroot.'/course/view.php', array('id'=>$course->id));
-                } else {
-                    $url = new moodle_url($CFG->wwwroot.'/course/');
-                }
-                break;
-        }
-        redirect($url);
-
+    // The form has been cancelled, take them back to what ever the return to is.
+    redirect($returnurl);
 } else if ($data = $editform->get_data()) {
     // Process data if submitted.
     if (empty($course->id)) {
@@ -136,14 +160,20 @@ if ($editform->is_cancelled()) {
             // Deal with course creators - enrol them internally with default role.
             enrol_try_internal_enrol($course->id, $USER->id, $CFG->creatornewroleid);
         }
-        if (!is_enrolled($context)) {
+
+        // The URL to take them to if they chose save and display.
+        $courseurl = new moodle_url('/course/view.php', array('id' => $course->id));
+
+        // If they choose to save and display, and they are not enrolled take them to the enrolments page instead.
+        if (!is_enrolled($context) && isset($data->saveanddisplay)) {
             // Redirect to manual enrolment page if possible.
             $instances = enrol_get_instances($course->id, true);
             foreach($instances as $instance) {
                 if ($plugin = enrol_get_plugin($instance->enrol)) {
                     if ($plugin->get_manual_enrol_link($instance)) {
                         // We know that the ajax enrol UI will have an option to enrol.
-                        redirect(new moodle_url('/enrol/users.php', array('id'=>$course->id)));
+                        $courseurl = new moodle_url('/enrol/users.php', array('id' => $course->id));
+                        break;
                     }
                 }
             }
@@ -151,10 +181,17 @@ if ($editform->is_cancelled()) {
     } else {
         // Save any changes to the files used in the editor.
         update_course($data, $editoroptions);
+        // Set the URL to take them too if they choose save and display.
+        $courseurl = new moodle_url('/course/view.php', array('id' => $course->id));
     }
 
-    // Redirect user to newly created/updated course.
-    redirect(new moodle_url('/course/view.php', array('id' => $course->id)));
+    if (isset($data->saveanddisplay)) {
+        // Redirect user to newly created/updated course.
+        redirect($courseurl);
+    } else {
+        // Save and return. Take them back to wherever.
+        redirect($returnurl);
+    }
 }
 
 // Print the form.
index 1de01c9..54359aa 100644 (file)
@@ -27,6 +27,7 @@ class course_edit_form extends moodleform {
         $category      = $this->_customdata['category'];
         $editoroptions = $this->_customdata['editoroptions'];
         $returnto = $this->_customdata['returnto'];
+        $returnurl = $this->_customdata['returnurl'];
 
         $systemcontext   = context_system::instance();
         $categorycontext = context_coursecat::instance($category->id);
@@ -51,6 +52,10 @@ class course_edit_form extends moodleform {
         $mform->setType('returnto', PARAM_ALPHANUM);
         $mform->setConstant('returnto', $returnto);
 
+        $mform->addElement('hidden', 'returnurl', null);
+        $mform->setType('returnurl', PARAM_LOCALURL);
+        $mform->setConstant('returnurl', $returnurl);
+
         $mform->addElement('text','fullname', get_string('fullnamecourse'),'maxlength="254" size="50"');
         $mform->addHelpButton('fullname', 'fullnamecourse');
         $mform->addRule('fullname', get_string('missingfullname'), 'required', null, 'client');
@@ -296,7 +301,15 @@ class course_edit_form extends moodleform {
             }
         }
 
-        $this->add_action_buttons();
+        // When two elements we need a group.
+        $buttonarray = array();
+        if ($returnto !== 0) {
+            $buttonarray[] = &$mform->createElement('submit', 'saveandreturn', get_string('savechangesandreturn'));
+        }
+        $buttonarray[] = &$mform->createElement('submit', 'saveanddisplay', get_string('savechangesanddisplay'));
+        $buttonarray[] = &$mform->createElement('cancel');
+        $mform->addGroup($buttonarray, 'buttonar', '', array(' '), false);
+        $mform->closeHeaderBefore('buttonar');
 
         $mform->addElement('hidden', 'id', null);
         $mform->setType('id', PARAM_INT);
index 33b9f55..eaeaff7 100644 (file)
@@ -395,6 +395,7 @@ abstract class format_base {
      * @return null|moodle_url
      */
     public function get_view_url($section, $options = array()) {
+        global $CFG;
         $course = $this->get_course();
         $url = new moodle_url('/course/view.php', array('id' => $course->id));
 
@@ -405,7 +406,7 @@ abstract class format_base {
         } else {
             $sectionno = $section;
         }
-        if (!empty($options['navigation']) && $sectionno !== null) {
+        if (empty($CFG->linkcoursesections) && !empty($options['navigation']) && $sectionno !== null) {
             // by default assume that sections are never displayed on separate pages
             return null;
         }
index f7e91bb..cb0a7ed 100644 (file)
@@ -75,6 +75,7 @@ class format_topics extends format_base {
      * @return null|moodle_url
      */
     public function get_view_url($section, $options = array()) {
+        global $CFG;
         $course = $this->get_course();
         $url = new moodle_url('/course/view.php', array('id' => $course->id));
 
@@ -101,7 +102,7 @@ class format_topics extends format_base {
             if ($sectionno != 0 && $usercoursedisplay == COURSE_DISPLAY_MULTIPAGE) {
                 $url->param('section', $sectionno);
             } else {
-                if (!empty($options['navigation'])) {
+                if (empty($CFG->linkcoursesections) && !empty($options['navigation'])) {
                     return null;
                 }
                 $url->set_anchor('section-'.$sectionno);
index 73d97c2..66152d2 100644 (file)
@@ -82,6 +82,7 @@ class format_weeks extends format_base {
      * @return null|moodle_url
      */
     public function get_view_url($section, $options = array()) {
+        global $CFG;
         $course = $this->get_course();
         $url = new moodle_url('/course/view.php', array('id' => $course->id));
 
@@ -108,7 +109,7 @@ class format_weeks extends format_base {
             if ($sectionno != 0 && $usercoursedisplay == COURSE_DISPLAY_MULTIPAGE) {
                 $url->param('section', $sectionno);
             } else {
-                if (!empty($options['navigation'])) {
+                if (empty($CFG->linkcoursesections) && !empty($options['navigation'])) {
                     return null;
                 }
                 $url->set_anchor('section-'.$sectionno);
index 35dbee9..3380e36 100644 (file)
@@ -25,7 +25,7 @@ Feature: Toggle activities groups mode from the course page
     And I set the following fields to these values:
       | Group mode | No groups |
       | Force group mode | No |
-    When I press "Save changes"
+    When I press "Save and display"
     Then "No groups (Click to change)" "link" should exist
     And "//a/child::img[contains(@src, 'groupn')]" "xpath_element" should exist
     And I click on "No groups (Click to change)" "link" in the "Test forum name" activity
index aaacef4..a2d102c 100644 (file)
@@ -108,7 +108,7 @@ class behat_course extends behat_base {
             $steps[] = new Given('I set the following fields to these values:', $table);
         }
 
-        $steps[] = new Given('I press "' . get_string('savechanges') . '"');
+        $steps[] = new Given('I press "' . get_string('savechangesanddisplay') . '"');
 
         return $steps;
     }
index 668a50d..27a334a 100644 (file)
@@ -29,3 +29,21 @@ Feature: Managers can create courses
     And I follow "News forum"
     And "Add a new topic" "button" should not exist
     And I should see "Forced subscription" in the "Administration" "block"
+
+  Scenario: Create a course from the management interface and return to it
+    Given the following "courses" exist:
+      | fullname | shortname | idnumber |
+      | Course 1 | Course 1 | C1 |
+    And I log in as "admin"
+    And I go to the courses management page
+    And I should see the "Categories" management page
+    And I click on category "Miscellaneous" in the management interface
+    And I should see the "Course categories and courses" management page
+    And I click on "Create new course" "link" in the "#course-listing" "css_element"
+    When I set the following fields to these values:
+      | Course full name | Course 2 |
+      | Course short name | Course 2 |
+      | Course summary | Course 2 summary |
+    And I press "Save and return"
+    Then I should see the "Course categories and courses" management page
+    And I should see course listing "Course 1" before "Course 2"
index 2cff137..1c74098 100644 (file)
@@ -23,9 +23,8 @@ Feature: Test we can both create and delete a course.
       | Course short name | TCCAC |
       | Course ID number | TC3401 |
       | Course summary | This course has been created by automated tests. |
-    And I press "Save changes"
+    And I press "Save and return"
     # Redirect
-    And I go to the courses management page
     And I should see the "Course categories and courses" management page
     And I click on category "Cat 1" in the management interface
     # Redirect
index 11e0f09..30b9b6a 100644 (file)
@@ -22,7 +22,7 @@ Feature: Edit course settings
       | Course full name | Edited course fullname |
       | Course short name | Edited course shortname |
       | Course summary | Edited course summary |
-    And I press "Save changes"
+    And I press "Save and display"
     And I follow "Edited course fullname"
     Then I should not see "Course 1"
     And I should not see "C1"
@@ -34,3 +34,23 @@ Feature: Edit course settings
     And the field "Course summary" matches value "Edited course summary"
     And I am on homepage
     And I should see "Edited course fullname"
+
+  Scenario: Edit course settings and return to the management interface
+    Given the following "categories" exist:
+      | name | category | idnumber |
+      | Cat 1 | 0 | CAT1 |
+    And the following "courses" exist:
+      | category | fullname | shortname | idnumber |
+      | CAT1 | Course 1 | Course 1 | C1 |
+    And I log in as "admin"
+    And I go to the courses management page
+    And I should see the "Categories" management page
+    And I click on category "Cat 1" in the management interface
+    And I should see the "Course categories and courses" management page
+    When I click on "edit" action for "Course 1" in management course listing
+    And I set the following fields to these values:
+      | Course full name | Edited course fullname |
+      | Course short name | Edited course shortname |
+      | Course summary | Edited course summary |
+    And I press "Save and return"
+    Then I should see the "Course categories and courses" management page
\ No newline at end of file
index 73fe95e..41975e0 100644 (file)
@@ -27,7 +27,7 @@ Feature: Force group mode in a course
     Given I set the following fields to these values:
       | Group mode | Separate groups |
       | Force group mode | Yes |
-    When I press "Save changes"
+    When I press "Save and display"
     Then "//a/child::img[contains(@alt, 'Separate groups (forced mode)')]" "xpath_element" should not exist
     And "//img[contains(@alt, 'Separate groups (forced mode)')]" "xpath_element" should not exist
 
@@ -36,7 +36,7 @@ Feature: Force group mode in a course
     Given I set the following fields to these values:
       | Group mode | Visible groups |
       | Force group mode | Yes |
-    And I press "Save changes"
+    And I press "Save and display"
     Then "//a/child::img[contains(@alt, 'Visible groups (forced mode)')]" "xpath_element" should not exist
     And "//img[contains(@alt, 'Visible groups (forced mode)')]" "xpath_element" should not exist
 
@@ -45,7 +45,7 @@ Feature: Force group mode in a course
     Given I set the following fields to these values:
       | Group mode | No groups |
       | Force group mode | Yes |
-    And I press "Save changes"
+    And I press "Save and display"
     Then "//a/child::img[contains(@alt, 'No groups (forced mode)')]" "xpath_element" should not exist
     And "//img[contains(@alt, 'No groups (forced mode)')]" "xpath_element" should not exist
 
index 68abd0f..f2cde5b 100644 (file)
@@ -36,7 +36,7 @@ Feature: Activities can be moved between sections
     Given I click on "Edit settings" "link" in the "Administration" "block"
     And I set the following fields to these values:
       | Course layout | Show one section per page |
-    And I press "Save changes"
+    And I press "Save and display"
     When I move "Test forum name" activity to section "2"
     Then I should see "Test forum name" in the "#section-2" "css_element"
     And I should not see "Test forum name" in the "#section-1" "css_element"
@@ -45,7 +45,7 @@ Feature: Activities can be moved between sections
     Given I click on "Edit settings" "link" in the "Administration" "block"
     And I set the following fields to these values:
       | Course layout | Show one section per page |
-    And I press "Save changes"
+    And I press "Save and display"
     And I add a "Forum" to section "1" and I fill the form with:
       | Forum name | Second forum name |
       | Description | Second forum description |
index b56a0b9..a4772fe 100644 (file)
@@ -31,7 +31,7 @@ Feature: Sections can be moved
     Given I click on "Edit settings" "link" in the "Administration" "block"
     And I set the following fields to these values:
       | Course layout | Show one section per page |
-    And I press "Save changes"
+    And I press "Save and display"
     And I add a "Forum" to section "1" and I fill the form with:
       | Forum name | Test forum name |
       | Description | Test forum description |
@@ -44,7 +44,7 @@ Feature: Sections can be moved
     Given I click on "Edit settings" "link" in the "Administration" "block"
     And I set the following fields to these values:
       | Course layout | Show one section per page |
-    And I press "Save changes"
+    And I press "Save and display"
     And I add a "Forum" to section "2" and I fill the form with:
       | Forum name | Test forum name |
       | Description | Test forum description |
index 082242c..f0195bd 100644 (file)
@@ -25,7 +25,7 @@ Feature: Rename roles within a course
     And I set the following fields to these values:
       | Your word for 'Non-editing teacher' | Tutor |
       | Your word for 'Student' | Learner |
-    And I press "Save changes"
+    And I press "Save and display"
     And I expand "Switch role to..." node
     Then I should see "Tutor"
     And I should see "Learner"
@@ -37,7 +37,7 @@ Feature: Rename roles within a course
     And I set the following fields to these values:
       | Your word for 'Non-editing teacher' | |
       | Your word for 'Student' | |
-    And I press "Save changes"
+    And I press "Save and display"
     And I expand "Switch role to..." node
     And I should see "Teacher"
     And I should see "Student"
index b5b1903..7cfb317 100644 (file)
@@ -617,6 +617,8 @@ $string['legacyfilesinnewcourses_help'] = 'By default, legacy course files areas
 $string['licensesettings'] = 'Licence settings';
 $string['linkadmincategories'] = 'Link admin categories';
 $string['linkadmincategories_help'] = 'If enabled admin setting categories will be displayed as links in the navigation and will lead to the admin category pages.';
+$string['linkcoursesections'] = 'Always link course sections';
+$string['linkcoursesections_help'] = 'Always try to provide a link for course sections. Course sections are usually only shown as links if the course format displays a single section per page. If this setting is enabled a link will always be provided.';
 $string['loading'] = 'Loading';
 $string['localetext'] = 'Sitewide locale';
 $string['localstringcustomization'] = 'Local string customization';
index db531a5..5fac49e 100644 (file)
@@ -99,9 +99,8 @@ $string['invalidlock'] = 'Invalid lock';
 $string['invalidplugin'] = 'Invalid plugin';
 $string['invalidstore'] = 'Invalid cache store provided';
 $string['lockdefault'] = 'Default';
-$string['lockingmeans'] = 'Locking mechanism';
-$string['lockmethod'] = 'Lock method';
-$string['lockmethod_help'] = 'This is the method used for locking when required of this store.';
+$string['locking'] = 'Locking';
+$string['locking_help'] = 'Locking is a mechanism that restricts access to cached data to one process at a time to prevent the data from being overwritten. The locking method determines how the lock is acquired and checked.';
 $string['lockname'] = 'Name';
 $string['locknamedesc'] = 'The name must be unique and can only consist of the characters: a-zA-Z_';
 $string['locknamenotunique'] = 'The name you have selected is not unique. Please select a unique name.';
@@ -170,3 +169,8 @@ $string['unsupportedmode'] = 'Unsupported mode';
 $string['untestable'] = 'Untestable';
 $string['userinputsharingkey'] = 'Custom key for sharing';
 $string['userinputsharingkey_help'] = 'Enter your own private key here. When you set up other stores on other sites you wish to share data with make sure you set the exact same key there.';
+
+// Deprecated since 2.9.
+$string['lockingmeans'] = 'Locking mechanism';
+$string['lockmethod'] = 'Lock method';
+$string['lockmethod_help'] = 'This is the method used for locking when required of this store.';
\ No newline at end of file
index a17e036..134a8f0 100644 (file)
@@ -7,3 +7,6 @@ hidden,core_role
 simpleview,core_grades
 fullview,core_grades
 categoriesedit,core_grades
+lockingmeans,core_cache
+lockmethod,core_cache
+lockmethod_help,core_cache
\ No newline at end of file
index 4e45ae2..577d72e 100644 (file)
@@ -1566,6 +1566,7 @@ $string['saveandnext'] = 'Save and show next';
 $string['savedat'] = 'Saved at:';
 $string['savechanges'] = 'Save changes';
 $string['savechangesanddisplay'] = 'Save and display';
+$string['savechangesandreturn'] = 'Save and return';
 $string['savechangesandreturntocourse'] = 'Save and return to course';
 $string['savecomment'] = 'Save comment';
 $string['savepreferences'] = 'Save preferences';
index bab9041..320e847 100644 (file)
@@ -85,6 +85,8 @@ class moodle1_mod_feedback_handler extends moodle1_mod_handler {
      * data available
      */
     public function process_feedback($data) {
+        global $CFG;
+
         // get the course module id and context id
         $instanceid     = $data['id'];
         $cminfo         = $this->get_cminfo($instanceid);
@@ -99,6 +101,12 @@ class moodle1_mod_feedback_handler extends moodle1_mod_handler {
         $this->fileman->itemid   = 0;
         $data['intro'] = moodle1_converter::migrate_referenced_files($data['intro'], $this->fileman);
 
+        // Convert the introformat if necessary.
+        if ($CFG->texteditors !== 'textarea') {
+            $data['intro'] = text_to_html($data['intro'], false, false, true);
+            $data['introformat'] = FORMAT_HTML;
+        }
+
         // start writing feedback.xml
         $this->open_xml_writer("activities/feedback_{$this->moduleid}/feedback.xml");
         $this->xmlwriter->begin_tag('activity', array('id' => $instanceid, 'moduleid' => $this->moduleid,
index 7014367..969e332 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 // This file is part of Moodle - http://moodle.org/
 //
 // Moodle is free software: you can redistribute it and/or modify
@@ -27,6 +26,9 @@ defined('MOODLE_INTERNAL') || die();
 
 /**
  * imscp conversion handler. This resource handler is called by moodle1_mod_resource_handler
+ *
+ * @copyright  2011 Andrew Davis <andrew@moodle.com>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 class moodle1_mod_imscp_handler extends moodle1_resource_successor_handler {
 
@@ -44,7 +46,7 @@ class moodle1_mod_imscp_handler extends moodle1_resource_successor_handler {
         $moduleid      = $currentcminfo['id'];
         $contextid     = $this->converter->get_contextid(CONTEXT_MODULE, $moduleid);
 
-        // prepare the new imscp instance record
+        // Prepare the new imscp instance record.
         $imscp                  = array();
         $imscp['id']            = $data['id'];
         $imscp['name']          = $data['name'];
@@ -55,15 +57,15 @@ class moodle1_mod_imscp_handler extends moodle1_resource_successor_handler {
         $imscp['structure']     = null;
         $imscp['timemodified']  = $data['timemodified'];
 
-        // prepare a fresh new file manager for this instance
+        // Prepare a fresh new file manager for this instance.
         $this->fileman = $this->converter->get_file_manager($contextid, 'mod_imscp');
 
-        // convert course files embedded into the intro
+        // Convert course files embedded into the intro.
         $this->fileman->filearea = 'intro';
         $this->fileman->itemid   = 0;
         $imscp['intro'] = moodle1_converter::migrate_referenced_files($imscp['intro'], $this->fileman);
 
-        // migrate package backup file
+        // Migrate package backup file.
         if ($data['reference']) {
             $packagename = basename($data['reference']);
             $packagepath = $this->converter->get_tempdir_path().'/moddata/resource/'.$data['id'].'/'.$packagename;
@@ -76,16 +78,17 @@ class moodle1_mod_imscp_handler extends moodle1_resource_successor_handler {
             }
         }
 
-        // migrate extracted package data
+        // Migrate extracted package data.
         $this->fileman->filearea = 'content';
         $this->fileman->itemid   = 1;
         $this->fileman->migrate_directory('moddata/resource/'.$data['id']);
 
-        // parse manifest
-        $structure = $this->parse_structure($this->converter->get_tempdir_path().'/moddata/resource/'.$data['id'].'/imsmanifest.xml', $imscp, $contextid);
+        // Parse manifest.
+        $structure = $this->parse_structure($this->converter->get_tempdir_path().
+                    '/moddata/resource/'.$data['id'].'/imsmanifest.xml', $imscp, $contextid);
         $imscp['structure'] = is_array($structure) ? serialize($structure) : null;
 
-        // write imscp.xml
+        // Write imscp.xml.
         $this->open_xml_writer("activities/imscp_{$moduleid}/imscp.xml");
         $this->xmlwriter->begin_tag('activity', array('id' => $instanceid, 'moduleid' => $moduleid,
             'modulename' => 'imscp', 'contextid' => $contextid));
@@ -93,7 +96,7 @@ class moodle1_mod_imscp_handler extends moodle1_resource_successor_handler {
         $this->xmlwriter->end_tag('activity');
         $this->close_xml_writer();
 
-        // write inforef.xml
+        // Write inforef.xml.
         $this->open_xml_writer("activities/imscp_{$moduleid}/inforef.xml");
         $this->xmlwriter->begin_tag('inforef');
         $this->xmlwriter->begin_tag('fileref');
@@ -105,7 +108,7 @@ class moodle1_mod_imscp_handler extends moodle1_resource_successor_handler {
         $this->close_xml_writer();
     }
 
-    /// internal implementation details follow /////////////////////////////////
+    // Internal implementation details follow.
 
     /**
      * Parse the IMS package structure for the $imscp->structure field
index a19fc0a..72c1ac5 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 // This file is part of Moodle - http://moodle.org/
 //
 // Moodle is free software: you can redistribute it and/or modify
@@ -30,6 +29,9 @@ require_once($CFG->dirroot . '/mod/imscp/backup/moodle2/backup_imscp_stepslib.ph
 
 /**
  * Provides the steps to perform one complete backup of the IMSCP instance
+ *
+ * @copyright 2010 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 class backup_imscp_activity_task extends backup_activity_task {
 
@@ -55,15 +57,15 @@ class backup_imscp_activity_task extends backup_activity_task {
     static public function encode_content_links($content) {
         global $CFG;
 
-        $base = preg_quote($CFG->wwwroot,"/");
+        $base = preg_quote($CFG->wwwroot, "/");
 
-        // Link to the list of imscps
-        $search="/(".$base."\/mod\/imscp\/index.php\?id\=)([0-9]+)/";
-        $content= preg_replace($search, '$@IMSCPINDEX*$2@$', $content);
+        // Link to the list of imscps.
+        $search = "/(" . $base . "\/mod\/imscp\/index.php\?id\=)([0-9]+)/";
+        $content = preg_replace($search, '$@IMSCPINDEX*$2@$', $content);
 
-        // Link to imscp view by moduleid
-        $search="/(".$base."\/mod\/imscp\/view.php\?id\=)([0-9]+)/";
-        $content= preg_replace($search, '$@IMSCPVIEWBYID*$2@$', $content);
+        // Link to imscp view by moduleid.
+        $search = "/(" . $base . "\/mod\/imscp\/view.php\?id\=)([0-9]+)/";
+        $content = preg_replace($search, '$@IMSCPVIEWBYID*$2@$', $content);
 
         return $content;
     }
index 38326ad..acf495a 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 // This file is part of Moodle - http://moodle.org/
 //
 // Moodle is free software: you can redistribute it and/or modify
@@ -27,39 +26,36 @@ defined('MOODLE_INTERNAL') || die();
 
 /**
  * Define the complete imscp structure for backup, with file and id annotations
+ *
+ * @copyright 2010 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 class backup_imscp_activity_structure_step extends backup_activity_structure_step {
 
     protected function define_structure() {
 
-        // To know if we are including userinfo
+        // To know if we are including userinfo.
         $userinfo = $this->get_setting_value('userinfo');
 
-        // Define each element separated
+        // Define each element separated.
         $imscp = new backup_nested_element('imscp', array('id'), array(
             'name', 'intro', 'introformat', 'revision',
             'keepold', 'structure', 'timemodified'));
 
-        // Build the tree
-        // (love this)
+        // Build the tree.
 
-        // Define sources
+        // Define sources.
         $imscp->set_source_table('imscp', array('id' => backup::VAR_ACTIVITYID));
 
-        // Define id annotations
-        // (none)
+        // Define id annotations - (none).
 
         // Define file annotations
-        $imscp->annotate_files('mod_imscp', 'intro', null); // This file area hasn't itemid
-        $imscp->annotate_files('mod_imscp', 'backup', null); // This file area hasn't itemid
-        /**
-         * I don't like itemid used for "imaginative" things like "revisions"!
-         * I don't like itemid used for "imaginative" things like "revisions"!
-         * I don't like itemid used for "imaginative" things like "revisions"!
-         */
-        $imscp->annotate_files('mod_imscp', 'content', null); // Horrible use of itemid here. Ignoring for backup/restore purposes
+        $imscp->annotate_files('mod_imscp', 'intro', null); // This file area hasn't itemid.
+        $imscp->annotate_files('mod_imscp', 'backup', null); // This file area hasn't itemid.
+        // Eloy Lafuente: I don't like itemid used for "imaginative" things like "revisions"!
+        $imscp->annotate_files('mod_imscp', 'content', null); // Horrible use of itemid here. Ignoring for backup/restore purposes.
 
-        // Return the root element (imscp), wrapped into standard activity structure
+        // Return the root element (imscp), wrapped into standard activity structure.
         return $this->prepare_activity_structure($imscp);
     }
 }
index d4547b9..03aa178 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 // This file is part of Moodle - http://moodle.org/
 //
 // Moodle is free software: you can redistribute it and/or modify
 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
 
 /**
- * @package mod_imscp
+ * Defines restore_imscp_activity_task class
+ *
+ * @package    mod_imscp
  * @subpackage backup-moodle2
- * @copyright 2010 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
- * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ * @copyright  2010 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
 defined('MOODLE_INTERNAL') || die();
 
-require_once($CFG->dirroot . '/mod/imscp/backup/moodle2/restore_imscp_stepslib.php'); // Because it exists (must)
+require_once($CFG->dirroot . '/mod/imscp/backup/moodle2/restore_imscp_stepslib.php');
 
 /**
- * imscp restore task that provides all the settings and steps to perform one
- * complete restore of the activity
+ * Provides the settings and steps to perform one complete restore of the activity
+ *
+ * @copyright 2010 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 class restore_imscp_activity_task extends restore_activity_task {
 
@@ -36,14 +39,14 @@ class restore_imscp_activity_task extends restore_activity_task {
      * Define (add) particular settings this activity can have
      */
     protected function define_my_settings() {
-        // No particular settings for this activity
+        // No particular settings for this activity.
     }
 
     /**
      * Define (add) particular steps this activity can have
      */
     protected function define_my_steps() {
-        // imscp only has one structure step
+        // Module imscp only has one structure step.
         $this->add_step(new restore_imscp_activity_structure_step('imscp_structure', 'imscp.xml'));
     }
 
index c1d278a..2f9cd58 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 // This file is part of Moodle - http://moodle.org/
 //
 // Moodle is free software: you can redistribute it and/or modify
 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
 
 /**
+ * Define all the restore steps that will be used by the restore_imscp_activity_task
+ *
  * @package mod_imscp
  * @subpackage backup-moodle2
  * @copyright 2010 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
-/**
- * Define all the restore steps that will be used by the restore_imscp_activity_task
- */
-
 /**
  * Structure step to restore one imscp activity
+ *
+ * @copyright 2010 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 class restore_imscp_activity_structure_step extends restore_activity_structure_step {
 
@@ -36,7 +36,7 @@ class restore_imscp_activity_structure_step extends restore_activity_structure_s
         $paths = array();
         $paths[] = new restore_path_element('imscp', '/activity/imscp');
 
-        // Return the paths wrapped into standard activity structure
+        // Return the paths wrapped into standard activity structure.
         return $this->prepare_activity_structure($paths);
     }
 
@@ -48,19 +48,15 @@ class restore_imscp_activity_structure_step extends restore_activity_structure_s
         $data->course = $this->get_courseid();
         $data->timemodified = $this->apply_date_offset($data->timemodified);
 
-        // insert the imscp record
+        // Insert the imscp record.
         $newitemid = $DB->insert_record('imscp', $data);
-        // immediately after inserting "activity" record, call this
+        // Immediately after inserting "activity" record, call this.
         $this->apply_activity_instance($newitemid);
     }
 
     protected function after_execute() {
-        // Add imscp related files, no need to match by itemname (just internally handled context)
-        /**
-         * I don't like itemid used for "imaginative" things like "revisions"!
-         * I don't like itemid used for "imaginative" things like "revisions"!
-         * I don't like itemid used for "imaginative" things like "revisions"!
-         */
+        // Add imscp related files, no need to match by itemname (just internally handled context).
+        // Eloy Lafuente: I don't like itemid used for "imaginative" things like "revisions"!
         $this->add_related_files('mod_imscp', 'intro', null);
         $this->add_related_files('mod_imscp', 'backup', null);
         $this->add_related_files('mod_imscp', 'content', null);
index ec0df5b..0762ca2 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 // This file is part of Moodle - http://moodle.org/
 //
 // Moodle is free software: you can redistribute it and/or modify
@@ -30,6 +29,9 @@
 
 defined('MOODLE_INTERNAL') || die();
 
+/**
+ * Stub for database installation.
+ */
 function xmldb_imscp_install() {
     global $CFG;
 
index 5c37279..2af0412 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 // This file is part of Moodle - http://moodle.org/
 //
 // Moodle is free software: you can redistribute it and/or modify
@@ -27,8 +26,8 @@
 defined('MOODLE_INTERNAL') || die();
 
 $logs = array(
-    array('module'=>'imscp', 'action'=>'view', 'mtable'=>'imscp', 'field'=>'name'),
-    array('module'=>'imscp', 'action'=>'view all', 'mtable'=>'imscp', 'field'=>'name'),
-    array('module'=>'imscp', 'action'=>'update', 'mtable'=>'imscp', 'field'=>'name'),
-    array('module'=>'imscp', 'action'=>'add', 'mtable'=>'imscp', 'field'=>'name'),
-);
\ No newline at end of file
+    array('module' => 'imscp', 'action' => 'view', 'mtable' => 'imscp', 'field' => 'name'),
+    array('module' => 'imscp', 'action' => 'view all', 'mtable' => 'imscp', 'field' => 'name'),
+    array('module' => 'imscp', 'action' => 'update', 'mtable' => 'imscp', 'field' => 'name'),
+    array('module' => 'imscp', 'action' => 'add', 'mtable' => 'imscp', 'field' => 'name'),
+);
index 969632e..0de44a1 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 // This file is part of Moodle - http://moodle.org/
 //
 // Moodle is free software: you can redistribute it and/or modify
 
 defined('MOODLE_INTERNAL') || die();
 
+/**
+ * Stub for database upgrade.
+ * @param int $oldversion
+ */
 function xmldb_imscp_upgrade($oldversion) {
     global $CFG, $DB;
 
     $dbman = $DB->get_manager();
 
+    // Moodle v2.2.0 release upgrade line.
+    // Put any upgrade step following this.
 
-    // Moodle v2.2.0 release upgrade line
-    // Put any upgrade step following this
-
-    // Moodle v2.3.0 release upgrade line
-    // Put any upgrade step following this
-
-
-    // Moodle v2.4.0 release upgrade line
-    // Put any upgrade step following this
+    // Moodle v2.3.0 release upgrade line.
+    // Put any upgrade step following this.
 
+    // Moodle v2.4.0 release upgrade line.
+    // Put any upgrade step following this.
 
     // Moodle v2.5.0 release upgrade line.
     // Put any upgrade step following this.
 
-
     // Moodle v2.6.0 release upgrade line.
     // Put any upgrade step following this.
 
index 2b6ed50..f2c7257 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 // This file is part of Moodle - http://moodle.org/
 //
 // Moodle is free software: you can redistribute it and/or modify
@@ -25,9 +24,9 @@
 
 require('../../config.php');
 
-$id = required_param('id', PARAM_INT); // course id
+$id = required_param('id', PARAM_INT); // Course id.
 
-$course = $DB->get_record('course', array('id'=>$id), '*', MUST_EXIST);
+$course = $DB->get_record('course', array('id' => $id), '*', MUST_EXIST);
 
 require_course_login($course, true);
 $PAGE->set_pagelayout('incourse');
@@ -89,10 +88,10 @@ foreach ($imscps as $imscp) {
         $printsection = '<span class="smallinfo">'.userdate($imscp->timemodified)."</span>";
     }
 
-    $class = $imscp->visible ? '' : 'class="dimmed"'; // hidden modules are dimmed
+    $class = $imscp->visible ? '' : 'class="dimmed"'; // Hidden modules are dimmed.
     $table->data[] = array (
         $printsection,
-        "<a $class href=\"view.php?id=$cm->id\">".format_string($imscp->name)."</a>",
+        "<a $class href=\"view.php?id=$cm->id\">" . format_string($imscp->name)."</a>",
         format_module_intro('imscp', $imscp, $cm->id));
 }
 
index c20ea67..8358146 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 // This file is part of Moodle - http://moodle.org/
 //
 // Moodle is free software: you can redistribute it and/or modify
index 0721c83..cfd8a17 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 // This file is part of Moodle - http://moodle.org/
 //
 // Moodle is free software: you can redistribute it and/or modify
@@ -56,7 +55,8 @@ function imscp_get_extra_capabilities() {
 
 /**
  * This function is used by the reset_course_userdata function in moodlelib.
- * @param $data the data submitted from the reset course.
+ *
+ * @param stdClass $data the data submitted from the reset course.
  * @return array status array
  */
 function imscp_reset_userdata($data) {
@@ -109,10 +109,10 @@ function imscp_add_instance($data, $mform) {
 
     $data->id = $DB->insert_record('imscp', $data);
 
-    // we need to use context now, so we need to make sure all needed info is already in db
-    $DB->set_field('course_modules', 'instance', $data->id, array('id'=>$cmid));
+    // We need to use context now, so we need to make sure all needed info is already in db.
+    $DB->set_field('course_modules', 'instance', $data->id, array('id' => $cmid));
     $context = context_module::instance($cmid);
-    $imscp = $DB->get_record('imscp', array('id'=>$data->id), '*', MUST_EXIST);
+    $imscp = $DB->get_record('imscp', array('id' => $data->id), '*', MUST_EXIST);
 
     if (!empty($data->package)) {
         // Save uploaded files to 'backup' filearea.
@@ -150,12 +150,12 @@ function imscp_update_instance($data, $mform) {
 
     $data->timemodified = time();
     $data->id           = $data->instance;
-    $data->structure   = null; // better reparse structure after each update
+    $data->structure   = null; // Better reparse structure after each update.
 
     $DB->update_record('imscp', $data);
 
     $context = context_module::instance($cmid);
-    $imscp = $DB->get_record('imscp', array('id'=>$data->id), '*', MUST_EXIST);
+    $imscp = $DB->get_record('imscp', array('id' => $data->id), '*', MUST_EXIST);
 
     if (!empty($data->package) && ($draftareainfo = file_get_draft_area_info($data->package)) &&
             $draftareainfo['filecount']) {
@@ -164,7 +164,7 @@ function imscp_update_instance($data, $mform) {
         $imscp->revision++;
         $DB->update_record('imscp', $imscp);
 
-        // get a list of existing packages before adding new package
+        // Get a list of existing packages before adding new package.
         if ($imscp->keepold > -1) {
             $packages = $fs->get_area_files($context->id, 'mod_imscp', 'backup', false, "itemid ASC", false);
         } else {
@@ -176,16 +176,16 @@ function imscp_update_instance($data, $mform) {
         $files = $fs->get_area_files($context->id, 'mod_imscp', 'backup', $imscp->revision, '', false);
         $package = reset($files);
 
-        // purge all extracted content
+        // Purge all extracted content.
         $fs->delete_area_files($context->id, 'mod_imscp', 'content');
 
-        // extract package content
+        // Extract package content.
         if ($package) {
             $packer = get_file_packer('application/zip');
             $package->extract_to_storage($packer, $context->id, 'mod_imscp', 'content', $imscp->revision, '/');
         }
 
-        // cleanup old package files, keep current + keepold
+        // Cleanup old package files, keep current + keep old.
         while ($packages and (count($packages) > $imscp->keepold)) {
             $package = array_shift($packages);
             $fs->delete_area_files($context->id, 'mod_imscp', 'backup', $package->get_itemid());
@@ -207,13 +207,13 @@ function imscp_update_instance($data, $mform) {
 function imscp_delete_instance($id) {
     global $DB;
 
-    if (!$imscp = $DB->get_record('imscp', array('id'=>$id))) {
+    if (!$imscp = $DB->get_record('imscp', array('id' => $id))) {
         return false;
     }
 
-    // note: all context files are deleted automatically
+    // Note: all context files are deleted automatically.
 
-    $DB->delete_records('imscp', array('id'=>$imscp->id));
+    $DB->delete_records('imscp', array('id' => $imscp->id));
 
     return true;
 }
@@ -256,10 +256,10 @@ function imscp_get_file_areas($course, $cm, $context) {
 function imscp_get_file_info($browser, $areas, $course, $cm, $context, $filearea, $itemid, $filepath, $filename) {
     global $CFG, $DB;
 
-    // note: imscp_intro handled in file_browser automatically
+    // Note: imscp_intro handled in file_browser automatically.
 
     if (!has_capability('moodle/course:managefiles', $context)) {
-        // no peaking here for students!!
+        // No peeking here for students!
         return null;
     }
 
@@ -280,9 +280,9 @@ function imscp_get_file_info($browser, $areas, $course, $cm, $context, $filearea
         return null;
     }
 
-    // do not allow manual modification of any files!
+    // Do not allow manual modification of any files!
     $urlbase = $CFG->wwwroot.'/pluginfile.php';
-    return new file_info_stored($browser, $context, $storedfile, $urlbase, $itemid, true, true, false, false); //no writing here!
+    return new file_info_stored($browser, $context, $storedfile, $urlbase, $itemid, true, true, false, false); // No writing here!
 }
 
 /**
@@ -317,7 +317,7 @@ function imscp_pluginfile($course, $cm, $context, $filearea, $args, $forcedownlo
         $relativepath = implode('/', $args);
         if ($relativepath === 'imsmanifest.xml') {
             if (!has_capability('moodle/course:managefiles', $context)) {
-                // no stealing of detailed package info ;-)
+                // No stealing of detailed package info.
                 return false;
             }
         }
@@ -326,12 +326,12 @@ function imscp_pluginfile($course, $cm, $context, $filearea, $args, $forcedownlo
             return false;
         }
 
-        // finally send the file
+        // Finally send the file.
         send_stored_file($file, null, 0, $forcedownload, $options);
 
     } else if ($filearea === 'backup') {
         if (!has_capability('moodle/course:managefiles', $context)) {
-            // no stealing of package backups
+            // No stealing of package backups.
             return false;
         }
         $revision = array_shift($args);
@@ -342,7 +342,7 @@ function imscp_pluginfile($course, $cm, $context, $filearea, $args, $forcedownlo
             return false;
         }
 
-        // finally send the file
+        // Finally send the file.
         send_stored_file($file, null, 0, $forcedownload, $options);
 
     } else {
@@ -355,8 +355,9 @@ function imscp_pluginfile($course, $cm, $context, $filearea, $args, $forcedownlo
  * @param string $pagetype current page type
  * @param stdClass $parentcontext Block's parent context
  * @param stdClass $currentcontext Current context of block
+ * @return array $modulepagetype list
  */
 function imscp_page_type_list($pagetype, $parentcontext, $currentcontext) {
-    $module_pagetype = array('mod-imscp-*'=>get_string('page-mod-imscp-x', 'imscp'));
-    return $module_pagetype;
+    $modulepagetype = array('mod-imscp-*' => get_string('page-mod-imscp-x', 'imscp'));
+    return $modulepagetype;
 }
index 3ebd106..03e727f 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 // This file is part of Moodle - http://moodle.org/
 //
 // Moodle is free software: you can redistribute it and/or modify
@@ -29,6 +28,13 @@ require_once("$CFG->dirroot/mod/imscp/lib.php");
 require_once("$CFG->libdir/filelib.php");
 require_once("$CFG->libdir/resourcelib.php");
 
+/**
+ * Print IMSCP content to page.
+ *
+ * @param stdClass $imscp module instance.
+ * @param stdClass $cm course module.
+ * @param stdClass $course record.
+ */
 function imscp_print_content($imscp, $cm, $course) {
     global $PAGE, $CFG;
 
@@ -46,7 +52,10 @@ function imscp_print_content($imscp, $cm, $course) {
         echo imscp_htmllize_item($item, $imscp, $cm);
     }
     echo '</ul></div>';
-    echo '<div id="imscp_nav" style="display:none"><button id="nav_skipprev">&lt;&lt;</button><button id="nav_prev">&lt;</button><button id="nav_up">^</button><button id="nav_next">&gt;</button><button id="nav_skipnext">&gt;&gt;</button></div>';
+    echo '<div id="imscp_nav" style="display:none">';
+    echo '<button id="nav_skipprev">&lt;&lt;</button><button id="nav_prev">&lt;</button><button id="nav_up">^</button>';
+    echo '<button id="nav_next">&gt;</button><button id="nav_skipnext">&gt;&gt;</button>';
+    echo '</div>';
     echo '</div>';
     echo '</div>';
 
@@ -60,15 +69,19 @@ function imscp_print_content($imscp, $cm, $course) {
 function imscp_htmllize_item($item, $imscp, $cm) {
     global $CFG;
 
-    if (preg_match('|^https?://|', $item['href'])) {
-        $url = $item['href'];
+    if ($item['href']) {
+        if (preg_match('|^https?://|', $item['href'])) {
+            $url = $item['href'];
+        } else {
+            $context = context_module::instance($cm->id);
+            $urlbase = "$CFG->wwwroot/pluginfile.php";
+            $path = '/'.$context->id.'/mod_imscp/content/'.$imscp->revision.'/'.$item['href'];
+            $url = file_encode_url($urlbase, $path, false);
+        }
+        $result = "<li><a href=\"$url\">".$item['title'].'</a>';
     } else {
-        $context = context_module::instance($cm->id);
-        $urlbase = "$CFG->wwwroot/pluginfile.php";
-        $path = '/'.$context->id.'/mod_imscp/content/'.$imscp->revision.'/'.$item['href'];
-        $url = file_encode_url($urlbase, $path, false);
+        $result = '<li>'.$item['title'];
     }
-    $result = "<li><a href=\"$url\">".$item['title'].'</a>';
     if ($item['subitems']) {
         $result .= '<ul>';
         foreach ($item['subitems'] as $subitem) {
@@ -98,7 +111,7 @@ function imscp_parse_structure($imscp, $context) {
 }
 
 /**
- * Parse the contents of a IMS package's manifest file
+ * Parse the contents of a IMS package's manifest file.
  * @param string $manifestfilecontents the contents of the manifest file
  * @return array
  */
@@ -110,7 +123,7 @@ function imscp_parse_manifestfile($manifestfilecontents, $imscp, $context) {
     }
     libxml_disable_entity_loader($oldentities);
 
-    // we put this fake URL as base in order to detect path changes caused by xml:base attributes
+    // We put this fake URL as base in order to detect path changes caused by xml:base attributes.
     $doc->documentURI = 'http://grrr/';
 
     $xmlorganizations = $doc->getElementsByTagName('organizations');
@@ -128,20 +141,20 @@ function imscp_parse_manifestfile($manifestfilecontents, $imscp, $context) {
     $organization = null;
     foreach ($xmlorganization as $org) {
         if (is_null($organization)) {
-            // use first if default nor found
+            // Use first if default nor found.
             $organization = $org;
         }
         if (!$org->attributes->getNamedItem('identifier')) {
             continue;
         }
         if ($default === $org->attributes->getNamedItem('identifier')->nodeValue) {
-            // found default - use it
+            // Found default - use it.
             $organization = $org;
             break;
         }
     }
 
-    // load all resources
+    // Load all resources.
     $resources = array();
 
     $xmlresources = $doc->getElementsByTagName('resource');
@@ -151,14 +164,14 @@ function imscp_parse_manifestfile($manifestfilecontents, $imscp, $context) {
         }
         $identifier = $identifier->nodeValue;
         if ($xmlbase = $res->baseURI) {
-            // undo the fake URL, we are interested in relative links only
+            // Undo the fake URL, we are interested in relative links only.
             $xmlbase = str_replace('http://grrr/', '/', $xmlbase);
             $xmlbase = rtrim($xmlbase, '/').'/';
         } else {
             $xmlbase = '';
         }
         if (!$href = $res->attributes->getNamedItem('href')) {
-            // If href not found look for <file href="help.htm"/>
+            // If href not found look for <file href="help.htm"/>.
             $fileresources = $res->getElementsByTagName('file');
             foreach ($fileresources as $file) {
                 $href = $file->getAttribute('href');
@@ -175,7 +188,7 @@ function imscp_parse_manifestfile($manifestfilecontents, $imscp, $context) {
         if (strpos($href, 'http://') !== 0) {
             $href = $xmlbase.$href;
         }
-        // href cleanup - Some packages are poorly done and use \ in urls
+        // Item href cleanup - Some packages are poorly done and use \ in urls.
         $href = ltrim(strtr($href, "\\", '/'), '/');
         $resources[$identifier] = $href;
     }
@@ -248,7 +261,7 @@ function imscp_recursive_item($xmlitem, $level, $resources) {
             $title = $child->textContent;
 
         } else if ($child->nodeName === 'item') {
-            if ($subitem = imscp_recursive_item($child, $level+1, $resources)) {
+            if ($subitem = imscp_recursive_item($child, $level + 1, $resources)) {
                 $subitems[] = $subitem;
             }
         }
@@ -263,6 +276,9 @@ function imscp_recursive_item($xmlitem, $level, $resources) {
 
 /**
  * File browsing support class
+ *
+ * @copyright  2009 Petr Skoda  {@link http://skodak.org}
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 class imscp_file_info extends file_info {
     protected $course;
@@ -285,12 +301,12 @@ class imscp_file_info extends file_info {
      * @return array with keys contextid, filearea, itemid, filepath and filename
      */
     public function get_params() {
-        return array('contextid'=>$this->context->id,
-                     'component'=>'mod_imscp',
-                     'filearea' =>$this->filearea,
-                     'itemid'   =>null,
-                     'filepath' =>null,
-                     'filename' =>null);
+        return array('contextid' => $this->context->id,
+                     'component' => 'mod_imscp',
+                     'filearea'  => $this->filearea,
+                     'itemid'    => null,
+                     'filepath'  => null,
+                     'filename'  => null);
     }
 
     /**
index 417877c..8823cdb 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 // This file is part of Moodle - http://moodle.org/
 //
 // Moodle is free software: you can redistribute it and/or modify
@@ -16,7 +15,7 @@
 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
 
 /**
- * IMS CP configuration form
+ * This file contains the forms to create and edit an instance of this module
  *
  * @package mod_imscp
  * @copyright  2009 Petr Skoda  {@link http://skodak.org}
 
 defined('MOODLE_INTERNAL') || die();
 
-require_once ($CFG->dirroot.'/course/moodleform_mod.php');
+require_once($CFG->dirroot.'/course/moodleform_mod.php');
 require_once($CFG->libdir.'/filelib.php');
 
+/**
+ * IMS CP configuration form
+ *
+ * @package mod_imscp
+ * @copyright  2009 Petr Skoda  {@link http://skodak.org}
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
 class mod_imscp_mod_form extends moodleform_mod {
-    function definition() {
+    /**
+     * Define the form - called by parent constructor
+     */
+    public function definition() {
         global $CFG, $DB;
         $mform = $this->_form;
 
         $config = get_config('imscp');
 
-        //-------------------------------------------------------
+        // Title and description.
         $mform->addElement('header', 'general', get_string('general', 'form'));
-        $mform->addElement('text', 'name', get_string('name'), array('size'=>'48'));
+        $mform->addElement('text', 'name', get_string('name'), array('size' => '48'));
         if (!empty($CFG->formatstringstriptags)) {
             $mform->setType('name', PARAM_TEXT);
         } else {
@@ -47,24 +56,28 @@ class mod_imscp_mod_form extends moodleform_mod {
         $mform->addRule('name', get_string('maximumchars', '', 255), 'maxlength', 255, 'client');
         $this->add_intro_editor($config->requiremodintro);
 
-        //-------------------------------------------------------
+        // IMS-CP file upload.
         $mform->addElement('header', 'content', get_string('contentheader', 'imscp'));
         $mform->setExpanded('content', true);
         $mform->addElement('filepicker', 'package', get_string('packagefile', 'imscp'));
 
-        $options = array('-1'=>get_string('all'), '0'=>get_string('no'), '1'=>'1', '2'=>'2', '5'=>'5', '10'=>'10', '20'=>'20');
+        $options = array('-1' => get_string('all'), '0' => get_string('no'),
+                         '1' => '1', '2' => '2', '5' => '5', '10' => '10', '20' => '20');
         $mform->addElement('select', 'keepold', get_string('keepold', 'imscp'), $options);
         $mform->setDefault('keepold', $config->keepold);
         $mform->setAdvanced('keepold', $config->keepold_adv);
 
-        //-------------------------------------------------------
         $this->standard_coursemodule_elements();
 
-        //-------------------------------------------------------
         $this->add_action_buttons();
     }
 
-    function validation($data, $files) {
+    /**
+     * Perform minimal validation on the settings form
+     * @param array $data
+     * @param array $files
+     */
+    public function validation($data, $files) {
         global $USER;
 
         if ($errors = parent::validation($data, $files)) {
@@ -83,7 +96,7 @@ class mod_imscp_mod_form extends moodleform_mod {
             $file = reset($files);
             if ($file->get_mimetype() != 'application/zip') {
                 $errors['package'] = get_string('invalidfiletype', 'error', '', $file);
-                // better delete current file, it is not usable anyway
+                // Better delete current file, it is not usable anyway.
                 $fs->delete_area_files($usercontext->id, 'user', 'draft', $data['package']);
             }
         }
index c4f226a..0f17b95 100644 (file)
@@ -33,6 +33,10 @@ M.mod_imscp.init = function(Y) {
 
     Y.use('yui2-resize', 'yui2-dragdrop', 'yui2-container', 'yui2-button', 'yui2-layout', 'yui2-treeview', 'yui2-json', 'yui2-event', function(Y) {
 
+        var imscp_activate_item_by_index = function(index) {
+            imscp_activate_item(Y.YUI2.widget.TreeView.getNode('imscp_tree', index));
+        };
+
         var imscp_activate_item = function(node) {
             if (!node) {
                 return;
@@ -41,21 +45,53 @@ M.mod_imscp.init = function(Y) {
             imscp_current_node.highlight();
 
             var content = new Y.YUI2.util.Element('imscp_content');
-            try {
-                // first try IE way - it can not set name attribute later
-                // and also it has some restrictions on DOM access from object tag
-                var obj = document.createElement('<iframe id="imscp_object" src="'+node.href+'">');
-            } catch (e) {
-                var obj = document.createElement('object');
-                obj.setAttribute('id', 'imscp_object');
-                obj.setAttribute('type', 'text/html');
-                obj.setAttribute('data', node.href);
+            var obj;
+            if (node.href) {
+                try {
+                    // First try IE way - it can not set name attribute later
+                    // and also it has some restrictions on DOM access from object tag.
+                    obj = document.createElement('<iframe id="imscp_object" src="' + node.href + '">');
+                } catch (e) {
+                    obj = document.createElement('object');
+                    obj.setAttribute('id', 'imscp_object');
+                    obj.setAttribute('type', 'text/html');
+                    obj.setAttribute('data', node.href);
+                }
+            } else {
+                // No href, so create links to children.
+                obj = document.createElement('div');
+                obj.setAttribute('id', 'imscp_child_list');
+
+                var title = document.createElement('h2');
+                title.appendChild(document.createTextNode(node.label));
+                title.setAttribute('class', 'sectionname');
+                obj.appendChild(title);
+
+                var ul = document.createElement('ul');
+                obj.appendChild(ul);
+                for (var i = 0; i < node.children.length; i++) {
+                    var childnode = node.children[i];
+                    var li = document.createElement('li');
+                    var a = document.createElement('a');
+                    a.appendChild(document.createTextNode(childnode.label));
+                    a.setAttribute('id', 'ref_' + childnode.index);
+                    Y.YUI2.util.Event.addListener(a, "click", function () {
+                        imscp_activate_item_by_index(this.id.substr(4));
+                    });
+                    ul.appendChild(li);
+                    li.appendChild(a);
+                }
             }
             var old = Y.YUI2.util.Dom.get('imscp_object');
             if (old) {
                 content.replaceChild(obj, old);
             } else {
-                content.appendChild(obj);
+                old = Y.YUI2.util.Dom.get('imscp_child_list');
+                if (old) {
+                    content.replaceChild(obj, old);
+                } else {
+                    content.appendChild(obj);
+                }
             }
             imscp_resize_frame();
 
@@ -75,17 +111,16 @@ M.mod_imscp.init = function(Y) {
             imscp_buttons[4].set('disabled', (imscp_skipnext(imscp_current_node) == null));
         };
 
-
         var imscp_resize_layout = function(alsowidth) {
             if (alsowidth) {
                 var layout = Y.YUI2.util.Dom.get('imscp_layout');
                 var newwidth = imscp_get_htmlelement_size('maincontent', 'width');
                 layout.style.width = '600px';
                 if (newwidth > 600) {
-                    layout.style.width = newwidth+'px';
+                    layout.style.width = newwidth + 'px';
                 }
             }
-            // make sure that the max width of the TOC doesn't go to far
+            // Make sure that the max width of the TOC doesn't go to far.
 
             var left = imscp_layout_widget.getUnitByPosition('left');
             var maxwidth = parseInt(Y.YUI2.util.Dom.getStyle('imscp_layout', 'width'));
@@ -101,7 +136,7 @@ M.mod_imscp.init = function(Y) {
             if (newheight < 400) {
                 newheight = 400;
             }
-            imscp_layout_widget.setStyle('height', newheight+'px');
+            imscp_layout_widget.setStyle('height', newheight + 'px');
 
             imscp_layout_widget.render();
             imscp_resize_frame();
@@ -111,7 +146,7 @@ M.mod_imscp.init = function(Y) {
             var val = Y.YUI2.util.Dom.getStyle(el, prop);
             if (val == 'auto') {
                 if (el.get) {
-                    el = el.get('element'); // get real HTMLElement from YUI element
+                    el = el.get('element'); // Get real HTMLElement from YUI element.
                 }
                 val = Y.YUI2.util.Dom.getComputedStyle(Y.YUI2.util.Dom.get(el), prop);
             }
@@ -119,26 +154,37 @@ M.mod_imscp.init = function(Y) {
         };
 
         var imscp_resize_frame = function() {
-            var obj = Y.YUI2.util.Dom.get('imscp_object');
+            obj = Y.YUI2.util.Dom.get('imscp_object');
             if (obj) {
                 var content = imscp_layout_widget.getUnitByPosition('center').get('wrap');
-                // basically trap IE6 and 7
+                // Basically trap IE6 and 7.
                 if (Y.YUI2.env.ua.ie > 5 && Y.YUI2.env.ua.ie < 8) {
                     if( obj.style.setAttribute ) {
-                        obj.style.setAttribute("cssText", 'width: ' +(content.offsetWidth - 6)+'px; height: ' + (content.offsetHeight - 10)+'px;');
+                        obj.style.setAttribute("cssText", 'width: ' + (content.offsetWidth - 6) + 'px; height: ' + (content.offsetHeight - 10) + 'px;');
                     }
                     else {
-                        obj.style.setAttribute('width', (content.offsetWidth - 6)+'px', 0);
-                        obj.style.setAttribute('height', (content.offsetHeight - 10)+'px', 0);
+                        obj.style.setAttribute('width', (content.offsetWidth - 6) + 'px', 0);
+                        obj.style.setAttribute('height', (content.offsetHeight - 10) + 'px', 0);
                     }
                 }
                 else {
-                    obj.style.width = (content.offsetWidth - 6)+'px';
-                    obj.style.height = (content.offsetHeight - 10)+'px';
+                    obj.style.width = (content.offsetWidth - 6) + 'px';
+                    obj.style.height = (content.offsetHeight - 10) + 'px';
                 }
             }
         };
 
+        var imscp_firstlinked = function(node) {
+            // Return first item with an href.
+            if (node.href) {
+                return node;
+            } else if (node.children) {
+                return imscp_firstlinked(node.children[0]);
+            } else {
+                return null;
+            }
+        };
+
         var imscp_up = function(node) {
             if (node.depth > 0) {
                 return node.parent;
@@ -148,7 +194,7 @@ M.mod_imscp.init = function(Y) {
 
         var imscp_lastchild = function(node) {
             if (node.children.length) {
-                return imscp_lastchild(node.children[node.children.length-1]);
+                return imscp_lastchild(node.children[node.children.length - 1]);
             } else {
                 return node;
             }
@@ -186,8 +232,7 @@ M.mod_imscp.init = function(Y) {
             return null;
         };
 
-
-        // layout
+        // Layout.
         Y.YUI2.widget.LayoutUnit.prototype.STR_COLLAPSE = M.util.get_string('hide', 'moodle');
         Y.YUI2.widget.LayoutUnit.prototype.STR_EXPAND = M.util.get_string('show', 'moodle');
 
@@ -208,18 +253,18 @@ M.mod_imscp.init = function(Y) {
             imscp_resize_frame();
         });
 
-        // ugly resizing hack that works around problems with resizing of iframes and objects
+        // Ugly resizing hack that works around problems with resizing of iframes and objects.
         left._resize.on('startResize', function() {
-            var obj = Y.YUI2.util.Dom.get('imscp_object');
+            obj = Y.YUI2.util.Dom.get('imscp_object');
             obj.style.display = 'none';
         });
         left._resize.on('endResize', function() {
-            var obj = Y.YUI2.util.Dom.get('imscp_object');
+            obj = Y.YUI2.util.Dom.get('imscp_object');
             obj.style.display = 'block';
             imscp_resize_frame();
         });
 
-        // TOC tree
+        // TOC tree.
         var tree = new Y.YUI2.widget.TreeView('imscp_tree');
         tree.singleNodeHighlight = true;
         tree.subscribe('clickEvent', function(oArgs) {
@@ -248,7 +293,7 @@ M.mod_imscp.init = function(Y) {
         var navbar = Y.YUI2.util.Dom.get('imscp_nav');
         navbar.style.display = 'block';
 
-        // navigation
+        // Navigation.
         imscp_buttons[0] = new Y.YUI2.widget.Button('nav_skipprev');
         imscp_buttons[1] = new Y.YUI2.widget.Button('nav_prev');
         imscp_buttons[2] = new Y.YUI2.widget.Button('nav_up');
@@ -270,13 +315,13 @@ M.mod_imscp.init = function(Y) {
             imscp_activate_item(imscp_skipnext(imscp_current_node));
         });
 
-        // finally activate the first item
-        imscp_activate_item(tree.getRoot().children[0]);
+        // Finally activate the first item.
+        imscp_activate_item(imscp_firstlinked(tree.getRoot().children[0]));
 
-        // resizing
+        // Resizing.
         imscp_resize_layout(false);
 
-        // fix layout if window resized
+        // Fix layout if window resized.
         window.onresize = function() {
             imscp_resize_layout(true);
         };
index eec0bdc..d235ae9 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 // This file is part of Moodle - http://moodle.org/
 //
 // Moodle is free software: you can redistribute it and/or modify
@@ -27,14 +26,17 @@ defined('MOODLE_INTERNAL') || die;
 
 if ($ADMIN->fulltree) {
 
-    //--- general settings -----------------------------------------------------------------------------------
+    // General settings.
     $settings->add(new admin_setting_configcheckbox('imscp/requiremodintro', get_string('requiremodintro', 'admin'),
                                         get_string('configrequiremodintro', 'admin'), 1));
 
-    //--- modedit defaults -----------------------------------------------------------------------------------
-    $settings->add(new admin_setting_heading('imscpmodeditdefaults', get_string('modeditdefaults', 'admin'), get_string('condifmodeditdefaults', 'admin')));
-    $options = array('-1'=>get_string('all'), '0'=>get_string('no'), '1'=>'1', '2'=>'2', '5'=>'5', '10'=>'10', '20'=>'20');
+    // Modedit defaults.
+    $settings->add(new admin_setting_heading('imscpmodeditdefaults',
+                                             get_string('modeditdefaults', 'admin'),
+                                             get_string('condifmodeditdefaults', 'admin')));
+    $options = array('-1' => get_string('all'), '0' => get_string('no'),
+                     '1' => '1', '2' => '2', '5' => '5', '10' => '10', '20' => '20');
     $settings->add(new admin_setting_configselect_with_advanced('imscp/keepold',
         get_string('keepold', 'imscp'), get_string('keepoldexplain', 'imscp'),
-        array('value'=>1, 'adv'=>false), $options));
+        array('value' => 1, 'adv' => false), $options));
 }
index 7fbb568..7f8b24a 100644 (file)
 
 #page-mod-imscp-view .yui-layout-hd h2 {
  color: black;
-}
\ No newline at end of file
+}
+
+.path-mod-imscp #imscp_child_list {
+ margin-left: 1em;
+ width: auto;
+ height: auto;
+}
index fe1e8ca..77c2138 100644 (file)
@@ -53,14 +53,14 @@ class mod_imscp_generator_testcase extends advanced_testcase {
         $this->assertEquals('Another imscp', $records[$imscp->id]->name);
 
         // Examples of specifying the package file (do not validate anything, just check for exceptions).
-        // 1. As path to the file in filesystem:
+        // 1. As path to the file in filesystem...
         $params = array(
             'course' => $course->id,
             'packagepath' => $CFG->dirroot.'/mod/imscp/tests/packages/singlescobasic.zip'
         );
         $imscp = $this->getDataGenerator()->create_module('imscp', $params);
 
-        // 2. As file draft area id:
+        // 2. As file draft area id...
         $fs = get_file_storage();
         $params = array(
             'course' => $course->id,
index c7423e3..95b63ba 100644 (file)
@@ -24,7 +24,7 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2014111000;       // The current module version (Date: YYYYMMDDXX)
-$plugin->requires  = 2014110400;    // Requires this Moodle version
-$plugin->component = 'mod_imscp';      // Full name of the plugin (used for diagnostics)
+$plugin->version   = 2014111000;  // The current module version (Date: YYYYMMDDXX).
+$plugin->requires  = 2014110400;  // Requires this Moodle version.
+$plugin->component = 'mod_imscp'; // Full name of the plugin (used for diagnostics).
 $plugin->cron      = 0;
index 6a11b58..eacf10f 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 // This file is part of Moodle - http://moodle.org/
 //
 // Moodle is free software: you can redistribute it and/or modify
@@ -27,19 +26,19 @@ require('../../config.php');
 require_once("$CFG->dirroot/mod/imscp/locallib.php");
 require_once($CFG->libdir . '/completionlib.php');
 
-$id = optional_param('id', 0, PARAM_INT);  // Course module ID
-$i  = optional_param('i', 0, PARAM_INT);   // IMS CP instance id
+$id = optional_param('id', 0, PARAM_INT);  // Course module id.
+$i  = optional_param('i', 0, PARAM_INT);   // IMS CP instance id.
 
-if ($i) {  // Two ways to specify the module
-    $imscp = $DB->get_record('imscp', array('id'=>$i), '*', MUST_EXIST);
+if ($i) {  // Two ways to specify the module.
+    $imscp = $DB->get_record('imscp', array('id' => $i), '*', MUST_EXIST);
     $cm = get_coursemodule_from_instance('imscp', $imscp->id, $imscp->course, false, MUST_EXIST);
 
 } else {
     $cm = get_coursemodule_from_id('imscp', $id, 0, false, MUST_EXIST);
-    $imscp = $DB->get_record('imscp', array('id'=>$cm->instance), '*', MUST_EXIST);
+    $imscp = $DB->get_record('imscp', array('id' => $cm->instance), '*', MUST_EXIST);
 }
 
-$course = $DB->get_record('course', array('id'=>$cm->course), '*', MUST_EXIST);
+$course = $DB->get_record('course', array('id' => $cm->course), '*', MUST_EXIST);
 
 require_course_login($course, true, $cm);
 $context = context_module::instance($cm->id);
@@ -53,7 +52,7 @@ $event = \mod_imscp\event\course_module_viewed::create($params);
 $event->add_record_snapshot('imscp', $imscp);
 $event->trigger();
 
-// Update 'viewed' state if required by completion system
+// Update 'viewed' state if required by completion system.
 $completion = new completion_info($course);
 $completion->set_module_viewed($cm);
 
@@ -65,8 +64,8 @@ $PAGE->requires->string_for_js('toc', 'imscp');
 $PAGE->requires->string_for_js('hide', 'moodle');
 $PAGE->requires->string_for_js('show', 'moodle');
 
-//TODO: find some better way to disable blocks and minimise footer - pagetype just for this does not seem like a good solution
-//$PAGE->set_pagelayout('maxcontent');
+// TODO: find some better way to disable blocks and minimise footer - pagetype just for this does not seem like a good solution.
+// $PAGE->set_pagelayout('maxcontent'); ?
 
 $PAGE->set_title($course->shortname.': '.$imscp->name);
 $PAGE->set_heading($course->fullname);
@@ -74,7 +73,7 @@ $PAGE->set_activity_record($imscp);
 echo $OUTPUT->header();
 echo $OUTPUT->heading(format_string($imscp->name));
 
-// verify imsmanifest was parsed properly
+// Verify imsmanifest was parsed properly.
 if (!$imscp->structure) {
     echo $OUTPUT->notification(get_string('deploymenterror', 'imscp'), 'notifyproblem');
     echo $OUTPUT->footer();
index a458b01..11ad3bf 100644 (file)
@@ -34,3 +34,8 @@ Feature: Test importing questions from GIFT format.
     And I set the field "id_format_gift" to "1"
     And I press "Export questions to file"
     And following "click here" should download between "1550" and "1650" bytes
+    # If the download step is the last in the scenario then we can sometimes run
+    # into the situation where the download page causes a http redirect but behat
+    # has already conducted its reset (generating an error). By putting a logout
+    # step we avoid behat doing the reset until we are off that page.
+    And I log out
index 18dcc9b..941c722 100644 (file)
@@ -36,6 +36,11 @@ Feature: Test importing questions from Moodle XML format.
     And I set the field "id_format_xml" to "1"
     And I press "Export questions to file"
     And following "click here" should download between "57000" and "58000" bytes
+    # If the download step is the last in the scenario then we can sometimes run
+    # into the situation where the download page causes a http redirect but behat
+    # has already conducted its reset (generating an error). By putting a logout
+    # step we avoid behat doing the reset until we are off that page.
+    And I log out
 
   @javascript @_file_upload
   Scenario: import some multiple choice questions from Moodle XML format
index 2d0237e..fc2d7f8 100644 (file)
@@ -29,7 +29,7 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$version  = 2014120102.00;              // YYYYMMDD      = weekly release date of this DEV branch.
+$version  = 2014120200.00;              // YYYYMMDD      = weekly release date of this DEV branch.
                                         //         RR    = release increments - 00 in DEV branches.
                                         //           .XX = incremental changes.