Merge branch 'wip-MDL-33338-master' of git://github.com/marinaglancy/moodle
authorDan Poltawski <dan@moodle.com>
Mon, 28 May 2012 07:43:33 +0000 (15:43 +0800)
committerDan Poltawski <dan@moodle.com>
Mon, 28 May 2012 07:43:33 +0000 (15:43 +0800)
63 files changed:
auth/shibboleth/index.php
backup/moodle2/restore_final_task.class.php
backup/moodle2/restore_stepslib.php
backup/util/helper/backup_cron_helper.class.php
course/lib.php
course/view.php
course/yui/dragdrop/dragdrop.js
grade/lib.php
lib/db/log.php
lib/db/upgrade.php
lib/filelib.php
lib/filestorage/file_storage.php
lib/filestorage/stored_file.php
lib/gdlib.php
lib/mathslib.php
lib/outputcomponents.php
lib/yui/blocks/blocks.js
lib/yui/dragdrop/dragdrop.js
mod/book/lang/en/book.php
mod/book/locallib.php
mod/book/settings.php
mod/book/styles.css
mod/book/tool/exportimscp/lang/en/booktool_exportimscp.php
mod/book/tool/importhtml/lang/en/booktool_importhtml.php
mod/book/version.php
mod/feedback/complete.php
mod/feedback/complete_guest.php
mod/feedback/item/captcha/lib.php
mod/feedback/item/feedback_item_class.php
mod/feedback/item/info/lib.php
mod/feedback/item/label/lib.php
mod/feedback/item/multichoice/lib.php
mod/feedback/item/multichoicerated/lib.php
mod/feedback/item/numeric/lib.php
mod/feedback/item/textarea/lib.php
mod/feedback/item/textfield/lib.php
mod/feedback/lib.php
mod/folder/edit.php
mod/forum/rsslib.php
mod/forum/subscribe.php
pix/u/f3.png [new file with mode: 0644]
question/type/essay/db/upgrade.php
question/type/essay/renderer.php
question/type/essay/version.php
theme/afterburner/config.php
theme/anomaly/config.php
theme/arialist/config.php
theme/base/config.php
theme/boxxie/config.php
theme/boxxie/style/boilerplate.css [deleted file]
theme/canvas/config.php
theme/formal_white/config.php
theme/formal_white/style/formal_white.css
theme/formfactor/config.php
theme/leatherbound/config.php
theme/magazine/config.php
theme/serenity/layout/embedded.php [deleted file]
theme/serenity/layout/frontpage.php [deleted file]
theme/serenity/layout/general.php [deleted file]
theme/splash/config.php
theme/standardold/config.php
theme/upgrade.txt
version.php

index 7bc8f90..a1e4a1c 100644 (file)
@@ -30,6 +30,7 @@
 
 /// If we can find the Shibboleth attribute, save it in session and return to main login page
     if (!empty($_SERVER[$pluginconfig->user_attribute])) {    // Shibboleth auto-login
+        $frm = new stdClass();
         $frm->username = strtolower($_SERVER[$pluginconfig->user_attribute]);
         $frm->password = substr(base64_encode($_SERVER[$pluginconfig->user_attribute]),0,8);
         // The random password consists of the first 8 letters of the base 64 encoded user ID
index e8831d7..06674ac 100644 (file)
@@ -135,6 +135,7 @@ class restore_final_task extends restore_task {
         $rules[] = new restore_log_rule('course', 'report outline', 'report/outline/index.php?id={course}', '{course}');
         $rules[] = new restore_log_rule('course', 'report participation', 'report/participation/index.php?id={course}', '{course}');
         $rules[] = new restore_log_rule('course', 'report stats', 'report/stats/index.php?id={course}', '{course}');
+        $rules[] = new restore_log_rule('course', 'view section', 'view.php?id={course}&section={course_sectionnumber}', '{course}');
 
         // module 'user' rules
         $rules[] = new restore_log_rule('user', 'view', 'view.php?id={user}&course={course}', '{user}');
index 4d610e5..d87cdb9 100644 (file)
@@ -1047,6 +1047,7 @@ class restore_section_structure_step extends restore_structure_step {
         global $CFG, $DB;
         $data = (object)$data;
         $oldid = $data->id; // We'll need this later
+        $oldsection = $data->number;
 
         $restorefiles = false;
 
@@ -1099,10 +1100,12 @@ class restore_section_structure_step extends restore_structure_step {
 
             $DB->update_record('course_sections', $section);
             $newitemid = $secrec->id;
+            $oldsection = $secrec->section;
         }
 
         // Annotate the section mapping, with restorefiles option if needed
         $this->set_mapping('course_section', $oldid, $newitemid, $restorefiles);
+        $this->set_mapping('course_sectionnumber', $oldsection, $section->section, $restorefiles);
 
         // set the new course_section id in the task
         $this->task->set_sectionid($newitemid);
@@ -2541,7 +2544,7 @@ class restore_module_structure_step extends restore_structure_step {
 
         $data = (object)$data;
         $oldid = $data->id;
-
+        $oldsection = $data->sectionnumber;
         $this->task->set_old_moduleversion($data->version);
 
         $data->course = $this->task->get_courseid();
@@ -2568,6 +2571,7 @@ class restore_module_structure_step extends restore_structure_step {
                 'course' => $this->get_courseid(),
                 'section' => 1);
             $data->section = $DB->insert_record('course_sections', $sectionrec); // section 1
+            $this->set_mapping('course_sectionnumber', $oldsection, $sectionrec->section, $restorefiles);
         }
         $data->groupingid= $this->get_mappingid('grouping', $data->groupingid);      // grouping
         if (!$CFG->enablegroupmembersonly) {                                         // observe groupsmemberonly
index d25c794..94a7a87 100644 (file)
@@ -315,6 +315,7 @@ abstract class backup_cron_automated_helper {
      */
     public static function launch_automated_backup($course, $starttime, $userid) {
 
+        $outcome = true;
         $config = get_config('backup');
         $bc = new backup_controller(backup::TYPE_1COURSE, $course->id, backup::FORMAT_MOODLE, backup::INTERACTIVE_NO, backup::MODE_AUTOMATED, $userid);
 
@@ -347,7 +348,7 @@ abstract class backup_cron_automated_helper {
 
             $bc->set_status(backup::STATUS_AWAITING);
 
-            $outcome = $bc->execute_plan();
+            $bc->execute_plan();
             $results = $bc->get_results();
             $file = $results['backup_destination'];
             $dir = $config->backup_auto_destination;
@@ -363,16 +364,17 @@ abstract class backup_cron_automated_helper {
                 }
             }
 
-            $outcome = true;
-        } catch (backup_exception $e) {
-            $bc->log('backup_auto_failed_on_course', backup::LOG_WARNING, $course->shortname);
+        } catch (moodle_exception $e) {
+            $bc->log('backup_auto_failed_on_course', backup::LOG_ERROR, $course->shortname); // Log error header.
+            $bc->log('Exception: ' . $e->errorcode, backup::LOG_ERROR, $e->a, 1); // Log original exception problem.
+            $bc->log('Debug: ' . $e->debuginfo, backup::LOG_DEBUG, null, 1); // Log original debug information.
             $outcome = false;
         }
 
         $bc->destroy();
         unset($bc);
 
-        return true;
+        return $outcome;
     }
 
     /**
index 8e07373..648f87e 100644 (file)
@@ -2995,6 +2995,8 @@ function move_section($course, $section, $move) {
         }
         $n++;
     }
+    // After moving section, rebuild course cache.
+    rebuild_course_cache($course->id, true);
     return true;
 }
 
index a7b1784..de37981 100644 (file)
 
     require_once($CFG->dirroot.'/calendar/lib.php');    /// This is after login because it needs $USER
 
-    //TODO: danp do we need different urls?
-    add_to_log($course->id, 'course', 'view', "view.php?id=$course->id", "$course->id");
+    $logparam = 'id='. $course->id;
+    $loglabel = 'view';
+    $infoid = $course->id;
+    if(!empty($section)) {
+        $logparam .= '&section='. $section;
+        $loglabel = 'view section';
+        $sectionparams = array('course' => $course->id, 'section' => $section);
+        if ($coursesections = $DB->get_record('course_sections', $sectionparams, 'id', MUST_EXIST)) {
+            $infoid = $coursesections->id;
+    }
+    }
+    add_to_log($course->id, 'course', $loglabel, "view.php?". $logparam, $infoid);
 
     $course->format = clean_param($course->format, PARAM_ALPHA);
     if (!file_exists($CFG->dirroot.'/course/format/'.$course->format.'/format.php')) {
index 012355e..a8b293a 100644 (file)
@@ -119,6 +119,13 @@ YUI.add('moodle-course-dragdrop', function(Y) {
             drag.get('dragNode').addClass(CSS.COURSECONTENT);
         },
 
+        drag_dropmiss : function(e) {
+            // Missed the target, but we assume the user intended to drop it
+            // on the last last ghost node location, e.drag and e.drop should be
+            // prepared by global_drag_dropmiss parent so simulate drop_hit(e).
+            this.drop_hit(e);
+        },
+
         drop_hit : function(e) {
             var drag = e.drag;
             // Get a reference to our drag node
@@ -309,6 +316,13 @@ YUI.add('moodle-course-dragdrop', function(Y) {
             drag.get('dragNode').all('img.iconsmall').setStyle('vertical-align', 'baseline');
         },
 
+        drag_dropmiss : function(e) {
+            // Missed the target, but we assume the user intended to drop it
+            // on the last last ghost node location, e.drag and e.drop should be
+            // prepared by global_drag_dropmiss parent so simulate drop_hit(e).
+            this.drop_hit(e);
+        },
+
         drop_hit : function(e) {
             var drag = e.drag;
             // Get a reference to our drag node
index e1937be..9d1bda9 100644 (file)
@@ -32,16 +32,56 @@ require_once $CFG->libdir.'/gradelib.php';
  * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 class graded_users_iterator {
-    public $course;
-    public $grade_items;
-    public $groupid;
-    public $users_rs;
-    public $grades_rs;
-    public $gradestack;
-    public $sortfield1;
-    public $sortorder1;
-    public $sortfield2;
-    public $sortorder2;
+
+    /**
+     * The couse whose users we are interested in
+     */
+    protected $course;
+
+    /**
+     * An array of grade items or null if only user data was requested
+     */
+    protected $grade_items;
+
+    /**
+     * The group ID we are interested in. 0 means all groups.
+     */
+    protected $groupid;
+
+    /**
+     * A recordset of graded users
+     */
+    protected $users_rs;
+
+    /**
+     * A recordset of user grades (grade_grade instances)
+     */
+    protected $grades_rs;
+
+    /**
+     * Array used when moving to next user while iterating through the grades recordset
+     */
+    protected $gradestack;
+
+    /**
+     * The first field of the users table by which the array of users will be sorted
+     */
+    protected $sortfield1;
+
+    /**
+     * Should sortfield1 be ASC or DESC
+     */
+    protected $sortorder1;
+
+    /**
+     * The second field of the users table by which the array of users will be sorted
+     */
+    protected $sortfield2;
+
+    /**
+     * Should sortfield2 be ASC or DESC
+     */
+    protected $sortorder2;
 
     /**
      * Should users whose enrolment has been suspended be ignored?
@@ -59,7 +99,7 @@ class graded_users_iterator {
      * @param string $sortfield2 The second field of the users table by which the array of users will be sorted
      * @param string $sortorder2 The order in which the second sorting field will be sorted (ASC or DESC)
      */
-    public function graded_users_iterator($course, $grade_items=null, $groupid=0,
+    public function __construct($course, $grade_items=null, $groupid=0,
                                           $sortfield1='lastname', $sortorder1='ASC',
                                           $sortfield2='firstname', $sortorder2='ASC') {
         $this->course      = $course;
@@ -75,6 +115,7 @@ class graded_users_iterator {
 
     /**
      * Initialise the iterator
+     *
      * @return boolean success
      */
     public function init() {
@@ -177,7 +218,7 @@ class graded_users_iterator {
      * Returns information about the next user
      * @return mixed array of user info, all grades and feedback or null when no more users found
      */
-    function next_user() {
+    public function next_user() {
         if (!$this->users_rs) {
             return false; // no users present
         }
@@ -244,10 +285,9 @@ class graded_users_iterator {
     }
 
     /**
-     * Close the iterator, do not forget to call this function.
-     * @return void
+     * Close the iterator, do not forget to call this function
      */
-    function close() {
+    public function close() {
         if ($this->users_rs) {
             $this->users_rs->close();
             $this->users_rs = null;
@@ -273,23 +313,23 @@ class graded_users_iterator {
 
 
     /**
-     * _push
+     * Add a grade_grade instance to the grade stack
      *
      * @param grade_grade $grade Grade object
      *
      * @return void
      */
-    function _push($grade) {
+    private function _push($grade) {
         array_push($this->gradestack, $grade);
     }
 
 
     /**
-     * _pop
+     * Remove a grade_grade instance from the grade stack
      *
-     * @return object current grade object
+     * @return grade_grade current grade object
      */
-    function _pop() {
+    private function _pop() {
         global $DB;
         if (empty($this->gradestack)) {
             if (empty($this->grades_rs) || !$this->grades_rs->valid()) {
index f404e01..f0475f6 100644 (file)
@@ -38,6 +38,7 @@ global $DB; // TODO: this is a hack, we should really do something with the SQL
 $logs = array(
     array('module'=>'course', 'action'=>'user report', 'mtable'=>'user', 'field'=>$DB->sql_concat('firstname', "' '" , 'lastname')),
     array('module'=>'course', 'action'=>'view', 'mtable'=>'course', 'field'=>'fullname'),
+    array('module'=>'course', 'action'=>'view section', 'mtable'=>'course_sections', 'field'=>'COALESCE(name, section)'),
     array('module'=>'course', 'action'=>'update', 'mtable'=>'course', 'field'=>'fullname'),
     array('module'=>'course', 'action'=>'enrol', 'mtable'=>'course', 'field'=>'fullname'), // there should be some way to store user id of the enrolled user!
     array('module'=>'course', 'action'=>'unenrol', 'mtable'=>'course', 'field'=>'fullname'), // there should be some way to store user id of the enrolled user!
index c74c724..2c75116 100644 (file)
@@ -648,5 +648,42 @@ function xmldb_main_upgrade($oldversion) {
         upgrade_main_savepoint(true, 2012052100.00);
     }
 
+    if ($oldversion < 2012052500.03) { // fix invalid course_completion_records MDL-27368
+        //first get all instances of duplicate records
+        $sql = 'SELECT userid, course FROM {course_completions} WHERE (deleted IS NULL OR deleted <> 1) GROUP BY userid, course HAVING (count(id) > 1)';
+        $duplicates = $DB->get_recordset_sql($sql, array());
+
+        foreach ($duplicates as $duplicate) {
+            $pointer = 0;
+            //now get all the records for this user/course
+            $sql = 'userid = ? AND course = ? AND (deleted IS NULL OR deleted <> 1)';
+            $completions = $DB->get_records_select('course_completions', $sql,
+                array($duplicate->userid, $duplicate->course), 'timecompleted DESC, timestarted DESC');
+            $needsupdate = false;
+            $origcompletion = null;
+            foreach ($completions as $completion) {
+                $pointer++;
+                if ($pointer === 1) { //keep 1st record but delete all others.
+                    $origcompletion = $completion;
+                } else {
+                    //we need to keep the "oldest" of all these fields as the valid completion record.
+                    $fieldstocheck = array('timecompleted', 'timestarted', 'timeenrolled');
+                    foreach ($fieldstocheck as $f) {
+                        if ($origcompletion->$f > $completion->$f) {
+                            $origcompletion->$f = $completion->$f;
+                            $needsupdate = true;
+                        }
+                    }
+                    $DB->delete_records('course_completions', array('id'=>$completion->id));
+                }
+            }
+            if ($needsupdate) {
+                $DB->update_record('course_completions', $origcompletion);
+            }
+        }
+
+        // Main savepoint reached
+        upgrade_main_savepoint(true, 2012052500.03);
+    }
     return true;
 }
index aa46e62..302ee9b 100644 (file)
@@ -3612,7 +3612,7 @@ function file_pluginfile($relativepath, $forcedownload, $preview = null) {
             }
 
             // fix file name automatically
-            if ($filename !== 'f1' and $filename !== 'f2') {
+            if ($filename !== 'f1' and $filename !== 'f2' and $filename !== 'f3') {
                 $filename = 'f1';
             }
 
@@ -3625,20 +3625,28 @@ function file_pluginfile($relativepath, $forcedownload, $preview = null) {
                 redirect($theme->pix_url('u/'.$filename, 'moodle')); // intentionally not cached
             }
 
-            if (!$file = $fs->get_file($context->id, 'user', 'icon', 0, '/', $filename.'/.png')) {
-                if (!$file = $fs->get_file($context->id, 'user', 'icon', 0, '/', $filename.'/.jpg')) {
-                    // bad reference - try to prevent future retries as hard as possible!
-                    if ($user = $DB->get_record('user', array('id'=>$context->instanceid), 'id, picture')) {
-                        if ($user->picture == 1 or $user->picture > 10) {
-                            $DB->set_field('user', 'picture', 0, array('id'=>$user->id));
+            if (!$file = $fs->get_file($context->id, 'user', 'icon', 0, '/', $filename.'.png')) {
+                if (!$file = $fs->get_file($context->id, 'user', 'icon', 0, '/', $filename.'.jpg')) {
+                    if ($filename === 'f3') {
+                        // f3 512x512px was introduced in 2.3, there might be only the smaller version.
+                        if (!$file = $fs->get_file($context->id, 'user', 'icon', 0, '/', 'f1.png')) {
+                            $file = $fs->get_file($context->id, 'user', 'icon', 0, '/', 'f1.jpg');
                         }
                     }
-                    // no redirect here because it is not cached
-                    $theme = theme_config::load($themename);
-                    $imagefile = $theme->resolve_image_location('u/'.$filename, 'moodle');
-                    send_file($imagefile, basename($imagefile), 60*60*24*14);
                 }
             }
+            if (!$file) {
+                // bad reference - try to prevent future retries as hard as possible!
+                if ($user = $DB->get_record('user', array('id'=>$context->instanceid), 'id, picture')) {
+                    if ($user->picture > 0) {
+                        $DB->set_field('user', 'picture', 0, array('id'=>$user->id));
+                    }
+                }
+                // no redirect here because it is not cached
+                $theme = theme_config::load($themename);
+                $imagefile = $theme->resolve_image_location('u/'.$filename, 'moodle');
+                send_file($imagefile, basename($imagefile), 60*60*24*14);
+            }
 
             send_stored_file($file, 60*60*24*365, 0, false, array('preview' => $preview)); // enable long caching, there are many images on each page
 
index 5fac726..9f0a3c2 100644 (file)
@@ -1260,6 +1260,8 @@ class file_storage {
             $filerecord->timemodified = $now;
         }
 
+        $transaction = $DB->start_delegated_transaction();
+
         // Insert file reference record.
         try {
             $referencerecord = new stdClass;
@@ -1292,6 +1294,8 @@ class file_storage {
 
         $this->create_directory($filerecord->contextid, $filerecord->component, $filerecord->filearea, $filerecord->itemid, $filerecord->filepath, $filerecord->userid);
 
+        $transaction->allow_commit();
+
         // Adding repositoryid and reference to file record to create stored_file instance
         $filerecord->repositoryid = $repositoryid;
         $filerecord->reference = $reference;
index a17d45f..c936716 100644 (file)
@@ -205,6 +205,8 @@ class stored_file {
         // Remove repository info.
         $this->repository = null;
 
+        $transaction = $DB->start_delegated_transaction();
+
         // Remove reference info from DB.
         $DB->delete_records('files_reference', array('id'=>$this->file_record->referencefileid));
 
@@ -216,6 +218,8 @@ class stored_file {
         $filerecord->referencefileid = null;
         $this->update($filerecord);
 
+        $transaction->allow_commit();
+
         // unset object variable
         unset($this->file_record->repositoryid);
         unset($this->file_record->reference);
@@ -247,6 +251,9 @@ class stored_file {
      */
     public function delete() {
         global $DB;
+
+        $transaction = $DB->start_delegated_transaction();
+
         // If other files referring to this file, we need convert them
         if ($files = $this->fs->get_references_by_storedfile($this)) {
             foreach ($files as $file) {
@@ -256,6 +263,9 @@ class stored_file {
         // Now delete file records in DB
         $DB->delete_records('files', array('id'=>$this->file_record->id));
         $DB->delete_records('files_reference', array('id'=>$this->file_record->referencefileid));
+
+        $transaction->allow_commit();
+
         // moves pool file to trash if content not needed any more
         $this->fs->deleted_file_cleanup($this->file_record->contenthash);
         return true; // BC only
index 68d891a..b4e4918 100644 (file)
@@ -119,6 +119,7 @@ function process_new_icon($context, $component, $filearea, $itemid, $originalfil
     $image->height = $imageinfo[1];
     $image->type   = $imageinfo[2];
 
+    $t = null;
     switch ($image->type) {
         case IMAGETYPE_GIF:
             if (function_exists('imagecreatefromgif')) {
@@ -127,6 +128,11 @@ function process_new_icon($context, $component, $filearea, $itemid, $originalfil
                 debugging('GIF not supported on this server');
                 return false;
             }
+            // Guess transparent colour from GIF.
+            $transparent = imagecolortransparent($im);
+            if ($transparent != -1) {
+                $t = imagecolorsforindex($im, $transparent);
+            }
             break;
         case IMAGETYPE_JPEG:
             if (function_exists('imagecreatefromjpeg')) {
@@ -166,19 +172,37 @@ function process_new_icon($context, $component, $filearea, $itemid, $originalfil
     if (function_exists('imagecreatetruecolor') and $CFG->gdversion >= 2) {
         $im1 = imagecreatetruecolor(100, 100);
         $im2 = imagecreatetruecolor(35, 35);
-        if ($image->type == IMAGETYPE_PNG and $imagefnc === 'imagepng') {
+        $im3 = imagecreatetruecolor(512, 512);
+        if ($image->type != IMAGETYPE_JPEG and $imagefnc === 'imagepng') {
+            if ($t) {
+                // Transparent GIF hacking...
+                $transparentcolour = imagecolorallocate($im1 , $t['red'] , $t['green'] , $t['blue']);
+                imagecolortransparent($im1 , $transparentcolour);
+                $transparentcolour = imagecolorallocate($im2 , $t['red'] , $t['green'] , $t['blue']);
+                imagecolortransparent($im2 , $transparentcolour);
+                $transparentcolour = imagecolorallocate($im3 , $t['red'] , $t['green'] , $t['blue']);
+                imagecolortransparent($im3 , $transparentcolour);
+            }
+
             imagealphablending($im1, false);
             $color = imagecolorallocatealpha($im1, 0, 0,  0, 127);
             imagefill($im1, 0, 0,  $color);
             imagesavealpha($im1, true);
+
             imagealphablending($im2, false);
             $color = imagecolorallocatealpha($im2, 0, 0,  0, 127);
             imagefill($im2, 0, 0,  $color);
             imagesavealpha($im2, true);
+
+            imagealphablending($im3, false);
+            $color = imagecolorallocatealpha($im3, 0, 0,  0, 127);
+            imagefill($im3, 0, 0,  $color);
+            imagesavealpha($im3, true);
         }
     } else {
         $im1 = imagecreate(100, 100);
         $im2 = imagecreate(35, 35);
+        $im3 = imagecreate(512, 512);
     }
 
     $cx = $image->width / 2;
@@ -192,6 +216,7 @@ function process_new_icon($context, $component, $filearea, $itemid, $originalfil
 
     imagecopybicubic($im1, $im, 0, 0, $cx - $half, $cy - $half, 100, 100, $half * 2, $half * 2);
     imagecopybicubic($im2, $im, 0, 0, $cx - $half, $cy - $half, 35, 35, $half * 2, $half * 2);
+    imagecopybicubic($im3, $im, 0, 0, $cx - $half, $cy - $half, 512, 512, $half * 2, $half * 2);
 
     $fs = get_file_storage();
 
@@ -220,6 +245,17 @@ function process_new_icon($context, $component, $filearea, $itemid, $originalfil
     $icon['filename'] = 'f2'.$imageext;
     $fs->create_file_from_string($icon, $data);
 
+    ob_start();
+    if (!$imagefnc($im3, NULL, $quality, $filters)) {
+        ob_end_clean();
+        $fs->delete_area_files($context->id, $component, $filearea, $itemid);
+        return false;
+    }
+    $data = ob_get_clean();
+    imagedestroy($im3);
+    $icon['filename'] = 'f3'.$imageext;
+    $fs->create_file_from_string($icon, $data);
+
     return $file1->get_id();
 }
 
index 82bf053..1640f14 100644 (file)
@@ -115,7 +115,7 @@ class calc_formula {
      * @param string $formula
      * @return string localised formula
      */
-    function localize($formula) {
+    public static function localize($formula) {
         $formula = str_replace('.', '$', $formula); // temp placeholder
         $formula = str_replace(',', get_string('listsep', 'langconfig'), $formula);
         $formula = str_replace('$', get_string('decsep', 'langconfig'), $formula);
@@ -127,7 +127,7 @@ class calc_formula {
      * @param string $formula localised formula
      * @return string
      */
-    function unlocalize($formula) {
+    public static function unlocalize($formula) {
         $formula = str_replace(get_string('decsep', 'langconfig'), '$', $formula);
         $formula = str_replace(get_string('listsep', 'langconfig'), ',', $formula);
         $formula = str_replace('$', '.', $formula); // temp placeholder
index 514eac9..4bd0673 100644 (file)
@@ -321,6 +321,9 @@ class user_picture implements renderable {
         } else if ($this->size === true or $this->size == 1) {
             $filename = 'f1';
             $size = 100;
+        } else if ($this->size > 100) {
+            $filename = 'f3';
+            $size = (int)$this->size;
         } else if ($this->size >= 50) {
             $filename = 'f1';
             $size = (int)$this->size;
index 35fc12e..8555f32 100644 (file)
@@ -167,6 +167,13 @@ YUI.add('moodle-core-blocks', function(Y) {
             this.dragsourceregion = null;
         },
 
+        drag_dropmiss : function(e) {
+            // Missed the target, but we assume the user intended to drop it
+            // on the last last ghost node location, e.drag and e.drop should be
+            // prepared by global_drag_dropmiss parent so simulate drop_hit(e).
+            this.drop_hit(e);
+        },
+
         drop_hit : function(e) {
             var drag = e.drag;
             // Get a reference to our drag node
index 930f600..76cadf5 100644 (file)
@@ -15,6 +15,7 @@ YUI.add('moodle-core-dragdrop', function(Y) {
         samenodeclass : null,
         parentnodeclass : null,
         groups : [],
+        lastdroptarget : null,
         initializer : function(params) {
             // Listen for all drag:start events
             Y.DD.DDM.on('drag:start', this.global_drag_start, this);
@@ -26,6 +27,8 @@ YUI.add('moodle-core-dragdrop', function(Y) {
             Y.DD.DDM.on('drop:over', this.global_drop_over, this);
             // Listen for all drop:hit events
             Y.DD.DDM.on('drop:hit', this.global_drop_hit, this);
+            // Listen for all drop:miss events
+            Y.DD.DDM.on('drag:dropmiss', this.global_drag_dropmiss, this);
         },
 
         get_drag_handle: function(title, classname, iconclass) {
@@ -66,14 +69,23 @@ YUI.add('moodle-core-dragdrop', function(Y) {
             return new M.core.exception(e);
         },
 
+        in_group: function(target) {
+            var ret = false;
+            Y.each(this.groups, function(v, k) {
+                if (target._groups[v]) {
+                    ret = true;
+                }
+            }, this);
+            return ret;
+        },
         /*
          * Drag-dropping related functions
          */
         global_drag_start : function(e) {
             // Get our drag object
             var drag = e.target;
-            // Check that drop object belong to correct group
-            if (!drag.target.inGroup(this.groups)) {
+            // Check that drag object belongs to correct group
+            if (!this.in_group(drag)) {
                 return;
             }
             // Set some general styles here
@@ -89,8 +101,8 @@ YUI.add('moodle-core-dragdrop', function(Y) {
 
         global_drag_end : function(e) {
             var drag = e.target;
-            // Check that drop object belong to correct group
-            if (!drag.target.inGroup(this.groups)) {
+            // Check that drag object belongs to correct group
+            if (!this.in_group(drag)) {
                 return;
             }
             //Put our general styles back
@@ -103,8 +115,8 @@ YUI.add('moodle-core-dragdrop', function(Y) {
 
         global_drag_drag : function(e) {
             var drag = e.target;
-            // Check that drop object belong to correct group
-            if (!drag.target.inGroup(this.groups)) {
+            // Check that drag object belongs to correct group
+            if (!this.in_group(drag)) {
                 return;
             }
             //Get the last y point
@@ -130,6 +142,8 @@ YUI.add('moodle-core-dragdrop', function(Y) {
             //Get a reference to our drag and drop nodes
             var drag = e.drag.get('node');
             var drop = e.drop.get('node');
+            // Save last drop target for the case of missed target processing
+            this.lastdroptarget = e.drop;
             //Are we dropping on the same node?
             if (drop.hasClass(this.samenodeclass)) {
                 //Are we not going up?
@@ -149,6 +163,19 @@ YUI.add('moodle-core-dragdrop', function(Y) {
             this.drop_over(e);
         },
 
+        global_drag_dropmiss : function(e) {
+            // drag:dropmiss does not have e.drag and e.drop properties
+            // we substitute them for the ease of use. For e.drop we use,
+            // this.lastdroptarget (ghost node we use for indicating where to drop)
+            e.drag = e.target;
+            // Check that drop object belong to correct group
+            if (!e.drag.target.inGroup(this.groups)) {
+                return;
+            }
+            e.drop = this.lastdroptarget;
+            this.drag_dropmiss(e);
+        },
+
         global_drop_hit : function(e) {
             // Check that drop object belong to correct group
             if (!e.drop.inGroup(this.groups)) {
@@ -163,6 +190,7 @@ YUI.add('moodle-core-dragdrop', function(Y) {
         drag_start : function(e) {},
         drag_end : function(e) {},
         drag_drag : function(e) {},
+        drag_dropmiss : function(e) {},
         drop_over : function(e) {},
         drop_hit : function(e) {}
     }, {
index f737bda..5d29b71 100644 (file)
@@ -38,74 +38,39 @@ $string['pluginname'] = 'Book';
 $string['pluginadministration'] = 'Book administration';
 
 $string['toc'] = 'Table of contents';
-$string['faq'] = 'Book FAQ';
-$string['faq_help'] = '
-*Why only two levels?*
-
-Two levels are generally enough for all books, three levels would lead to poorly structured documents. Book module is designed for
-creation of short multipage study materials. It is usually better to use PDF format for longer documents. The easiest way to create PDFs are
-virtual printers (see
-<a  href="http://sector7g.wurzel6.de/pdfcreator/index_en.htm"  target="_blank">PDFCreator</a>,
-<a  href="http://fineprint.com/products/pdffactory/index.html"  target="_blank">PDFFactory</a>,
-<a  href="http://www.adobe.com/products/acrobatstd/main.html"  target="_blank">Adobe Acrobat</a>,
-etc.).
-
-*Can students edit books?*
-
-Only teachers can create and edit books. There are no plans to implement student editing for books, but somebody may create something
-similar for students (Portfolio?). The main reason is to keep Book module as simple as possible.
-
-*How do I search the books?*
-
-At present there is only one way, use browser\'s search capability in print page. Global searching is now possible only in Moodle forums.
-It would be nice to have global searching for all resources including books, any volunteers?
-
-*My titles do not fit on one line.*
-
-Either rephrase your titles or ask your site admin to change TOC
-width. It is defined globally for all books in module configuration
-page.';
-
 $string['customtitles'] = 'Custom titles';
-$string['customtitles_help'] = 'Chapter titles are displayed automatically only in TOC.';
+$string['customtitles_help'] = 'Normally the chapter title is displayed in the table of contents (TOC) AND as a heading above the content.
 
+If the custom titles checkbox is ticked, the chapter title is NOT displayed as a heading above the content. A different title (perhaps longer than the chapter title) may be entered as part of the content.';
 $string['chapters'] = 'Chapters';
 $string['editingchapter'] = 'Editing chapter';
 $string['chaptertitle'] = 'Chapter title';
 $string['content'] = 'Content';
 $string['subchapter'] = 'Subchapter';
-
-$string['numbering'] = 'Chapter numbering';
-$string['numbering_help'] = '* None - chapter and subchapter titles are not formatted at all, use if you want to define special numbering styles. For example letters: in chapter title type "A First Chapter", "A.1 Some Subchapter",...
-* Numbers - chapters and subchapters are numbered (1, 1.1, 1.2, 2, ...)
-* Bullets - subchapters are indented and displayed with bullets
-* Indented - subchapters are indented';
-
+$string['numbering'] = 'Chapter formatting';
+$string['numbering_help'] = '* None - Chapter and subchapter titles have no formatting
+* Numbers - Chapters and subchapter titles are numbered 1, 1.1, 1.2, 2, ...
+* Bullets - Subchapters are indented and displayed with bullets in the table of contents
+* Indented - Subchapters are indented in the table of contents';
 $string['numbering0'] = 'None';
 $string['numbering1'] = 'Numbers';
 $string['numbering2'] = 'Bullets';
 $string['numbering3'] = 'Indented';
-$string['numberingoptions'] = 'Available numbering options';
-$string['numberingoptions_help'] = 'Select numbering options that should be available when creating new books.';
-
+$string['numberingoptions'] = 'Available options for chapter formatting';
+$string['numberingoptions_desc'] = 'Options for displaying chapters and subchapters in the table of contents';
 $string['chapterscount'] = 'Chapters';
-
 $string['addafter'] = 'Add new chapter';
 $string['confchapterdelete'] = 'Do you really want to delete this chapter?';
 $string['confchapterdeleteall'] = 'Do you really want to delete this chapter and all its subchapters?';
-
 $string['top'] = 'top';
-
 $string['navprev'] = 'Previous';
 $string['navnext'] = 'Next';
 $string['navexit'] = 'Exit book';
-
 $string['book:addinstance'] = 'Add a new book';
 $string['book:read'] = 'Read book';
 $string['book:edit'] = 'Edit book chapters';
 $string['book:viewhiddenchapters'] = 'View hidden book chapters';
-
-$string['errorchapter'] = 'Error reading book chapter.';
+$string['errorchapter'] = 'Error reading chapter of book.';
 
 $string['page-mod-book-x'] = 'Any book module page';
 
index 96f9f45..238913d 100644 (file)
@@ -194,12 +194,6 @@ function book_add_fake_block($chapters, $chapter, $book, $cm, $edit) {
 
     $toc = book_get_toc($chapters, $chapter, $book, $cm, $edit, 0);
 
-    if ($edit) {
-        $toc .= '<div class="book_faq">';
-        $toc .=  $OUTPUT->help_icon('faq', 'mod_book', get_string('faq', 'mod_book'));
-        $toc .=  '</div>';
-    }
-
     $bc = new block_contents();
     $bc->title = get_string('toc', 'mod_book');
     $bc->attributes['class'] = 'block';
index 810ad3c..38f87bb 100644 (file)
@@ -35,7 +35,7 @@ if ($ADMIN->fulltree) {
     $options = book_get_numbering_types();
 
     $settings->add(new admin_setting_configmultiselect('book/numberingoptions',
-        get_string('numberingoptions', 'mod_book'), get_string('numberingoptions_help', 'mod_book'),
+        get_string('numberingoptions', 'mod_book'), get_string('numberingoptions_desc', 'mod_book'),
         array_keys($options), $options));
 
 
@@ -46,4 +46,4 @@ if ($ADMIN->fulltree) {
     $settings->add(new admin_setting_configselect('book/numbering',
         get_string('numbering', 'mod_book'), '', BOOK_NUM_NUMBERS, $options));
 
-}
\ No newline at end of file
+}
index d09189d..6ddaf09 100644 (file)
 
 /* == Fake toc block == */
 
-.mod_book .book_faq {
-  font-size: 0.7em;
-}
-
 /* toc style NONE */
 .mod_book .book_toc_none {
   font-size: 0.8em;
index 2273e55..5b6a505 100644 (file)
@@ -26,5 +26,5 @@ defined('MOODLE_INTERNAL') || die;
 
 $string['exportimscp:export'] = 'Export book as IMS content package';
 $string['generateimscp'] = 'Generate IMS CP';
-$string['nochapters'] = 'No book chapters found, can not export to IMS CP.';
+$string['nochapters'] = 'No book chapters found, so unable to export to IMS CP.';
 $string['pluginname'] = 'Book IMS CP export';
index c564009..bbd811d 100644 (file)
 defined('MOODLE_INTERNAL') || die;
 
 $string['doimport'] = 'Import';
-$string['errornochapters'] = 'Can not find chapters in selected file';
-$string['import'] = 'Import from HTML';
+$string['errornochapters'] = 'Cannot find chapters in selected file';
+$string['import'] = 'Import chapter';
 $string['importhtml:import'] = 'Import chapters';
 $string['importing'] = 'Importing';
 $string['importingchapters'] = 'Importing chapters into book';
-$string['pluginname'] = 'Book HTML import';
+$string['pluginname'] = 'Book chapter import';
 $string['relinking'] = 'Relinking';
 $string['type'] = 'Type';
 $string['typeonefile'] = 'One HTML file with headings as chapters';
 $string['typezipfiles'] = 'Each HTML file represents one chapter';
-$string['typezipdirs'] = 'Each directory represents one chapter';
-$string['ziparchive'] = 'Zip archive';
-$string['ziparchive_help'] = 'Select a ZIP archive that contains HTML files and other media. File or directory names ending with "_sub" indicate subchapters. You can use copy and paste in text editor for simple HML files without embedded media.';
\ No newline at end of file
+$string['typezipdirs'] = 'Each folder represents one chapter';
+$string['ziparchive'] = 'Zip file';
+$string['ziparchive_help'] = 'Select a zip file containing HTML files and optional multimedia files and folders. To upload subchapters, add "_sub" to the end of HTML file or folder names.';
index fe07130..fbce66e 100644 (file)
@@ -25,6 +25,6 @@
 defined('MOODLE_INTERNAL') || die;
 
 $module->component = 'mod_book'; // Full name of the plugin (used for diagnostics)
-$module->version   = 2012052100; // The current module version (Date: YYYYMMDDXX)
+$module->version   = 2012052700; // The current module version (Date: YYYYMMDDXX)
 $module->requires  = 2012051900; // Requires this Moodle version
 $module->cron      = 0;          // Period for cron to check this module (secs)
index 7fee641..e4c202c 100644 (file)
@@ -507,11 +507,8 @@ if ($feedback_can_submit) {
                 //get the value
                 $frmvaluename = $feedbackitem->typ . '_'. $feedbackitem->id;
                 if (isset($savereturn)) {
-                    if (isset($formdata->{$frmvaluename})) {
-                        $value = $formdata->{$frmvaluename};
-                    } else {
-                        $value = null;
-                    }
+                    $value = isset($formdata->{$frmvaluename}) ? $formdata->{$frmvaluename} : null;
+                    $value = feedback_clean_input_value($feedbackitem, $value);
                 } else {
                     if (isset($feedbackcompletedtmp->id)) {
                         $value = feedback_get_item_value($feedbackcompletedtmp->id,
@@ -530,6 +527,7 @@ if ($feedback_can_submit) {
                     feedback_print_item_complete($feedbackitem, $value, $highlightrequired);
                     echo $OUTPUT->box_end();
                 }
+
                 echo $OUTPUT->box_end();
 
                 $lastbreakposition = $feedbackitem->position; //last item-pos (item or pagebreak)
index 25747a9..b472c09 100644 (file)
@@ -72,7 +72,7 @@ if (isset($formdata->sesskey) AND
    !isset($formdata->gonextpage) AND
    !isset($formdata->gopreviouspage)) {
 
-    $gopage = $formdata->lastpage;
+    $gopage = (int) $formdata->lastpage;
 }
 if (isset($formdata->savevalues)) {
     $savevalues = true;
@@ -441,13 +441,10 @@ if ($feedback_can_submit) {
                 echo $OUTPUT->box_start('feedback_item_box_'.$align.$dependstyle);
                 $value = '';
                 //get the value
-                $frmvaluename = $feedbackitem->typ.'_'.$feedbackitem->id;
+                $frmvaluename = $feedbackitem->typ . '_'. $feedbackitem->id;
                 if (isset($savereturn)) {
-                    if (isset($formdata->{$frmvaluename})) {
-                        $value = $formdata->{$frmvaluename};
-                    } else {
-                        $value = null;
-                    }
+                    $value = isset($formdata->{$frmvaluename}) ? $formdata->{$frmvaluename} : null;
+                    $value = feedback_clean_input_value($feedbackitem, $value);
                 } else {
                     if (isset($feedbackcompletedtmp->id)) {
                         $value = feedback_get_item_value($feedbackcompletedtmp->id,
@@ -466,6 +463,7 @@ if ($feedback_can_submit) {
                     feedback_print_item_complete($feedbackitem, $value, $highlightrequired);
                     echo $OUTPUT->box_end();
                 }
+
                 echo $OUTPUT->box_end();
 
                 $lastbreakposition = $feedbackitem->position; //last item-pos (item or pagebreak)
index 126d51e..19fa17b 100644 (file)
@@ -326,4 +326,13 @@ class feedback_item_captcha extends feedback_item_base {
     public function can_switch_require() {
         return false;
     }
+
+    /**
+     * Cleans the value coming from the user for a field of this type.
+     * @param mixed $value
+     * @return mixed
+     */
+    public function clean_input_value($value) {
+        return clean_param($value, PARAM_RAW);
+    }
 }
index 981aefd..57f1d6d 100644 (file)
@@ -128,6 +128,14 @@ abstract class feedback_item_base {
      */
     abstract public function print_item_show_value($item, $value = '');
 
+    /**
+     * cleans the userinput while submitting the form
+     *
+     * @param mixed $value
+     * @return mixed
+     */
+    abstract public function clean_input_value($value);
+
 }
 
 //a dummy class to realize pagebreaks
@@ -175,7 +183,7 @@ class feedback_item_pagebreak extends feedback_item_base {
     }
     public function can_switch_require() {
     }
+    public function clean_input_value($value) {
+    }
 
-}
-
-
+}
\ No newline at end of file
index 299fef2..b58123f 100644 (file)
@@ -388,4 +388,13 @@ class feedback_item_info extends feedback_item_base {
     public function can_switch_require() {
         return false;
     }
+
+    /**
+     * Cleans the value coming from the user for a field of this type.
+     * @param mixed $value
+     * @return mixed
+     */
+    public function clean_input_value($value) {
+        return clean_param($value, PARAM_INT);
+    }
 }
index 25c62a9..bd88d39 100644 (file)
@@ -270,4 +270,12 @@ class feedback_item_label extends feedback_item_base {
     }
     public function get_analysed($item, $groupid = false, $courseid = false) {
     }
+    /**
+     * Cleans the value coming from the user for a field of this type.
+     * @param mixed $value
+     * @return mixed
+     */
+    public function clean_input_value($value) {
+        return '';
+    }
 }
index cfba141..d48abbe 100644 (file)
@@ -826,4 +826,13 @@ class feedback_item_multichoice extends feedback_item_base {
     public function value_is_array() {
         return true;
     }
+
+    /**
+     * Cleans the value coming from the user for a field of this type.
+     * @param mixed $value
+     * @return mixed
+     */
+    public function clean_input_value($value) {
+        return clean_param_array($value, PARAM_INT);
+    }
 }
index 031f7b8..47ecedb 100644 (file)
@@ -678,4 +678,12 @@ class feedback_item_multichoicerated extends feedback_item_base {
         return true;
     }
 
+    /**
+     * Cleans the value coming from the user for a field of this type.
+     * @param mixed $value
+     * @return mixed
+     */
+    public function clean_input_value($value) {
+        return clean_param($value, PARAM_INT);
+    }
 }
index 2369413..eb2b720 100644 (file)
@@ -534,4 +534,13 @@ class feedback_item_numeric extends feedback_item_base {
     public function can_switch_require() {
         return true;
     }
+
+    /**
+     * Cleans the value coming from the user for a field of this type.
+     * @param mixed $value
+     * @return mixed
+     */
+    public function clean_input_value($value) {
+        return clean_param($value, PARAM_FLOAT);
+    }
 }
index 54df5e6..8ed9370 100644 (file)
@@ -333,4 +333,13 @@ class feedback_item_textarea extends feedback_item_base {
     public function can_switch_require() {
         return true;
     }
+
+    /**
+     * Cleans the value coming from the user for a field of this type.
+     * @param mixed $value
+     * @return mixed
+     */
+    public function clean_input_value($value) {
+        return clean_param($value, PARAM_CLEANHTML);
+    }
 }
index 4051ffb..c9a4dc6 100644 (file)
@@ -320,4 +320,13 @@ class feedback_item_textfield extends feedback_item_base {
     public function can_switch_require() {
         return true;
     }
+
+    /**
+     * Cleans the value coming from the user for a field of this type.
+     * @param mixed $value
+     * @return mixed
+     */
+    public function clean_input_value($value) {
+        return clean_param($value, PARAM_CLEANHTML);
+    }
 }
index 3c9809b..e007c4e 100644 (file)
@@ -2058,6 +2058,18 @@ function feedback_get_page_to_continue($feedbackid, $courseid = false, $guestid
 //functions to handle the values
 ////////////////////////////////////////////////
 
+/**
+ * cleans the userinput while submitting the form.
+ *
+ * @param stdClass $item The feedback item record from the database that the value needs to be cleaned against.
+ * @param mixed $value
+ * @return mixed
+ */
+function feedback_clean_input_value($item, $value) {
+    $itemobj = feedback_get_item_class($item->typ);
+    return $itemobj->clean_input_value($value);
+}
+
 /**
  * this saves the values of an completed.
  * if the param $tmp is set true so the values are saved temporary in table feedback_valuetmp.
index 9185685..0b74e47 100644 (file)
@@ -48,7 +48,7 @@ $PAGE->set_activity_record($folder);
 
 $data = new stdClass();
 $data->id = $cm->id;
-$options = array('mainfile'=>true, 'subdirs'=>1, 'maxbytes'=>$CFG->maxbytes, 'maxfiles'=>-1, 'accepted_types'=>'*');
+$options = array('subdirs'=>1, 'maxbytes'=>$CFG->maxbytes, 'maxfiles'=>-1, 'accepted_types'=>'*');
 file_prepare_standard_filemanager($data, 'files', $options, $context, 'mod_folder', 'content', 0);
 
 $mform = new mod_folder_edit_form(null, array('data'=>$data, 'options'=>$options));
index f1444af..86bf31b 100644 (file)
@@ -31,7 +31,7 @@
  * @return string the full path to the cached RSS feed directory. Null if there is a problem.
  */
 function forum_rss_get_feed($context, $args) {
-    global $CFG, $DB;
+    global $CFG, $DB, $USER;
 
     $status = true;
 
@@ -43,7 +43,7 @@ function forum_rss_get_feed($context, $args) {
 
     $forumid  = clean_param($args[3], PARAM_INT);
     $cm = get_coursemodule_from_instance('forum', $forumid, 0, false, MUST_EXIST);
-    $modcontext = get_context_instance(CONTEXT_MODULE, $cm->id);
+    $modcontext = context_module::instance($cm->id);
 
     //context id from db should match the submitted one
     if ($context->id != $modcontext->id || !has_capability('mod/forum:viewdiscussion', $modcontext)) {
@@ -58,8 +58,14 @@ function forum_rss_get_feed($context, $args) {
     //the sql that will retreive the data for the feed and be hashed to get the cache filename
     $sql = forum_rss_get_sql($forum, $cm);
 
-    //hash the sql to get the cache file name
-    $filename = rss_get_file_name($forum, $sql);
+    // Hash the sql to get the cache file name.
+    // If the forum is Q and A then we need to cache the files per user. This can
+    // have a large impact on performance, so we want to only do it on this type of forum.
+    if ($forum->type == 'qanda') {
+        $filename = rss_get_file_name($forum, $sql . $USER->id);
+    } else {
+        $filename = rss_get_file_name($forum, $sql);
+    }
     $cachedfilepath = rss_get_file_full_name('mod_forum', $filename);
 
     //Is the cache out of date?
@@ -151,7 +157,7 @@ function forum_rss_feed_discussions_sql($forum, $cm, $newsince=0) {
     $now = round(time(), -2);
     $params = array($cm->instance);
 
-    $modcontext = get_context_instance(CONTEXT_MODULE, $cm->id);
+    $modcontext = context_module::instance($cm->id);
 
     if (!empty($CFG->forum_enabletimedposts)) { /// Users must fulfill timed posts
         if (!has_capability('mod/forum:viewhiddentimedposts', $modcontext)) {
@@ -205,7 +211,7 @@ function forum_rss_feed_discussions_sql($forum, $cm, $newsince=0) {
  * @return string the SQL query to be used to get the Post details from the forum table of the database
  */
 function forum_rss_feed_posts_sql($forum, $cm, $newsince=0) {
-    $modcontext = get_context_instance(CONTEXT_MODULE, $cm->id);
+    $modcontext = context_module::instance($cm->id);
 
     //get group enforcement SQL
     $groupmode    = groups_get_activity_groupmode($cm);
@@ -290,8 +296,10 @@ function forum_rss_get_group_sql($cm, $groupmode, $currentgroup, $modcontext=nul
  *
  * @Todo MDL-31129 implement post attachment handling
  */
-function forum_rss_feed_contents($forum, $sql, $context) {
-    global $CFG, $DB;
+
+function forum_rss_feed_contents($forum, $sql) {
+    global $CFG, $DB, $USER;
+
 
     $status = true;
 
@@ -305,23 +313,45 @@ function forum_rss_feed_contents($forum, $sql, $context) {
         $isdiscussion = false;
     }
 
+    if (!$cm = get_coursemodule_from_instance('forum', $forum->id, $forum->course)) {
+        print_error('invalidcoursemodule');
+    }
+    $context = context_module::instance($cm->id);
+
     $formatoptions = new stdClass();
     $items = array();
     foreach ($recs as $rec) {
             $item = new stdClass();
             $user = new stdClass();
-            if ($isdiscussion && !empty($rec->discussionname)) {
-                $item->title = format_string($rec->discussionname);
-            } else if (!empty($rec->postsubject)) {
-                $item->title = format_string($rec->postsubject);
+
+            if ($isdiscussion && !forum_user_can_see_discussion($forum, $rec->discussionid, $context)) {
+                // This is a discussion which the user has no permission to view
+                $item->title = get_string('forumsubjecthidden', 'forum');
+                $message = get_string('forumbodyhidden', 'forum');
+                $item->author = get_string('forumauthorhidden', 'forum');
+            } else if (!$isdiscussion && !forum_user_can_see_post($forum, $rec->discussionid, $rec->postid, $USER, $cm)) {
+                // This is a post which the user has no permission to view
+                $item->title = get_string('forumsubjecthidden', 'forum');
+                $message = get_string('forumbodyhidden', 'forum');
+                $item->author = get_string('forumauthorhidden', 'forum');
             } else {
-                //we should have an item title by now but if we dont somehow then substitute something somewhat meaningful
-                $item->title = format_string($forum->name.' '.userdate($rec->postcreated,get_string('strftimedatetimeshort', 'langconfig')));
+                // The user must have permission to view
+                if ($isdiscussion && !empty($rec->discussionname)) {
+                    $item->title = format_string($rec->discussionname);
+                } else if (!empty($rec->postsubject)) {
+                    $item->title = format_string($rec->postsubject);
+                } else {
+                    //we should have an item title by now but if we dont somehow then substitute something somewhat meaningful
+                    $item->title = format_string($forum->name.' '.userdate($rec->postcreated,get_string('strftimedatetimeshort', 'langconfig')));
+                }
+                $user->firstname = $rec->userfirstname;
+                $user->lastname = $rec->userlastname;
+                $item->author = fullname($user);
+                $message = file_rewrite_pluginfile_urls($rec->postmessage, 'pluginfile.php', $context->id,
+                        'mod_forum', 'post', $rec->postid);
+                $formatoptions->trusted = $rec->posttrust;
             }
-            $user->firstname = $rec->userfirstname;
-            $user->lastname = $rec->userlastname;
-            $item->author = fullname($user);
-            $item->pubdate = $rec->postcreated;
+
             if ($isdiscussion) {
                 $item->link = $CFG->wwwroot."/mod/forum/discuss.php?d=".$rec->discussionid;
             } else {
@@ -329,8 +359,6 @@ function forum_rss_feed_contents($forum, $sql, $context) {
             }
 
             $formatoptions->trusted = $rec->posttrust;
-            $message = file_rewrite_pluginfile_urls($rec->postmessage, 'pluginfile.php', $context->id,
-                'mod_forum', 'post', $rec->postid);
             $item->description = format_text($message, $rec->postformat, $formatoptions, $forum->course);
 
             //TODO: MDL-31129 implement post attachment handling
@@ -342,6 +370,7 @@ function forum_rss_feed_contents($forum, $sql, $context) {
                     $item->attachments = array();
                 }
             }*/
+            $item->pubdate = $rec->postcreated;
 
             $items[] = $item;
         }
index 9066c8e..58a5fd5 100644 (file)
@@ -62,7 +62,7 @@ if ($user) {
     if (!has_capability('mod/forum:managesubscriptions', $context)) {
         print_error('nopermissiontosubscribe', 'forum');
     }
-    $user = $DB->get_record('user', array('id' => $user), MUST_EXIST);
+    $user = $DB->get_record('user', array('id' => $user), '*', MUST_EXIST);
 } else {
     $user = $USER;
 }
diff --git a/pix/u/f3.png b/pix/u/f3.png
new file mode 100644 (file)
index 0000000..27e3516
Binary files /dev/null and b/pix/u/f3.png differ
index 7a80f4d..6d60323 100644 (file)
@@ -40,5 +40,85 @@ function xmldb_qtype_essay_upgrade($oldversion) {
     // Moodle v2.2.0 release upgrade line
     // Put any upgrade step following this
 
+    if ($oldversion < 2011102701) {
+        // In Moodle <= 2.0 essay had both question.generalfeedback and question_answers.feedback.
+        // This was silly, and in Moodel >= 2.1 only question.generalfeedback. To avoid
+        // dataloss, we concatenate question_answers.feedback onto the end of question.generalfeedback.
+        $toupdate = $DB->get_recordset_sql("
+                SELECT q.id,
+                       q.generalfeedback,
+                       q.generalfeedbackformat,
+                       qa.feedback,
+                       qa.feedbackformat
+
+                  FROM {question} q
+                  JOIN {question_answers} qa ON qa.question = q.id
+
+                 WHERE q.qtype = 'essay'
+                   AND " . $DB->sql_isnotempty('question_answers', 'feedback', false, true));
+
+        foreach ($toupdate as $data) {
+            upgrade_set_timeout(60);
+            if ($data->generalfeedbackformat == $data->feedbackformat) {
+                $DB->set_field('question', 'generalfeedback',
+                        $data->generalfeedback . $data->feedback,
+                        array('id' => $data->id));
+
+            } else {
+                $newdata = new stdClass();
+                $newdata->id = $data->id;
+                $newdata->generalfeedback =
+                        qtype_essay_convert_to_html($data->generalfeedback, $data->generalfeedbackformat) .
+                        qtype_essay_convert_to_html($data->feedback,        $data->feedbackformat);
+                $newdata->generalfeedbackformat = FORMAT_HTML;
+                $DB->update_record('question', $newdata);
+            }
+        }
+
+        $toupdate->close();
+
+        // Essay savepoint reached.
+        upgrade_plugin_savepoint(true, 2011102701, 'qtype', 'essay');
+    }
+
+    if ($oldversion < 2011102702) {
+        // Then we delete the old question_answers rows for essay questions.
+        $DB->delete_records_select('question_answers',
+                "question IN (SELECT id FROM {question} WHERE qtype = 'essay')");
+
+        // Essay savepoint reached.
+        upgrade_plugin_savepoint(true, 2011102702, 'qtype', 'essay');
+    }
+
     return true;
 }
+
+/**
+ * Convert some content to HTML.
+ * @param string $text the content to convert to HTML
+ * @param int $oldformat One of the FORMAT_... constants.
+ */
+function qtype_essay_convert_to_html($text, $oldformat) {
+    switch ($oldformat) {
+        // Similar to format_text.
+
+        case FORMAT_PLAIN:
+            $text = s($text);
+            $text = str_replace(' ', '&nbsp; ', $text);
+            $text = nl2br($text);
+            return $text;
+
+        case FORMAT_MARKDOWN:
+            return markdown_to_html($text);
+
+        case FORMAT_MOODLE:
+            return text_to_html($text);
+
+        case FORMAT_HTML:
+            return $text;
+
+        default:
+            throw new coding_exception(
+                    'Unexpected text format when upgrading essay questions.');
+    }
+}
index afb52f8..288954f 100644 (file)
@@ -113,7 +113,9 @@ class qtype_essay_renderer extends qtype_renderer {
         $pickeroptions->itemid = $qa->prepare_response_files_draft_itemid(
                 'attachments', $options->context->id);
 
-        return form_filemanager_render($pickeroptions) . html_writer::empty_tag(
+        $fm = new form_filemanager($pickeroptions);
+        $filesrenderer = $this->page->get_renderer('core', 'files');
+        return $filesrenderer->render($fm). html_writer::empty_tag(
                 'input', array('type' => 'hidden', 'name' => $qa->get_qt_field_name('attachments'),
                 'value' => $pickeroptions->itemid));
     }
index fec2889..0b44d4b 100644 (file)
@@ -26,7 +26,7 @@
 defined('MOODLE_INTERNAL') || die();
 
 $plugin->component = 'qtype_essay';
-$plugin->version   = 2011102700;
+$plugin->version   = 2011102702;
 
 $plugin->requires  = 2011102700;
 
index f1b5859..b0e7006 100644 (file)
@@ -34,31 +34,31 @@ $THEME->layouts = array(
     'standard' => array(
         'file' => 'default.php',
         'regions' => array('side-pre', 'side-post'),
-        'defaultregion' => 'side-post',
+        'defaultregion' => 'side-pre',
     ),
     // Main course page
     'course' => array(
         'file' => 'default.php',
         'regions' => array('side-pre', 'side-post'),
-        'defaultregion' => 'side-post',
+        'defaultregion' => 'side-pre',
         'options' => array('langmenu'=>true),
     ),
     'coursecategory' => array(
         'file' => 'default.php',
         'regions' => array('side-pre', 'side-post'),
-        'defaultregion' => 'side-post',
+        'defaultregion' => 'side-pre',
     ),
     // part of course, typical for modules - default page layout if $cm specified in require_login()
     'incourse' => array(
         'file' => 'default.php',
         'regions' => array('side-pre', 'side-post'),
-        'defaultregion' => 'side-post',
+        'defaultregion' => 'side-pre',
     ),
     // The site home page.
     'frontpage' => array(
         'file' => 'default.php',
         'regions' => array('side-pre', 'side-post'),
-        'defaultregion' => 'side-post',
+        'defaultregion' => 'side-pre',
         'options' => array('langmenu'=>true),
     ),
     // Server administration scripts.
index 8b6746d..6fcbaee 100644 (file)
@@ -32,33 +32,33 @@ $THEME->layouts = array(
     'standard' => array(
         'file' => 'general.php',
         'regions' => array('side-pre', 'side-post'),
-        'defaultregion' => 'side-post',
+        'defaultregion' => 'side-pre',
         'options' => array('langmenu' => true)
     ),
     // Course page
     'course' => array(
         'file' => 'general.php',
         'regions' => array('side-pre', 'side-post'),
-        'defaultregion' => 'side-post',
+        'defaultregion' => 'side-pre',
         'options' => array('langmenu' => true)
     ),
     // Course page
     'coursecategory' => array(
         'file' => 'general.php',
         'regions' => array('side-pre', 'side-post'),
-        'defaultregion' => 'side-post',
+        'defaultregion' => 'side-pre',
         'options' => array('langmenu' => true)
     ),
     'incourse' => array(
         'file' => 'general.php',
         'regions' => array('side-pre', 'side-post'),
-        'defaultregion' => 'side-post',
+        'defaultregion' => 'side-pre',
         'options' => array('langmenu' => true)
     ),
     'frontpage' => array(
         'file' => 'general.php',
         'regions' => array('side-pre', 'side-post'),
-        'defaultregion' => 'side-post',
+        'defaultregion' => 'side-pre',
         'options' => array('langmenu' => true)
     ),
     'admin' => array(
@@ -70,13 +70,13 @@ $THEME->layouts = array(
     'mydashboard' => array(
         'file' => 'general.php',
         'regions' => array('side-pre', 'side-post'),
-        'defaultregion' => 'side-post',
+        'defaultregion' => 'side-pre',
         'options' => array('langmenu' => true)
     ),
     'mypublic' => array(
         'file' => 'general.php',
         'regions' => array('side-pre', 'side-post'),
-        'defaultregion' => 'side-post',
+        'defaultregion' => 'side-pre',
         'options' => array('langmenu' => true)
     ),
     'login' => array(
index 751523c..4de9416 100644 (file)
@@ -38,8 +38,8 @@ $THEME->name = 'arialist';
 
 
 $THEME->parents = array(
-       'canvas',
-       'base',
+    'canvas',
+    'base',
 );
 
 /////////////////////////////////////////////////////
@@ -55,8 +55,8 @@ $THEME->parents = array(
 
 $THEME->sheets = array(
     'pagelayout',
-       'core',
-       'settings',
+    'core',
+    'settings',
 );
 
 ////////////////////////////////////////////////////
@@ -65,12 +65,12 @@ $THEME->sheets = array(
 ////////////////////////////////////////////////////
 
 $THEME->parents_exclude_sheets = array(
-               'base'=>array(
-                       'pagelayout',
-               ),
-               'canvas'=>array(
-                       'pagelayout',
-               ),
+        'base'=>array(
+            'pagelayout',
+        ),
+        'canvas'=>array(
+            'pagelayout',
+        ),
 );
 
 
@@ -156,7 +156,7 @@ $THEME->layouts = array(
         'options' => array('nofooter'=>true, 'nonavbar'=>true, 'nocustommenu'=>true),
     ),
     'embedded' => array(
-       'theme' => 'canvas',
+        'theme' => 'canvas',
         'file' => 'embedded.php',
         'regions' => array(),
         'options' => array('nofooter'=>true, 'nonavbar'=>true, 'nocustommenu'=>true),
@@ -209,14 +209,14 @@ $THEME->csspostprocess = 'arialist_process_css';
 // As above but will be included in the page footer.
 ////////////////////////////////////////////////////
 
-$THEME->larrow = '&lang;';
+$THEME->larrow  = '&lang;';
 
 ////////////////////////////////////////////////////
 // Overrides the left arrow image used throughout
 // Moodle
 ////////////////////////////////////////////////////
 
-$THEME->rarrow = '&rang;';
+$THEME->rarrow  = '&rang;';
 
 ////////////////////////////////////////////////////
 // Overrides the right arrow image used throughout Moodle
index 978396c..7c9aa2d 100644 (file)
@@ -64,31 +64,31 @@ $THEME->layouts = array(
     'standard' => array(
         'file' => 'general.php',
         'regions' => array('side-pre', 'side-post'),
-        'defaultregion' => 'side-post',
+        'defaultregion' => 'side-pre',
     ),
     // Main course page
     'course' => array(
         'file' => 'general.php',
         'regions' => array('side-pre', 'side-post'),
-        'defaultregion' => 'side-post',
+        'defaultregion' => 'side-pre',
         'options' => array('langmenu'=>true),
     ),
     'coursecategory' => array(
         'file' => 'general.php',
         'regions' => array('side-pre', 'side-post'),
-        'defaultregion' => 'side-post',
+        'defaultregion' => 'side-pre',
     ),
     // part of course, typical for modules - default page layout if $cm specified in require_login()
     'incourse' => array(
         'file' => 'general.php',
         'regions' => array('side-pre', 'side-post'),
-        'defaultregion' => 'side-post',
+        'defaultregion' => 'side-pre',
     ),
     // The site home page.
     'frontpage' => array(
         'file' => 'frontpage.php',
         'regions' => array('side-pre', 'side-post'),
-        'defaultregion' => 'side-post',
+        'defaultregion' => 'side-pre',
     ),
     // Server administration scripts.
     'admin' => array(
@@ -100,14 +100,14 @@ $THEME->layouts = array(
     'mydashboard' => array(
         'file' => 'general.php',
         'regions' => array('side-pre', 'side-post'),
-        'defaultregion' => 'side-post',
+        'defaultregion' => 'side-pre',
         'options' => array('langmenu'=>true),
     ),
     // My public page
     'mypublic' => array(
         'file' => 'general.php',
         'regions' => array('side-pre', 'side-post'),
-        'defaultregion' => 'side-post',
+        'defaultregion' => 'side-pre',
     ),
     'login' => array(
         'file' => 'general.php',
index 7aff519..8c91ce3 100644 (file)
@@ -69,32 +69,32 @@ $THEME->layouts = array(
     'base' => array(
         'file' => 'general.php',
         'regions' => array('side-pre', 'side-post'),
-        'defaultregion' => 'side-post',
+        'defaultregion' => 'side-pre',
     ),
     'standard' => array(
         'file' => 'general.php',
         'regions' => array('side-pre', 'side-post'),
-        'defaultregion' => 'side-post',
+        'defaultregion' => 'side-pre',
     ),
     'course' => array(
         'file' => 'general.php',
         'regions' => array('side-pre', 'side-post'),
-        'defaultregion' => 'side-post'
+        'defaultregion' => 'side-pre'
     ),
     'coursecategory' => array(
         'file' => 'general.php',
         'regions' => array('side-pre', 'side-post'),
-        'defaultregion' => 'side-post',
+        'defaultregion' => 'side-pre',
     ),
     'incourse' => array(
         'file' => 'general.php',
         'regions' => array('side-pre', 'side-post'),
-        'defaultregion' => 'side-post',
+        'defaultregion' => 'side-pre',
     ),
     'frontpage' => array(
         'file' => 'frontpage.php',
         'regions' => array('side-pre', 'side-post'),
-        'defaultregion' => 'side-post',
+        'defaultregion' => 'side-pre',
     ),
     'admin' => array(
         'file' => 'general.php',
@@ -104,13 +104,13 @@ $THEME->layouts = array(
     'mydashboard' => array(
         'file' => 'general.php',
         'regions' => array('side-pre', 'side-post'),
-        'defaultregion' => 'side-post',
+        'defaultregion' => 'side-pre',
         'options' => array('langmenu'=>true),
     ),
     'mypublic' => array(
         'file' => 'general.php',
         'regions' => array('side-pre', 'side-post'),
-        'defaultregion' => 'side-post',
+        'defaultregion' => 'side-pre',
     ),
     'login' => array(
         'file' => 'general.php',
diff --git a/theme/boxxie/style/boilerplate.css b/theme/boxxie/style/boilerplate.css
deleted file mode 100644 (file)
index 3bf99fc..0000000
+++ /dev/null
@@ -1,147 +0,0 @@
-/* -------------------------------------------------------------- 
-  
-   Boilerplate reset.css
-   * Resets default browser CSS.
-   
--------------------------------------------------------------- */
-
-html, body, div, span, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, code, del, dfn, em, img, q, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td { margin: 0; padding: 0; border: 0; font-weight: inherit; font-style: inherit; font-size: 100%; font-family: inherit; vertical-align: baseline; }
-body { line-height: 1.5; background: #fff; margin: 0; }
-table { border-collapse: collapse; border-spacing: 0; }
-caption, th, td { text-align: left; font-weight:400; }
-blockquote:before, blockquote:after, q:before, q:after { content: ""; }
-blockquote, q { quotes: "" ""; }
-a img { border: none; }
-input,textarea { margin: 0; }
-
-/* Removes Firefox imposed outline */
-a { outline: none; }
-
-/* Clearing floats without extra markup  */
-.wrapper { display: inline-block; }
-.wrapper:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; }
-* html .wrapper { height: 1%; }
-.wrapper { display: block; }
-
-/* -------------------------------------------------------------- 
-   
-   Boilerplate typography.css
-   * Sets up some sensible default typography.
-  
--------------------------------------------------------------- */
-
-/* This is where you set your desired font size. The line-heights 
-   and vertical margins are automatically calculated from this. 
-   The percentage is of 16px (0.75 * 16px = 12px). */
-body { font-size: 85%; }
-
-
-/* Default fonts and colors. */
-body,h1,h2,h3,h4,h5,h6,p,ul,ol,dl,input,textarea { font-family: Helvetica, Arial, sans-serif; }
-
-
-/* Headings
--------------------------------------------------------------- */
-
-h1,h2,h3,h4,h5,h6 { font-weight: bold; }
-
-h1 { font-size: 2.25em; line-height: 1; margin-bottom: 0.5em; }
-h2 { font-size: 1.75em; margin-bottom: 0.5em; }
-h3 { font-size: 1.5em; line-height: 1; margin-bottom: 1em; }
-h4 { font-size: 1.2em; line-height: 1.25; margin-bottom: 1em; }
-h5 { font-size: 1em; margin-bottom: 1.5em; }
-h6 { font-size: 1em; }
-
-
-/* Text elements
--------------------------------------------------------------- */
-
-p { margin: 0 0 1em; }
-
-ul, ol { margin: 0 1.5em 1.5em 1.5em; }
-ul { list-style-type: circle; }
-ol { list-style-type: decimal; }
-
-dl { margin: 0 0 1.5em 0; }
-dl dt { font-weight: bold; }
-dl dd { margin-left: 1.5em; }
-
-abbr, acronym { border-bottom: 1px dotted #000; }
-address { margin-top: 1.5em; font-style: italic; }
-del { color: #000; }
-
-a { color: #009; text-decoration: none; }
-a:hover { text-decoration: underline; }
-
-blockquote { margin: 1.5em; }
-strong { font-weight: bold; }
-em, dfn { font-style: italic; }
-dfn { font-weight: bold; }
-pre, code { margin: 1.5em 0; white-space: pre; }
-pre, code, tt { font: 1.2em monospace; line-height: 1.5; } 
-tt { display: block; margin: 1.5em 0; line-height: 1.5; }
-
-
-/* Tables
--------------------------------------------------------------- */
-
-th { border-bottom: 2px solid #ddd; font-weight: bold; }
-th,td { padding: 4px;vertical-align: middle }
-tfoot { font-style: italic; }
-caption { background: #ffc; }
-
-
-/* Some default classes
--------------------------------------------------------------- */
-
-.small { font-size: .8em; margin-bottom: 1.875em; line-height: 1.875em; }
-.large { font-size: 1.25em; line-height:1.5em; margin-bottom: 1em; }
-.quiet { color: #999; }
-
-.hide { display: none; }
-.highlight { background: #ffc; }
-
-.top { margin-top: 0; padding-top: 0; }
-.bottom { margin-bottom: 0; padding-bottom: 0; }
-
-/* -------------------------------------------------------------- 
-   
-   Boilerplate forms.css
-   * Sets up some default styling for forms
-   
--------------------------------------------------------------- */
-
-label { font-weight: bold; }
-
-/* Fieldsets */
-fieldset { padding: 1.4em; margin: 0 0 1.5em 0; border: 1px solid #ddd; }
-legend { padding: 0 .4em; font-weight: bold; font-size: 1.2em; }
-
-/* Textareas */
-textarea { margin: 0.5em 0.5em 0 0; }
-textarea { padding: .4em; }
-
-
-/* hForm
--------------------------------------------------------------- */
-form.hform p { margin: 0 0 .5em; }
-form.hform p label { float: left; width: 100px; }
-
-form.hform p input { width: 200px; }
-form.hform p select { width: 200px; }
-
-form.hform p input.button { width: auto; }
-form.hform p input.checkbox { width: auto; }
-form.hform p input.radio { width: auto; }
-
-form.hform p.checkbox { margin-left: 100px; }
-form.hform p.checkbox label { float: none; }
-form.hform p.checkbox input { width: auto; }
-
-
-/* vForm
--------------------------------------------------------------- */
-form.vform p { margin: 0 0 .5em; }
-form.vform p label { display: block; }
-
-form.vform p.checkbox label { display: inline; }
index 1fdd596..925a72b 100644 (file)
@@ -89,32 +89,32 @@ $THEME->layouts = array(
     'base' => array(
         'file' => 'general.php',
         'regions' => array('side-pre', 'side-post'),
-        'defaultregion' => 'side-post',
+        'defaultregion' => 'side-pre',
     ),
     'standard' => array(
         'file' => 'general.php',
         'regions' => array('side-pre', 'side-post'),
-        'defaultregion' => 'side-post',
+        'defaultregion' => 'side-pre',
     ),
     'course' => array(
         'file' => 'general.php',
         'regions' => array('side-pre', 'side-post'),
-        'defaultregion' => 'side-post'
+        'defaultregion' => 'side-pre'
     ),
     'coursecategory' => array(
         'file' => 'general.php',
         'regions' => array('side-pre', 'side-post'),
-        'defaultregion' => 'side-post',
+        'defaultregion' => 'side-pre',
     ),
     'incourse' => array(
         'file' => 'general.php',
         'regions' => array('side-pre', 'side-post'),
-        'defaultregion' => 'side-post',
+        'defaultregion' => 'side-pre',
     ),
     'frontpage' => array(
         'file' => 'frontpage.php',
         'regions' => array('side-pre', 'side-post'),
-        'defaultregion' => 'side-post',
+        'defaultregion' => 'side-pre',
     ),
     'admin' => array(
         'file' => 'general.php',
@@ -124,13 +124,13 @@ $THEME->layouts = array(
     'mydashboard' => array(
         'file' => 'general.php',
         'regions' => array('side-pre', 'side-post'),
-        'defaultregion' => 'side-post',
+        'defaultregion' => 'side-pre',
         'options' => array('langmenu'=>true),
     ),
     'mypublic' => array(
         'file' => 'general.php',
         'regions' => array('side-pre', 'side-post'),
-        'defaultregion' => 'side-post',
+        'defaultregion' => 'side-pre',
     ),
     'login' => array(
         'file' => 'general.php',
index 37888ab..f537c48 100644 (file)
@@ -91,33 +91,33 @@ $THEME->layouts = array(
     'base' => array(
         'file' => 'general.php',
         'regions' => array('side-pre', 'side-post'),
-        'defaultregion' => 'side-post',
+        'defaultregion' => 'side-pre',
     ),
     'standard' => array(
         'file' => 'general.php',
         'regions' => array('side-pre', 'side-post'),
-        'defaultregion' => 'side-post',
+        'defaultregion' => 'side-pre',
     ),
     'course' => array(
         'file' => 'general.php',
         'regions' => array('side-pre', 'side-post'),
-        'defaultregion' => 'side-post',
+        'defaultregion' => 'side-pre',
         'options' => array('langmenu'=>true),
     ),
     'coursecategory' => array(
         'file' => 'general.php',
         'regions' => array('side-pre', 'side-post'),
-        'defaultregion' => 'side-post',
+        'defaultregion' => 'side-pre',
     ),
     'incourse' => array(
         'file' => 'general.php',
         'regions' => array('side-pre', 'side-post'),
-        'defaultregion' => 'side-post',
+        'defaultregion' => 'side-pre',
     ),
     'frontpage' => array(
         'file' => 'frontpage.php',
         'regions' => array('side-pre', 'side-post'),
-        'defaultregion' => 'side-post',
+        'defaultregion' => 'side-pre',
         'options' => array('langmenu'=>true),
     ),
     'admin' => array(
@@ -128,13 +128,13 @@ $THEME->layouts = array(
     'mydashboard' => array(
         'file' => 'general.php',
         'regions' => array('side-pre', 'side-post'),
-        'defaultregion' => 'side-post',
+        'defaultregion' => 'side-pre',
         'options' => array('langmenu'=>true),
     ),
     'mypublic' => array(
         'file' => 'general.php',
         'regions' => array('side-pre', 'side-post'),
-        'defaultregion' => 'side-post',
+        'defaultregion' => 'side-pre',
     ),
     'login' => array(
         'file' => 'general.php',
index d97fa46..f905a47 100644 (file)
@@ -73,22 +73,13 @@ p {margin:0}
 #page-enrol-instances .select.menujump {margin-left:0.5em;}
 
 /* environmenttable */
-.environmenttable .error {
-    background-color: red;
-}
-
-.environmenttable .warn {
-    background-color: yellow;
-}
-
-.environmenttable .ok {
-    background-color: lime;
-}
+.environmenttable .error {background-color:red;}
+.environmenttable .warn {background-color:yellow;}
+.environmenttable .ok {background-color:lime;}
 
 /* adminsettings */
-#adminsettings .form-overridden {
-    background-color: yellow;
-}
+#adminsettings .form-overridden {background-color:yellow;}
+#adminsettings .form-warning {color:red;}
 
 /* tables */
 .editcourse th,
index 25814bd..ddc32e8 100644 (file)
@@ -76,32 +76,32 @@ $THEME->layouts = array(
     'base' => array(
         'file' => 'general.php',
         'regions' => array('side-pre', 'side-post'),
-        'defaultregion' => 'side-post',
+        'defaultregion' => 'side-pre',
     ),
     'standard' => array(
         'file' => 'general.php',
         'regions' => array('side-pre', 'side-post'),
-        'defaultregion' => 'side-post',
+        'defaultregion' => 'side-pre',
     ),
     'course' => array(
         'file' => 'general.php',
         'regions' => array('side-pre', 'side-post'),
-        'defaultregion' => 'side-post'
+        'defaultregion' => 'side-pre'
     ),
     'coursecategory' => array(
         'file' => 'general.php',
         'regions' => array('side-pre', 'side-post'),
-        'defaultregion' => 'side-post',
+        'defaultregion' => 'side-pre',
     ),
     'incourse' => array(
         'file' => 'general.php',
         'regions' => array('side-pre', 'side-post'),
-        'defaultregion' => 'side-post',
+        'defaultregion' => 'side-pre',
     ),
     'frontpage' => array(
         'file' => 'frontpage.php',
         'regions' => array('side-pre', 'side-post'),
-        'defaultregion' => 'side-post',
+        'defaultregion' => 'side-pre',
     ),
     'admin' => array(
         'file' => 'general.php',
@@ -111,13 +111,13 @@ $THEME->layouts = array(
     'mydashboard' => array(
         'file' => 'general.php',
         'regions' => array('side-pre', 'side-post'),
-        'defaultregion' => 'side-post',
+        'defaultregion' => 'side-pre',
         'options' => array('langmenu'=>true),
     ),
     'mypublic' => array(
         'file' => 'general.php',
         'regions' => array('side-pre', 'side-post'),
-        'defaultregion' => 'side-post',
+        'defaultregion' => 'side-pre',
     ),
     'login' => array(
         'file' => 'general.php',
index 823f923..992a338 100644 (file)
@@ -80,32 +80,32 @@ $THEME->layouts = array(
     'base' => array(
         'file' => 'general.php',
         'regions' => array('side-pre', 'side-post'),
-        'defaultregion' => 'side-post',
+        'defaultregion' => 'side-pre',
     ),
     'standard' => array(
         'file' => 'general.php',
         'regions' => array('side-pre', 'side-post'),
-        'defaultregion' => 'side-post',
+        'defaultregion' => 'side-pre',
     ),
     'course' => array(
         'file' => 'general.php',
         'regions' => array('side-pre', 'side-post'),
-        'defaultregion' => 'side-post'
+        'defaultregion' => 'side-pre'
     ),
     'coursecategory' => array(
         'file' => 'general.php',
         'regions' => array('side-pre', 'side-post'),
-        'defaultregion' => 'side-post',
+        'defaultregion' => 'side-pre',
     ),
     'incourse' => array(
         'file' => 'general.php',
         'regions' => array('side-pre', 'side-post'),
-        'defaultregion' => 'side-post',
+        'defaultregion' => 'side-pre',
     ),
     'frontpage' => array(
         'file' => 'frontpage.php',
         'regions' => array('side-pre', 'side-post'),
-        'defaultregion' => 'side-post',
+        'defaultregion' => 'side-pre',
     ),
     'admin' => array(
         'file' => 'general.php',
@@ -115,13 +115,13 @@ $THEME->layouts = array(
     'mydashboard' => array(
         'file' => 'general.php',
         'regions' => array('side-pre', 'side-post'),
-        'defaultregion' => 'side-post',
+        'defaultregion' => 'side-pre',
         'options' => array('langmenu'=>true),
     ),
     'mypublic' => array(
         'file' => 'general.php',
         'regions' => array('side-pre', 'side-post'),
-        'defaultregion' => 'side-post',
+        'defaultregion' => 'side-pre',
     ),
     'login' => array(
         'file' => 'general.php',
index cc138f2..39e79c4 100644 (file)
@@ -49,35 +49,36 @@ $THEME->editor_sheets = array('editor');
 ////////////////////////////////////////////////////
 
 $THEME->layouts = array(
+    // Most backwards compatible layout without the blocks - this is the layout used by default
     'base' => array(
         'file' => 'general.php',
-        'regions' => array('side-pre', 'side-post'),
-        'defaultregion' => 'side-post',
+        'regions' => array(),
     ),
-    'general' => array(
+    // Standard layout with blocks, this is recommended for most pages with general information
+    'standard' => array(
         'file' => 'general.php',
         'regions' => array('side-pre', 'side-post'),
-        'defaultregion' => 'side-post',
+        'defaultregion' => 'side-pre',
     ),
     'course' => array(
         'file' => 'general.php',
         'regions' => array('side-pre', 'side-post'),
-        'defaultregion' => 'side-post'
+        'defaultregion' => 'side-pre'
     ),
     'coursecategory' => array(
         'file' => 'general.php',
         'regions' => array('side-pre', 'side-post'),
-        'defaultregion' => 'side-post',
+        'defaultregion' => 'side-pre',
     ),
     'incourse' => array(
         'file' => 'general.php',
         'regions' => array('side-pre', 'side-post'),
-        'defaultregion' => 'side-post',
+        'defaultregion' => 'side-pre',
     ),
     'frontpage' => array(
         'file' => 'frontpage.php',
         'regions' => array('side-pre', 'side-post'),
-        'defaultregion' => 'side-post',
+        'defaultregion' => 'side-pre',
     ),
     'admin' => array(
         'file' => 'general.php',
@@ -87,13 +88,13 @@ $THEME->layouts = array(
     'mydashboard' => array(
         'file' => 'general.php',
         'regions' => array('side-pre', 'side-post'),
-        'defaultregion' => 'side-post',
+        'defaultregion' => 'side-pre',
         'options' => array('langmenu'=>true),
     ),
     'mypublic' => array(
         'file' => 'general.php',
         'regions' => array('side-pre', 'side-post'),
-        'defaultregion' => 'side-post',
+        'defaultregion' => 'side-pre',
     ),
     'login' => array(
         'file' => 'general.php',
diff --git a/theme/serenity/layout/embedded.php b/theme/serenity/layout/embedded.php
deleted file mode 100644 (file)
index 9d39e02..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-<?php echo $OUTPUT->doctype() ?>
-<html <?php echo $OUTPUT->htmlattributes() ?>>
-<head>
-    <title><?php echo $PAGE->title ?></title>
-    <link rel="shortcut icon" href="<?php echo $OUTPUT->pix_url('favicon', 'theme')?>" />
-    <?php echo $OUTPUT->standard_head_html() ?>
-</head>
-<body id="<?php p($PAGE->bodyid) ?>" class="<?php p($PAGE->bodyclasses) ?>">
-<?php echo $OUTPUT->standard_top_of_body_html() ?>
-
-<div id="page">
-
-<!-- END OF HEADER -->
-
-    <div id="content" class="clearfix">
-        <?php echo $OUTPUT->main_content() ?>
-    </div>
-
-<!-- START OF FOOTER -->
-</div>
-<?php echo $OUTPUT->standard_end_of_body_html() ?>
-</body>
-</html>
\ No newline at end of file
diff --git a/theme/serenity/layout/frontpage.php b/theme/serenity/layout/frontpage.php
deleted file mode 100644 (file)
index 3c21eaa..0000000
+++ /dev/null
@@ -1,117 +0,0 @@
-<?php
-
-$hassidepre = (empty($PAGE->layout_options['noblocks']) && $PAGE->blocks->region_has_content('side-pre', $OUTPUT));
-$hassidepost = (empty($PAGE->layout_options['noblocks']) && $PAGE->blocks->region_has_content('side-post', $OUTPUT));
-
-$showsidepre = ($hassidepre && !$PAGE->blocks->region_completely_docked('side-pre', $OUTPUT));
-$showsidepost = ($hassidepost && !$PAGE->blocks->region_completely_docked('side-post', $OUTPUT));
-$custommenu = $OUTPUT->custom_menu();
-$hascustommenu = (empty($PAGE->layout_options['nocustommenu']) && !empty($custommenu));
-
-$bodyclasses = array();
-if ($showsidepre && !$showsidepost) {
-    $bodyclasses[] = 'side-pre-only';
-} else if ($showsidepost && !$showsidepre) {
-    $bodyclasses[] = 'side-post-only';
-} else if (!$showsidepost && !$showsidepre) {
-    $bodyclasses[] = 'content-only';
-}
-if ($hassidepre || $hassidepost) {
-       $bodyclasses[] = 'background';
-}
-if ($hascustommenu) {
-    $bodyclasses[] = 'has_custom_menu';
-}
-
-echo $OUTPUT->doctype() ?>
-<html <?php echo $OUTPUT->htmlattributes() ?>>
-<head>
-    <title><?php echo $PAGE->title ?></title>
-    <link rel="shortcut icon" href="<?php echo $OUTPUT->pix_url('favicon', 'theme')?>" />
-    <meta name="description" content="<?php p(strip_tags(format_text($SITE->summary, FORMAT_HTML))) ?>" />
-    <?php echo $OUTPUT->standard_head_html() ?>
-</head>
-<body id="<?php p($PAGE->bodyid) ?>" class="<?php p($PAGE->bodyclasses.' '.join(' ', $bodyclasses)) ?>">
-<?php echo $OUTPUT->standard_top_of_body_html() ?>
-
-<div id="page">
-       <div id="wrapper" class="clearfix">
-
-<!-- START OF HEADER -->
-
-    <div id="page-header" class="clearfix">
-               <div id="page-header-wrapper">
-               <h1 class="headermain"><?php echo $PAGE->heading ?></h1>
-           <div class="headermenu">
-                       <?php
-                           echo $OUTPUT->login_info();
-                       echo $OUTPUT->lang_menu();
-                           echo $PAGE->headingmenu;
-                       ?>
-               </div>
-           </div>
-    </div>
-<?php if ($hascustommenu) { ?>
-       <div id="custommenu"><?php echo $custommenu; ?></div>
-<?php } ?>
-<!-- END OF HEADER -->
-
-<!-- START OF CONTENT -->
-
-<div id="page-content-wrapper">
-    <div id="page-content">
-        <div id="region-main-box">
-            <div id="region-post-box">
-
-                <div id="region-main-wrap">
-                    <div id="region-main">
-                        <div class="region-content">
-                            <?php echo $OUTPUT->main_content() ?>
-                        </div>
-                    </div>
-                </div>
-
-                <?php if ($hassidepre) { ?>
-                <div id="region-pre" class="block-region">
-                    <div class="region-content">
-                        <?php echo $OUTPUT->blocks_for_region('side-pre') ?>
-                    </div>
-                </div>
-                <?php } ?>
-
-                <?php if ($hassidepost) { ?>
-                <div id="region-post" class="block-region">
-                    <div class="region-content">
-                        <?php echo $OUTPUT->blocks_for_region('side-post') ?>
-                    </div>
-                </div>
-                <?php } ?>
-
-            </div>
-        </div>
-    </div>
-</div>
-
-<!-- END OF CONTENT -->
-
-       </div>
-
-<!-- START OF FOOTER -->
-
-    <div id="page-footer">
-        <p class="helplink">
-        <?php echo page_doc_link(get_string('moodledocslink')) ?>
-        </p>
-
-        <?php
-        echo $OUTPUT->login_info();
-        echo $OUTPUT->home_link();
-        echo $OUTPUT->standard_footer_html();
-        ?>
-    </div>
-
-<!-- END OF FOOTER -->
-</div>
-<?php echo $OUTPUT->standard_end_of_body_html() ?>
-</body>
-</html>
diff --git a/theme/serenity/layout/general.php b/theme/serenity/layout/general.php
deleted file mode 100644 (file)
index 3c454f3..0000000
+++ /dev/null
@@ -1,121 +0,0 @@
-<?php
-
-$hasheading = ($PAGE->heading);
-$hasnavbar = (empty($PAGE->layout_options['nonavbar']) && $PAGE->has_navbar());
-$hasfooter = (empty($PAGE->layout_options['nofooter']));
-$hassidepre = (empty($PAGE->layout_options['noblocks']) && $PAGE->blocks->region_has_content('side-pre', $OUTPUT));
-$hassidepost = (empty($PAGE->layout_options['noblocks']) && $PAGE->blocks->region_has_content('side-post', $OUTPUT));
-
-$showsidepre = ($hassidepre && !$PAGE->blocks->region_completely_docked('side-pre', $OUTPUT));
-$showsidepost = ($hassidepost && !$PAGE->blocks->region_completely_docked('side-post', $OUTPUT));
-$custommenu = $OUTPUT->custom_menu();
-$hascustommenu = (empty($PAGE->layout_options['nocustommenu']) && !empty($custommenu));
-
-$bodyclasses = array();
-if ($showsidepre && !$showsidepost) {
-    $bodyclasses[] = 'side-pre-only';
-} else if ($showsidepost && !$showsidepre) {
-    $bodyclasses[] = 'side-post-only';
-} else if (!$showsidepost && !$showsidepre) {
-    $bodyclasses[] = 'content-only';
-}
-if ($hascustommenu) {
-    $bodyclasses[] = 'has_custom_menu';
-}
-echo $OUTPUT->doctype() ?>
-<html <?php echo $OUTPUT->htmlattributes() ?>>
-<head>
-    <title><?php echo $PAGE->title ?></title>
-    <link rel="shortcut icon" href="<?php echo $OUTPUT->pix_url('favicon', 'theme')?>" />
-    <?php echo $OUTPUT->standard_head_html() ?>
-</head>
-<body id="<?php p($PAGE->bodyid) ?>" class="<?php p($PAGE->bodyclasses.' '.join(' ', $bodyclasses)) ?>">
-<?php echo $OUTPUT->standard_top_of_body_html() ?>
-
-<div id="page">
-       <div id="wrapper" class="clearfix">
-<?php if ($hasheading || $hasnavbar) { ?>
-
-    <div id="page-header" class="clearfix">
-
-               <?php if ($hasheading) { ?>
-                       <h1 class="headermain"><?php echo $PAGE->heading ?></h1>
-                   <div class="headermenu">
-                               <?php
-                               echo $OUTPUT->login_info();
-                                       if (!empty($PAGE->layout_options['langmenu'])) {
-                                       echo $OUTPUT->lang_menu();
-                                   }
-                               echo $PAGE->headingmenu
-                               ?>
-                       </div>
-               <?php } ?>
-
-    </div>
-
-       <?php if ($hascustommenu) { ?>
-       <div id="custommenu"><?php echo $custommenu; ?></div>
-       <?php } ?>
-
-    <?php if ($hasnavbar) { ?>
-           <div class="navbar clearfix">
-           <div class="breadcrumb"><?php echo $OUTPUT->navbar(); ?></div>
-            <div class="navbutton"> <?php echo $PAGE->button; ?></div>
-      </div>
-    <?php } ?>
-
-<?php } ?>
-
-<!-- END OF HEADER -->
-
-<div id="page-content-wrapper">
-    <div id="page-content">
-        <div id="region-main-box">
-            <div id="region-post-box">
-
-                <div id="region-main-wrap">
-                    <div id="region-main">
-                        <div class="region-content">
-                            <?php echo $OUTPUT->main_content() ?>
-                        </div>
-                    </div>
-                </div>
-
-                <?php if ($hassidepre) { ?>
-                <div id="region-pre" class="block-region">
-                    <div class="region-content">
-                        <?php echo $OUTPUT->blocks_for_region('side-pre') ?>
-                    </div>
-                </div>
-                <?php } ?>
-
-                <?php if ($hassidepost) { ?>
-                <div id="region-post" class="block-region">
-                    <div class="region-content">
-                        <?php echo $OUTPUT->blocks_for_region('side-post') ?>
-                    </div>
-                </div>
-                <?php } ?>
-
-            </div>
-        </div>
-    </div>
-</div>
-
-    </div>
-
-<!-- START OF FOOTER -->
-    <?php if ($hasfooter) { ?>
-    <div id="page-footer" class="clearfix">
-        <p class="helplink"><?php echo page_doc_link(get_string('moodledocslink')) ?></p>
-        <?php
-        echo $OUTPUT->login_info();
-        echo $OUTPUT->home_link();
-        echo $OUTPUT->standard_footer_html();
-        ?>
-    </div>
-    <?php } ?>
-</div>
-<?php echo $OUTPUT->standard_end_of_body_html() ?>
-</body>
-</html>
index 41ba3bc..f9bca28 100644 (file)
@@ -53,29 +53,29 @@ $THEME->layouts = array(
     'standard' => array(
         'file' => 'general.php',
         'regions' => array('side-pre', 'side-post'),
-        'defaultregion' => 'side-post'
+        'defaultregion' => 'side-pre'
     ),
     // Course page
     'course' => array(
         'file' => 'general.php',
         'regions' => array('side-pre', 'side-post'),
-        'defaultregion' => 'side-post'
+        'defaultregion' => 'side-pre'
     ),
     // Course page
     'coursecategory' => array(
         'file' => 'general.php',
         'regions' => array('side-pre', 'side-post'),
-        'defaultregion' => 'side-post'
+        'defaultregion' => 'side-pre'
     ),
     'incourse' => array(
         'file' => 'general.php',
         'regions' => array('side-pre', 'side-post'),
-        'defaultregion' => 'side-post'
+        'defaultregion' => 'side-pre'
     ),
     'frontpage' => array(
         'file' => 'general.php',
         'regions' => array('side-pre', 'side-post'),
-        'defaultregion' => 'side-post'
+        'defaultregion' => 'side-pre'
     ),
     'admin' => array(
         'file' => 'general.php',
@@ -85,12 +85,12 @@ $THEME->layouts = array(
     'mydashboard' => array(
         'file' => 'general.php',
         'regions' => array('side-pre', 'side-post'),
-        'defaultregion' => 'side-post'
+        'defaultregion' => 'side-pre'
     ),
     'mypublic' => array(
         'file' => 'general.php',
         'regions' => array('side-pre', 'side-post'),
-        'defaultregion' => 'side-post'
+        'defaultregion' => 'side-pre'
     ),
     'login' => array(
         'file' => 'general.php',
index 30d4319..0d81929 100644 (file)
@@ -54,31 +54,31 @@ $THEME->layouts = array(
     'standard' => array(
         'file' => 'general.php',
         'regions' => array('side-pre', 'side-post'),
-        'defaultregion' => 'side-post',
+        'defaultregion' => 'side-pre',
     ),
     // Main course page
     'course' => array(
         'file' => 'general.php',
         'regions' => array('side-pre', 'side-post'),
-        'defaultregion' => 'side-post',
+        'defaultregion' => 'side-pre',
         'options' => array('langmenu'=>true),
     ),
     'coursecategory' => array(
         'file' => 'general.php',
         'regions' => array('side-pre', 'side-post'),
-        'defaultregion' => 'side-post',
+        'defaultregion' => 'side-pre',
     ),
     // part of course, typical for modules - default page layout if $cm specified in require_login()
     'incourse' => array(
         'file' => 'general.php',
         'regions' => array('side-pre', 'side-post'),
-        'defaultregion' => 'side-post',
+        'defaultregion' => 'side-pre',
     ),
     // The site home page.
     'frontpage' => array(
         'file' => 'frontpage.php',
         'regions' => array('side-pre', 'side-post'),
-        'defaultregion' => 'side-post',
+        'defaultregion' => 'side-pre',
     ),
     // Server administration scripts.
     'admin' => array(
@@ -90,14 +90,14 @@ $THEME->layouts = array(
     'mydashboard' => array(
         'file' => 'general.php',
         'regions' => array('side-pre', 'side-post'),
-        'defaultregion' => 'side-post',
+        'defaultregion' => 'side-pre',
         'options' => array('langmenu'=>true),
     ),
     // My public page
     'mypublic' => array(
         'file' => 'general.php',
         'regions' => array('side-pre', 'side-post'),
-        'defaultregion' => 'side-post',
+        'defaultregion' => 'side-pre',
     ),
     'login' => array(
         'file' => 'general.php',
index 4e9b5f1..4d18a33 100644 (file)
@@ -2,6 +2,11 @@ This files describes API changes in /theme/* themes,
 information provided here is intended especially for theme designer.
 
 
+=== 2.3 ===
+
+optional changes:
+* add new u/f3.png image when theme contains customised f1 and f2 default user images
+
 === 2.2 ===
 
 required changes:
index f9992a1..879a994 100644 (file)
@@ -30,7 +30,7 @@
 defined('MOODLE_INTERNAL') || die();
 
 
-$version  = 2012052500.00;              // YYYYMMDD      = weekly release date of this DEV branch
+$version  = 2012052500.03;              // YYYYMMDD      = weekly release date of this DEV branch
                                         //         RR    = release increments - 00 in DEV branches
                                         //           .XX = incremental changes