Index: version.php
===================================================================
RCS file: /cvsroot/moodle/moodle/version.php,v
retrieving revision 1.1552
diff -u -r1.1552 version.php
--- version.php	4 May 2010 00:42:45 -0000	1.1552
+++ version.php	4 May 2010 09:24:32 -0000
@@ -6,7 +6,7 @@
 // This is compared against the values stored in the database to determine
 // whether upgrades should be performed (see lib/db/*.php)
 
-    $version = 2010050300;  // YYYYMMDD   = date of the last version bump
+    $version = 2010050400;  // YYYYMMDD   = date of the last version bump
                             //         XX = daily increments
 
     $release = '2.0 dev (Build: 20100504)';  // Human-friendly version name
Index: admin/settings/appearance.php
===================================================================
RCS file: /cvsroot/moodle/moodle/admin/settings/appearance.php,v
retrieving revision 1.55
diff -u -r1.55 appearance.php
--- admin/settings/appearance.php	31 Mar 2010 07:41:44 -0000	1.55
+++ admin/settings/appearance.php	4 May 2010 09:24:33 -0000
@@ -35,6 +35,7 @@
         }
     }
 
+
     // calendar
     $temp = new admin_settingpage('calendar', get_string('calendarsettings','admin'));
     $temp->add(new admin_setting_special_adminseesall());
@@ -123,9 +124,10 @@
     $temp->add(new admin_setting_configcheckbox('doctonewwindow', get_string('doctonewwindow', 'admin'), get_string('configdoctonewwindow', 'admin'), 0));
     $ADMIN->add('appearance', $temp);
 
-    $temp = new admin_settingpage('mymoodle', get_string('mymoodle', 'admin'));
-    $temp->add(new admin_setting_configcheckbox('mymoodleredirect', get_string('mymoodleredirect', 'admin'), get_string('configmymoodleredirect', 'admin'), 0));
-    $temp->add(new admin_setting_configtext('mycoursesperpage', get_string('mycoursesperpage', 'admin'), get_string('configmycoursesperpage', 'admin'), 21, PARAM_INT));
+    $temp = new admin_externalpage('mypage', get_string('mypage', 'admin'), $CFG->wwwroot . '/my/indexsys.php');
+    $ADMIN->add('appearance', $temp);
+
+    $temp = new admin_externalpage('profilepage', get_string('myprofile', 'admin'), $CFG->wwwroot . '/user/profilesys.php');
     $ADMIN->add('appearance', $temp);
 
     // coursemanager is the person responsible for course - usually manages enrolments, receives notification, etc.
Index: blocks/moodleblock.class.php
===================================================================
RCS file: /cvsroot/moodle/moodle/blocks/moodleblock.class.php,v
retrieving revision 1.152
diff -u -r1.152 moodleblock.class.php
--- blocks/moodleblock.class.php	19 Apr 2010 06:30:30 -0000	1.152
+++ blocks/moodleblock.class.php	4 May 2010 09:24:33 -0000
@@ -665,7 +665,21 @@
      * @return boolean
      */
     function user_can_edit() {
-        return has_capability('moodle/block:edit', $this->context);
+        global $USER;
+
+        if (has_capability('moodle/block:edit', $this->context)) {
+            return true;
+        }
+
+        // The blocks in My Moodle are a special case.  We want them to inherit from the user context.
+        if (!empty($USER->id)
+            && $this->instance->parentcontextid == $this->page->context->id   // Block belongs to this page
+            && $this->page->context->contextlevel == CONTEXT_USER             // Page belongs to a user
+            && $this->page->context->instanceid == $USER->id) {               // Page belongs to this user
+            return has_capability('moodle/my:manageblocks', $this->page->context);
+        }
+
+        return false;
     }
 
     /**
@@ -676,7 +690,20 @@
      * @return boolean
      */
     function user_can_addto($page) {
-        return has_capability('moodle/block:edit', $page->context);
+        global $USER;
+
+        if (has_capability('moodle/block:edit', $page->context)) {
+            return true;
+        }
+
+        // The blocks in My Moodle are a special case and use a different capability.
+        if (!empty($USER->id)
+            && $page->context->contextlevel == CONTEXT_USER             // Page belongs to a user
+            && $page->context->instanceid == $USER->id) {               // Page belongs to this user
+            return has_capability('moodle/my:manageblocks', $page->context);
+        }
+
+        return false;
     }
 
     function get_extra_capabilities() {
Index: blocks/course_overview/block_course_overview.php
===================================================================
RCS file: blocks/course_overview/block_course_overview.php
diff -N blocks/course_overview/block_course_overview.php
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ blocks/course_overview/block_course_overview.php	4 May 2010 09:24:33 -0000
@@ -0,0 +1,128 @@
+<?php
+
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * Course overview block
+ *
+ * Currently, just a copy-and-paste from the old My Moodle.
+ *
+ * @package   blocks
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+require_once($CFG->dirroot.'/lib/weblib.php');
+require_once($CFG->dirroot . '/lib/formslib.php');
+
+class block_course_overview extends block_base {
+    /**
+     * block initializations
+     */
+    public function init() {
+        $this->title   = get_string('pluginname', 'block_course_overview');
+        $this->version = 2010021100;
+    }
+
+    /**
+     * block contents
+     *
+     * @return object
+     */
+    public function get_content() {
+        global $USER;
+        if($this->content !== NULL) {
+            return $this->content;
+        }
+
+        $this->content = new stdClass();
+        $this->content->text = '';
+        $this->content->footer = '';
+
+        $content = array();
+
+        // limits the number of courses showing up
+        $courses_limit = 21;
+        // FIXME: this should be a block setting, rather than a global setting
+        if (isset($CFG->mycoursesperpage)) {
+            $courses_limit = $CFG->mycoursesperpage;
+        }
+
+        $morecourses = false;
+        if ($courses_limit > 0) {
+            $courses_limit = $courses_limit + 1;
+        }
+
+        $courses = get_my_courses($USER->id, 'visible DESC,sortorder ASC', '*', false, $courses_limit);
+        $site = get_site();
+        $course = $site; //just in case we need the old global $course hack
+
+        if (($courses_limit > 0) && (count($courses) >= $courses_limit)) {
+            //remove the 'marker' course that we retrieve just to see if we have more than $courses_limit
+            array_pop($courses);
+            $morecourses = true;
+        }
+
+
+        if (array_key_exists($site->id,$courses)) {
+            unset($courses[$site->id]);
+        }
+
+        foreach ($courses as $c) {
+            if (isset($USER->lastcourseaccess[$c->id])) {
+                $courses[$c->id]->lastaccess = $USER->lastcourseaccess[$c->id];
+            } else {
+                $courses[$c->id]->lastaccess = 0;
+            }
+        }
+
+        if (empty($courses)) {
+            $content[] = get_string('nocourses','my');
+        } else {
+            ob_start();
+            print_overview($courses);
+            $content[] = ob_get_contents();
+            ob_end_clean();
+        }
+
+        // if more than 20 courses
+        if ($morecourses) {
+            $content[] = '<br />...';
+        }
+
+        $this->content->text = implode($content);
+
+        return $this->content;
+    }
+
+    /**
+     * allow the block to have a configuration page
+     *
+     * @return boolean
+     */
+    public function has_config() {
+        return false;
+    }
+
+    /**
+     * locations where block can be displayed
+     *
+     * @return array
+     */
+    public function applicable_formats() {
+        return array('my-index'=>true);
+    }
+}
+?>
Index: blocks/course_overview/lang/en/block_course_overview.php
===================================================================
RCS file: blocks/course_overview/lang/en/block_course_overview.php
diff -N blocks/course_overview/lang/en/block_course_overview.php
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ blocks/course_overview/lang/en/block_course_overview.php	4 May 2010 09:24:33 -0000
@@ -0,0 +1,2 @@
+<?php
+$string['pluginname'] = 'Course overview';
Index: blocks/myprofile/block_myprofile.php
===================================================================
RCS file: blocks/myprofile/block_myprofile.php
diff -N blocks/myprofile/block_myprofile.php
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ blocks/myprofile/block_myprofile.php	4 May 2010 09:24:33 -0000
@@ -0,0 +1,309 @@
+<?php
+
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * Displays the user's profile information.
+ *
+ * @package    blocks
+ * @copyright  2010 Remote-Learner.net
+ * @author     Olav Jordan <olav.jordan@remote-learner.ca>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+require_once($CFG->dirroot.'/lib/weblib.php');
+require_once($CFG->dirroot . '/lib/formslib.php');
+
+/**
+ * Displays the user's profile information.
+ *
+ * @copyright  2010 Remote-Learner.net
+ * @author     Olav Jordan <olav.jordan@remote-learner.ca>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class block_myprofile extends block_base {
+    /**
+     * block initializations
+     */
+    public function init() {
+        $this->title   = get_string('pluginname', 'block_myprofile');
+        $this->version = 2009123100;
+    }
+
+    /**
+     * block contents
+     *
+     * @return object
+     */
+    public function get_content() {
+        global $CFG, $USER, $DB, $OUTPUT, $PAGE;
+
+        if($this->content !== NULL) {
+            return $this->content;
+        }
+
+        if (!isloggedin()){
+            return '';      // Never useful unless you are logged in
+        }
+
+        $this->content = new stdClass;
+        $this->content->text = '';
+        $this->content->footer = '';
+
+        $course = $this->page->course;
+        if ($PAGE->context->contextlevel == CONTEXT_USER) {
+            $user = $DB->get_record('user', array('id' => $PAGE->context->instanceid));
+        } else {
+            $user = $USER;
+        }
+
+        if ($course->id == SITEID) {
+            $coursecontext = get_context_instance(CONTEXT_SYSTEM);
+        } else {
+            $coursecontext = get_context_instance(CONTEXT_COURSE, $course->id);   // Course context
+        }
+
+        // Make sure they can view the course
+        if (!has_capability('moodle/course:view', $coursecontext, $user->id)) {
+            return '';
+        }
+
+        // TODO: clean up the following even more
+
+        if(!isset($this->config->display_picture) || $this->config->display_picture == 1) {
+            $this->content->text .= '<div class="myprofileitem picture">';
+            $this->content->text = $OUTPUT->user_picture($user, array('courseid'=>$course->id, 'size'=>'100', 'class'=>'profilepicture'));  // The new class makes CSS easier
+            $this->content->text .= '</div>';
+        }
+
+        $this->content->text .= '<div class="myprofileitem fullname">'.fullname($user).'</div>';
+
+        if(!isset($this->config->display_country) || $this->config->display_country == 1) {
+            $countries = get_string_manager()->get_list_of_countries();
+            $this->content->text .= '<div class="myprofileitem country">';
+            $this->content->text .= get_string('country') . ': ' . $countries[$user->country];
+            $this->content->text .= '</div>';
+        }
+
+        if(!isset($this->config->display_city) || $this->config->display_city == 1) {
+            $this->content->text .= '<div class="myprofileitem city">';
+            $this->content->text .= get_string('city') . ': ' . $user->city;
+            $this->content->text .= '</div>';
+        }
+
+        if(!isset($this->config->display_email) || $this->config->display_email == 1) {
+            $this->content->text .= '<div class="myprofileitem email">';
+            $this->content->text .= obfuscate_mailto($user->email, '', $user->emailstop);
+            $this->content->text .= '</div>';
+        }
+
+        if(!empty($this->config->display_icq) && !empty($user->icq)) {
+            $this->content->text .= '<div class="myprofileitem icq">';
+            $this->content->text .= 'ICQ: ' . $user->icq;
+            $this->content->text .= '</div>';
+        }
+
+        if(!empty($this->config->display_skype) && !empty($user->skype)) {
+            $this->content->text .= '<div class="myprofileitem skype">';
+            $this->content->text .= 'Skype: ' . $user->skype;
+            $this->content->text .= '</div>';
+        }
+
+        if(!empty($this->config->display_yahoo) && !empty($user->yahoo)) {
+            $this->content->text .= '<div class="myprofileitem yahoo">';
+            $this->content->text .= 'Yahoo: ' . $user->yahoo;
+            $this->content->text .= '</div>';
+        }
+
+        if(!empty($this->config->display_aim) && !empty($user->aim)) {
+            $this->content->text .= '<div class="myprofileitem aim">';
+            $this->content->text .= 'AIM: ' . $user->aim;
+            $this->content->text .= '</div>';
+        }
+
+        if(!empty($this->config->display_msn) && !empty($user->msn)) {
+            $this->content->text .= '<div class="myprofileitem msn">';
+            $this->content->text .= 'MSN: ' . $user->msn;
+            $this->content->text .= '</div>';
+        }
+
+        if(!empty($this->config->display_phone1) && !empty($user->phone1)) {
+            $this->content->text .= '<div class="myprofileitem phone1">';
+            $this->content->text .= get_string('phone').': ' . $user->phone1;
+            $this->content->text .= '</div>';
+        }
+
+        if(!empty($this->config->display_phone2) && !empty($user->phone2)) {
+            $this->content->text .= '<div class="myprofileitem phone2">';
+            $this->content->text .= get_string('phone').': ' . $user->phone2;
+            $this->content->text .= '</div>';
+        }
+
+        if(!empty($this->config->display_institution) && !empty($user->institution)) {
+            $this->content->text .= '<div class="myprofileitem institution">';
+            $this->content->text .= $user->institution;
+            $this->content->text .= '</div>';
+        }
+
+        if(!empty($this->config->display_address) && !empty($user->address)) {
+            $this->content->text .= '<div class="myprofileitem address">';
+            $this->content->text .= $user->address;
+            $this->content->text .= '</div>';
+        }
+
+        if(!empty($this->config->display_firstaccess) && !empty($user->firstaccess)) {
+            $this->content->text .= '<div class="myprofileitem firstaccess">';
+            $this->content->text .= get_string('firstaccess').': ' . userdate($user->firstaccess);
+            $this->content->text .= '</div>';
+        }
+
+        if(!empty($this->config->display_lastaccess) && !empty($user->lastaccess)) {
+            $this->content->text .= '<div class="myprofileitem lastaccess">';
+            $this->content->text .= get_string('lastaccess').': ' . userdate($user->lastaccess);
+            $this->content->text .= '</div>';
+        }
+
+        if(!empty($this->config->display_currentlogin) && !empty($user->currentlogin)) {
+            $this->content->text .= '<div class="myprofileitem currentlogin">';
+            $this->content->text .= get_string('login').': ' . userdate($user->currentlogin);
+            $this->content->text .= '</div>';
+        }
+
+        if(!empty($this->config->display_lastip) && !empty($user->lastip)) {
+            $this->content->text .= '<div class="myprofileitem lastip">';
+            $this->content->text .= 'IP: ' . $user->lastip;
+            $this->content->text .= '</div>';
+        }
+
+        $editscript = NULL;
+        if (isguestuser($user)) {
+            // guest account can not be edited
+
+        } else if (is_mnet_remote_user($user)) {
+            // cannot edit remote users
+
+        } else if (isguestuser() or !isloggedin()) {
+            // guests and not logged in can not edit own profile
+
+        } else if ($USER->id == $user->id) {
+            $systemcontext = get_context_instance(CONTEXT_SYSTEM);
+            if (has_capability('moodle/user:update', $systemcontext)) {
+                $editscript = '/user/editadvanced.php';
+            } else if (has_capability('moodle/user:editownprofile', $systemcontext)) {
+                $editscript = '/user/edit.php';
+            }
+
+        } else {
+            $systemcontext = get_context_instance(CONTEXT_SYSTEM);
+            $personalcontext = get_context_instance(CONTEXT_USER, $user->id);
+            if (has_capability('moodle/user:update', $systemcontext) and !is_primary_admin($user->id)){
+                $editscript = '/user/editadvanced.php';
+            } else if (has_capability('moodle/user:editprofile', $personalcontext) and !is_primary_admin($user->id)){
+                //teachers, parents, etc.
+                $editscript = '/user/edit.php';
+            }
+        }
+
+
+        if ($editscript) {
+            $this->content->text .= '<div class="myprofileitem edit">';
+            $this->content->text .= '<a href="'.$CFG->wwwroot.$editscript.'?id='.$user->id.'&amp;course='.$course->id.'">'.get_string('editmyprofile').'</a>';
+            $this->content->text .= '</div>';
+        }
+
+
+        return $this->content;
+    }
+
+    /**
+     * allow the block to have a configuration page
+     *
+     * @return boolean
+     */
+    public function has_config() {
+        return false;
+    }
+
+    /**
+     * allow more than one instance of the block on a page
+     *
+     * @return boolean
+     */
+    public function instance_allow_multiple() {
+        //allow more than one instance on a page
+        return false;
+    }
+
+    /**
+     * allow instances to have their own configuration
+     *
+     * @return boolean
+     */
+    function instance_allow_config() {
+        //allow instances to have their own configuration
+        return false;
+    }
+
+    /**
+     * instance specialisations (must have instance allow config true)
+     *
+     */
+    public function specialization() {
+    }
+
+    /**
+     * displays instance configuration form
+     *
+     * @return boolean
+     */
+    function instance_config_print() {
+        if (!$this->instance_allow_config()) {
+            return false;
+        }
+
+        global $CFG;
+
+        $form = new block_myprofile.phpConfigForm(null, array($this->config));
+        $form->display();
+
+        return true;
+    }
+
+    /**
+     * locations where block can be displayed
+     *
+     * @return array
+     */
+    public function applicable_formats() {
+        return array('all'=>true);
+    }
+
+    /**
+     * post install configurations
+     *
+     */
+    public function after_install() {
+    }
+
+    /**
+     * post delete configurations
+     *
+     */
+    public function before_delete() {
+    }
+
+}
+?>
Index: blocks/myprofile/edit_form.php
===================================================================
RCS file: blocks/myprofile/edit_form.php
diff -N blocks/myprofile/edit_form.php
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ blocks/myprofile/edit_form.php	4 May 2010 09:24:34 -0000
@@ -0,0 +1,157 @@
+<?php
+
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * Form for editing profile block settings
+ *
+ * @package    blocks
+ * @copyright  2010 Remote-Learner.net
+ * @author     Olav Jordan <olav.jordan@remote-learner.ca>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class block_myprofile_edit_form extends block_edit_form {
+    protected function specific_definition($mform) {
+        global $CFG;
+        $mform->addElement('header', 'configheader', get_string('myprofile_settings', 'block_myprofile'));
+
+        $mform->addElement('selectyesno', 'config_display_picture', get_string('display_picture', 'block_myprofile'));
+        if (isset($this->block->config->display_picture)) {
+            $mform->setDefault('config_display_picture', $this->block->config->display_picture);
+        } else {
+            $mform->setDefault('config_display_picture', '1');
+        }
+
+        $mform->addElement('selectyesno', 'config_display_country', get_string('display_country', 'block_myprofile'));
+        if (isset($this->block->config->display_country)) {
+            $mform->setDefault('config_display_country', $this->block->config->display_country);
+        } else {
+            $mform->setDefault('config_display_country', '1');
+        }
+
+        $mform->addElement('selectyesno', 'config_display_city', get_string('display_city', 'block_myprofile'));
+        if (isset($this->block->config->display_city)) {
+            $mform->setDefault('config_display_city', $this->block->config->display_city);
+        } else {
+            $mform->setDefault('config_display_city', '1');
+        }
+
+        $mform->addElement('selectyesno', 'config_display_email', get_string('display_email', 'block_myprofile'));
+        if (isset($this->block->config->display_email)) {
+            $mform->setDefault('config_display_email', $this->block->config->display_email);
+        } else {
+            $mform->setDefault('config_display_email', '1');
+        }
+
+        $mform->addElement('selectyesno', 'config_display_un', get_string('display_un', 'block_myprofile'));
+        if (isset($this->block->config->display_un)) {
+            $mform->setDefault('config_display_un', $this->block->config->display_un);
+        } else {
+            $mform->setDefault('config_display_un', '0');
+        }
+
+        $mform->addElement('selectyesno', 'config_display_icq', get_string('display_icq', 'block_myprofile'));
+        if (isset($this->block->config->display_icq)) {
+            $mform->setDefault('config_display_icq', $this->block->config->display_icq);
+        } else {
+            $mform->setDefault('config_display_icq', '0');
+        }
+
+        $mform->addElement('selectyesno', 'config_display_skype', get_string('display_skype', 'block_myprofile'));
+        if (isset($this->block->config->display_skype)) {
+            $mform->setDefault('config_display_skype', $this->block->config->display_skype);
+        } else {
+            $mform->setDefault('config_display_skype', '0');
+        }
+
+        $mform->addElement('selectyesno', 'config_display_yahoo', get_string('display_yahoo', 'block_myprofile'));
+        if (isset($this->block->config->display_yahoo)) {
+            $mform->setDefault('config_display_yahoo', $this->block->config->display_yahoo);
+        } else {
+            $mform->setDefault('config_display_yahoo', '0');
+        }
+
+        $mform->addElement('selectyesno', 'config_display_aim', get_string('display_aim', 'block_myprofile'));
+        if (isset($this->block->config->display_aim)) {
+            $mform->setDefault('config_display_aim', $this->block->config->display_aim);
+        } else {
+            $mform->setDefault('config_display_aim', '0');
+        }
+
+        $mform->addElement('selectyesno', 'config_display_msn', get_string('display_msn', 'block_myprofile'));
+        if (isset($this->block->config->display_msn)) {
+            $mform->setDefault('config_display_msn', $this->block->config->display_msn);
+        } else {
+            $mform->setDefault('config_display_msn', '0');
+        }
+
+        $mform->addElement('selectyesno', 'config_display_phone1', get_string('display_phone1', 'block_myprofile'));
+        if (isset($this->block->config->display_phone1)) {
+            $mform->setDefault('config_display_phone1', $this->block->config->display_phone1);
+        } else {
+            $mform->setDefault('config_display_phone1', '0');
+        }
+
+        $mform->addElement('selectyesno', 'config_display_phone2', get_string('display_phone2', 'block_myprofile'));
+        if (isset($this->block->config->display_phone2)) {
+            $mform->setDefault('config_display_phone2', $this->block->config->display_phone2);
+        } else {
+            $mform->setDefault('config_display_phone2', '0');
+        }
+
+        $mform->addElement('selectyesno', 'config_display_institution', get_string('display_institution', 'block_myprofile'));
+        if (isset($this->block->config->display_institution)) {
+            $mform->setDefault('config_display_institution', $this->block->config->display_institution);
+        } else {
+            $mform->setDefault('config_display_institution', '0');
+        }
+
+        $mform->addElement('selectyesno', 'config_display_address', get_string('display_address', 'block_myprofile'));
+        if (isset($this->block->config->display_address)) {
+            $mform->setDefault('config_display_address', $this->block->config->display_address);
+        } else {
+            $mform->setDefault('config_display_address', '0');
+        }
+
+        $mform->addElement('selectyesno', 'config_display_firstaccess', get_string('display_firstaccess', 'block_myprofile'));
+        if (isset($this->block->config->display_firstaccess)) {
+            $mform->setDefault('config_display_firstaccess', $this->block->config->display_firstaccess);
+        } else {
+            $mform->setDefault('config_display_firstaccess', '0');
+        }
+
+        $mform->addElement('selectyesno', 'config_display_lastaccess', get_string('display_lastaccess', 'block_myprofile'));
+        if (isset($this->block->config->display_lastaccess)) {
+            $mform->setDefault('config_display_lastaccess', $this->block->config->display_lastaccess);
+        } else {
+            $mform->setDefault('config_display_lastaccess', '0');
+        }
+
+        $mform->addElement('selectyesno', 'config_display_currentlogin', get_string('display_currentlogin', 'block_myprofile'));
+        if (isset($this->block->config->display_currentlogin)) {
+            $mform->setDefault('config_display_currentlogin', $this->block->config->display_currentlogin);
+        } else {
+            $mform->setDefault('config_display_currentlogin', '0');
+        }
+
+        $mform->addElement('selectyesno', 'config_display_lastip', get_string('display_lastip', 'block_myprofile'));
+        if (isset($this->block->config->display_lastip)) {
+            $mform->setDefault('config_display_lastip', $this->block->config->display_lastip);
+        } else {
+            $mform->setDefault('config_display_lastip', '0');
+        }
+    }
+}
\ No newline at end of file
Index: blocks/myprofile/styles.css
===================================================================
RCS file: blocks/myprofile/styles.css
diff -N blocks/myprofile/styles.css
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ blocks/myprofile/styles.css	4 May 2010 09:24:34 -0000
@@ -0,0 +1,4 @@
+.block_myprofile img.profilepicture { height:100px; width:100px;}
+.block_myprofile .myprofileitem.fullname {font-size:1.5em; font-style: bold;}
+.block_myprofile .myprofileitem.edit {text-align: right;}
+
Index: blocks/myprofile/lang/en/block_myprofile.php
===================================================================
RCS file: blocks/myprofile/lang/en/block_myprofile.php
diff -N blocks/myprofile/lang/en/block_myprofile.php
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ blocks/myprofile/lang/en/block_myprofile.php	4 May 2010 09:24:34 -0000
@@ -0,0 +1,23 @@
+<?php
+$string['pluginname'] = 'Personal profile';
+$string['myprofile_settings'] = 'Personal profile settings';
+$string['contentsettings'] = 'Display settings for content region';
+$string['display_picture'] = 'Display picture';
+$string['display_country'] = 'Display country';
+$string['display_city'] = 'Display city';
+$string['display_email'] = 'Display email';
+$string['display_un'] = 'Display name';
+$string['display_icq'] = 'Display ICQ';
+$string['display_skype'] = 'Display Skype';
+$string['display_yahoo'] = 'Display Yahoo';
+$string['display_aim'] = 'Display AIM';
+$string['display_msn'] = 'Display MSN';
+$string['display_phone1'] = 'Display phone number 1';
+$string['display_phone2'] = 'Display phone number 2';
+$string['display_institution'] = 'Display institution';
+$string['display_address'] = 'Display address';
+$string['display_firstaccess'] = 'Display first access';
+$string['display_lastaccess'] = 'Display last access';
+$string['display_currentlogin'] = 'Display current login';
+$string['display_lastip'] = 'Display last IP';
+?>
Index: lang/en/admin.php
===================================================================
RCS file: /cvsroot/moodle/moodle/lang/en/admin.php,v
retrieving revision 1.82
diff -u -r1.82 admin.php
--- lang/en/admin.php	3 May 2010 18:25:01 -0000	1.82
+++ lang/en/admin.php	4 May 2010 09:24:35 -0000
@@ -254,6 +254,7 @@
 $string['configminpasswordupper'] = 'Passwords must have at least these many upper case letters.';
 $string['configmycoursesperpage'] = 'Maximum number of courses to display in any list of a user\'s own courses';
 $string['configmymoodleredirect'] = 'This setting forces redirects to /my on login for non-admins and replaces the top level site navigation with /my';
+$string['configmypagelocked'] = 'This setting prevents the default page from being edited by any non-admins';
 $string['confignavshowallcourses'] = 'Setting this ensures that all courses a user is registered in are shown on the navigation at all times. By default once a user browses to a course only that course is shown on the navigation.';
 $string['confignavshowcategories'] = 'Show course categories in the navigation bar and navigation blocks';
 $string['confignodefaultuserrolelists'] = 'This setting prevents all users from being returned from the database from deprecated calls of get_course_user, etc., for the site course if the default role provides that access. Check this, if you suffer a performance hit.';
@@ -668,8 +669,12 @@
 $string['multilangupgradenotice'] = 'Your site is probably using old multilang syntax, <a href="multilangupgrade.php">multilang upgrade</a> is recommended.';
 $string['mustenablestats'] = 'Stats have not yet been enabled on this site.';
 $string['mycoursesperpage'] = 'Number of courses';
+$string['mydashboard'] = 'System default dashboard';
 $string['mymoodle'] = 'My Moodle';
 $string['mymoodleredirect'] = 'Force users to use My Moodle';
+$string['mypage'] = 'Default My Moodle page';
+$string['myprofile'] = 'Default Profile page';
+$string['mypagelocked'] = 'Lock default page';
 $string['mysql416bypassed'] = 'However, if your site is using iso-8859-1 (latin) languages ONLY, you may continue using your currently installed MySQL 4.1.12 (or higher).';
 $string['mysql416required'] = 'MySQL 4.1.16 is the minimum version required for Moodle 1.6 in order to guarantee that all data can be converted to UTF-8 in the future.';
 $string['navigationupgrade'] = 'This upgrade introduces two new navigation blocks that will replace these blocks: Administration, Courses, Activities and Participants.  If you had set any special permissions on those blocks you should check to make sure everything is behaving as you want it.';
Index: lang/en/moodle.php
===================================================================
RCS file: /cvsroot/moodle/moodle/lang/en/moodle.php,v
retrieving revision 1.501
diff -u -r1.501 moodle.php
--- lang/en/moodle.php	4 May 2010 08:27:13 -0000	1.501
+++ lang/en/moodle.php	4 May 2010 09:24:36 -0000
@@ -324,6 +324,7 @@
 $string['coursenotaccessible'] = 'This course does not allow public access';
 $string['courseoverview'] = 'Course overview';
 $string['courseoverviewgraph'] = 'Course overview graph';
+$string['courseprofiles'] = 'Course profiles';
 $string['coursereasonforrejecting'] = 'Your reasons for rejecting this request';
 $string['coursereasonforrejectingemail'] = 'This will be emailed to the requester';
 $string['coursereject'] = 'Reject a course request';
@@ -1365,6 +1366,7 @@
 $string['publicdirectory0'] = 'Please do not publish this site';
 $string['publicdirectory1'] = 'Publish the site name only';
 $string['publicdirectory2'] = 'Publish the site name with a link';
+$string['publicprofile'] = 'Public profile';
 $string['publicsitefileswarning'] = 'Note: files placed here can be accessed by anyone';
 $string['publicsitefileswarning2'] = 'Note: Files placed here can be accessed by anyone who knows (or can guess) the URL. For security reasons, it is recommended that any backup files are deleted immediately after restoring them.';
 $string['publicsitefileswarning3'] = 'Note: Files placed here can be accessed by anyone who knows (or can guess) the URL. <br />For security reasons, backup files should be saved in the secure backupdata folder only.';
@@ -1716,8 +1718,8 @@
 $string['up'] = 'Up';
 $string['update'] = 'Update';
 $string['updated'] = 'Updated {$a}';
-$string['updatemymoodleoff'] = 'Normal mode';
-$string['updatemymoodleon'] = 'Edit this page';
+$string['updatemymoodleoff'] = 'Stop customising this page';
+$string['updatemymoodleon'] = 'Customise this page';
 $string['updatemyprofile'] = 'Update profile';
 $string['updatesevery'] = 'Updates every {$a} seconds';
 $string['updatethis'] = 'Update this {$a}';
Index: lang/en/my.php
===================================================================
RCS file: /cvsroot/moodle/moodle/lang/en/my.php,v
retrieving revision 1.5
diff -u -r1.5 my.php
--- lang/en/my.php	10 Apr 2010 14:01:51 -0000	1.5
+++ lang/en/my.php	4 May 2010 09:24:36 -0000
@@ -1,30 +1,16 @@
-<?php
+<?PHP // $Id$ 
+      // my.php - created with Moodle 1.7 beta + (2006101003)
 
-// This file is part of Moodle - http://moodle.org/
-//
-// Moodle is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Moodle is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
 
-/**
- * Strings for component 'my', language 'en', branch 'MOODLE_20_STABLE'
- *
- * @package   my
- * @copyright 1999 onwards Martin Dougiamas  {@link http://moodle.com}
- * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-$string['mymoodle'] = 'Overview of my courses';
+$string['mymoodle'] = 'My Moodle';
 $string['nocourses'] = 'No course information to show.';
-$string['noguest'] = 'The \'Course Overview\' page is not available to guest users';
+$string['noguest'] = 'The \'My Moodle\' page is not available to guest users';
 $string['pinblocks'] = 'Configure pinned blocks for my moodle';
-$string['pinblocksexplan'] = 'Any block settings you configure here will be visible (and non-editable) for any user of moodle on their \'my moodle\' overview page.';
+$string['pinblocksexplan'] = 'Any block settings you configure here will be visible (and non-editable) for any user of moodle on their \'My Moodle\' overview page.';
+$string['defaultpage'] = 'Default My Moodle page';
+$string['defaultprofilepage'] = 'Default profile page';
+$string['addpage'] = 'Add page';
+$string['delpage'] = 'Delete page';
+$string['managepages'] = 'Manage pages';
+
+?>
Index: lib/accesslib.php
===================================================================
RCS file: /cvsroot/moodle/moodle/lib/accesslib.php,v
retrieving revision 1.636
diff -u -r1.636 accesslib.php
--- lib/accesslib.php	2 May 2010 22:24:35 -0000	1.636
+++ lib/accesslib.php	4 May 2010 09:24:38 -0000
@@ -3710,9 +3710,10 @@
 
     switch ($context->contextlevel) {
         case CONTEXT_USER:
-            $url = new moodle_url('/user/view.php', array('id'=>$context->instanceid));
-            if ($COURSE->id != SITEID) {
-                $url->param('courseid', $COURSE->id);
+            if ($COURSE->id == SITEID) {
+                $url = new moodle_url('/user/profile.php', array('id'=>$context->instanceid));
+            } else {
+                $url = new moodle_url('/user/view.php', array('id'=>$context->instanceid, 'courseid'=>$COURSE->id));
             }
             return $url;;
 
Index: lib/adminlib.php
===================================================================
RCS file: /cvsroot/moodle/moodle/lib/adminlib.php,v
retrieving revision 1.459
diff -u -r1.459 adminlib.php
--- lib/adminlib.php	1 May 2010 07:12:57 -0000	1.459
+++ lib/adminlib.php	4 May 2010 09:24:40 -0000
@@ -5854,6 +5854,7 @@
         'community',
         'completionstatus',
         'course_list',
+        'course_overview',
         'course_summary',
         'glossary_random',
         'html',
@@ -5862,6 +5863,7 @@
         'mentees',
         'messages',
         'mnet_hosts',
+        'myprofile',
         'navigation',
         'news_items',
         'online_users',
@@ -6895,7 +6897,7 @@
                     $iprestriction = $token->iprestriction;
                 }
 
-                $userprofilurl = new moodle_url('/user/view.php?id='.$token->userid);
+                $userprofilurl = new moodle_url('/user/profile.php?id='.$token->userid);
                 $useratag = html_writer::start_tag('a', array('href' => $userprofilurl));
                 $useratag .= $token->firstname." ".$token->lastname;
                 $useratag .= html_writer::end_tag('a');
Index: lib/blocklib.php
===================================================================
RCS file: /cvsroot/moodle/moodle/lib/blocklib.php,v
retrieving revision 1.245
diff -u -r1.245 blocklib.php
--- lib/blocklib.php	27 Apr 2010 22:31:29 -0000	1.245
+++ lib/blocklib.php	4 May 2010 09:24:40 -0000
@@ -1772,8 +1772,18 @@
  * Add the default system-context blocks. E.g. the admin tree.
  */
 function blocks_add_default_system_blocks() {
+    global $DB;
+
     $page = new moodle_page();
     $page->set_context(get_context_instance(CONTEXT_SYSTEM));
     $page->blocks->add_blocks(array(BLOCK_POS_LEFT => array('navigation', 'settings')), '*', null, true);
     $page->blocks->add_blocks(array(BLOCK_POS_LEFT => array('admin_bookmarks')), 'admin-*', null, null, 2);
+
+    if ($defaultmypage = $DB->get_record('my_pages', array('userid'=>0, 'name'=>'__default', 'private'=>1))) {
+        $subpagepattern = $defaultmypage->id;
+    } else {
+        $subpagepattern = 0;
+    }
+
+    $page->blocks->add_blocks(array(BLOCK_POS_RIGHT => array('myprofile', 'private_files', 'online_users'), 'content' => array('course_overview')), 'my-index', $subpagepattern, false);
 }
Index: lib/moodlelib.php
===================================================================
RCS file: /cvsroot/moodle/moodle/lib/moodlelib.php,v
retrieving revision 1.1363
diff -u -r1.1363 moodlelib.php
--- lib/moodlelib.php	2 May 2010 11:43:58 -0000	1.1363
+++ lib/moodlelib.php	4 May 2010 09:24:43 -0000
@@ -5066,7 +5066,11 @@
     } else {
         $a = new object();
         $a->coursename = $course->fullname;
-        $a->profileurl = "$CFG->wwwroot/user/view.php?id=$user->id&course=$course->id";
+        if ($course->id == SITEID) {
+            $a->profileurl = "$CFG->wwwroot/user/profile.php?id=$user->id";
+        } else {
+            $a->profileurl = "$CFG->wwwroot/user/view.php?id=$user->id&course=$course->id";
+        }
         $message = get_string("welcometocoursetext", "", $a);
     }
 
Index: lib/navigationlib.php
===================================================================
RCS file: /cvsroot/moodle/moodle/lib/navigationlib.php,v
retrieving revision 1.107
diff -u -r1.107 navigationlib.php
--- lib/navigationlib.php	4 May 2010 04:00:03 -0000	1.107
+++ lib/navigationlib.php	4 May 2010 09:24:44 -0000
@@ -1251,7 +1251,11 @@
         // If the user is the current user or has permission to view the details of the requested
         // user than add a view profile link.
         if ($iscurrentuser || has_capability('moodle/user:viewdetails', $coursecontext) || has_capability('moodle/user:viewdetails', $usercontext)) {
-            $usernode->add(get_string('viewprofile'), new moodle_url('/user/view.php',$baseargs));
+            if ($issitecourse) {
+                $usernode->add(get_string('viewprofile'), new moodle_url('/user/profile.php',$baseargs));
+            } else {
+                $usernode->add(get_string('viewprofile'), new moodle_url('/user/view.php',$baseargs));
+            }
         }
 
         // Add nodes for forum posts and discussions if the user can view either or both
@@ -1263,7 +1267,7 @@
                 $forumtab->add(get_string('posts', 'forum'), new moodle_url('/mod/forum/user.php', $baseargs));
             }
             if ($canviewdiscussions) {
-                $forumtab->add(get_string('discussions', 'forum'), new moodle_url('/mod/forum/user.php', array_merge($baseargs, array('mode'=>'discussions'))));
+                $forumtab->add(get_string('discussions', 'forum'), new moodle_url('/mod/forum/user.php', array_merge($baseargs, array('mode'=>'discussions', 'course'=>$course->id))));
             }
         }
 
@@ -1290,59 +1294,62 @@
         }
 
         // Add a reports tab and then add reports the the user has permission to see.
-        $reporttab = $usernode->add(get_string('activityreports'));
         $anyreport  = has_capability('moodle/user:viewuseractivitiesreport', $usercontext);
         $viewreports = ($anyreport || ($course->showreports && $iscurrentuser));
-        $reportargs = array('user'=>$user->id);
-        if (!empty($course->id)) {
-            $reportargs['id'] = $course->id;
-        } else {
-            $reportargs['id'] = SITEID;
-        }
-        if ($viewreports || has_capability('coursereport/outline:view', $coursecontext)) {
-            $reporttab->add(get_string('outlinereport'), new moodle_url('/course/user.php', array_merge($reportargs, array('mode'=>'outline'))));
-            $reporttab->add(get_string('completereport'), new moodle_url('/course/user.php', array_merge($reportargs, array('mode'=>'complete'))));
-        }
+        if ($viewreports) {
+            $reporttab = $usernode->add(get_string('activityreports'));
+            $reportargs = array('user'=>$user->id);
+            if (!empty($course->id)) {
+                $reportargs['id'] = $course->id;
+            } else {
+                $reportargs['id'] = SITEID;
+            }
+            if ($viewreports || has_capability('coursereport/outline:view', $coursecontext)) {
+                $reporttab->add(get_string('outlinereport'), new moodle_url('/course/user.php', array_merge($reportargs, array('mode'=>'outline'))));
+                $reporttab->add(get_string('completereport'), new moodle_url('/course/user.php', array_merge($reportargs, array('mode'=>'complete'))));
+            }
 
-        if ($viewreports || has_capability('coursereport/log:viewtoday', $coursecontext)) {
-            $reporttab->add(get_string('todaylogs'), new moodle_url('/course/user.php', array_merge($reportargs, array('mode'=>'todaylogs'))));
-        }
+            if ($viewreports || has_capability('coursereport/log:viewtoday', $coursecontext)) {
+                $reporttab->add(get_string('todaylogs'), new moodle_url('/course/user.php', array_merge($reportargs, array('mode'=>'todaylogs'))));
+            }
 
-        if ($viewreports || has_capability('coursereport/log:view', $coursecontext)) {
-            $reporttab->add(get_string('alllogs'), new moodle_url('/course/user.php', array_merge($reportargs, array('mode'=>'alllogs'))));
-        }
+            if ($viewreports || has_capability('coursereport/log:view', $coursecontext)) {
+                $reporttab->add(get_string('alllogs'), new moodle_url('/course/user.php', array_merge($reportargs, array('mode'=>'alllogs'))));
+            }
 
-        if (!empty($CFG->enablestats)) {
-            if ($viewreports || has_capability('coursereport/stats:view', $coursecontext)) {
-                $reporttab->add(get_string('stats'), new moodle_url('/course/user.php', array_merge($reportargs, array('mode'=>'stats'))));
+            if (!empty($CFG->enablestats)) {
+                if ($viewreports || has_capability('coursereport/stats:view', $coursecontext)) {
+                    $reporttab->add(get_string('stats'), new moodle_url('/course/user.php', array_merge($reportargs, array('mode'=>'stats'))));
+                }
             }
-        }
 
-        $gradeaccess = false;
-        if (has_capability('moodle/grade:viewall', $coursecontext)) {
-            //ok - can view all course grades
-            $gradeaccess = true;
-        } else if ($course->showgrades) {
-            if ($iscurrentuser && has_capability('moodle/grade:view', $coursecontext)) {
-                //ok - can view own grades
-                $gradeaccess = true;
-            } else if (has_capability('moodle/grade:viewall', $usercontext)) {
-                // ok - can view grades of this user - parent most probably
-                $gradeaccess = true;
-            } else if ($anyreport) {
-                // ok - can view grades of this user - parent most probably
+            $gradeaccess = false;
+            if (has_capability('moodle/grade:viewall', $coursecontext)) {
+                //ok - can view all course grades
                 $gradeaccess = true;
+            } else if ($course->showgrades) {
+                if ($iscurrentuser && has_capability('moodle/grade:view', $coursecontext)) {
+                    //ok - can view own grades
+                    $gradeaccess = true;
+                } else if (has_capability('moodle/grade:viewall', $usercontext)) {
+                    // ok - can view grades of this user - parent most probably
+                    $gradeaccess = true;
+                } else if ($anyreport) {
+                    // ok - can view grades of this user - parent most probably
+                    $gradeaccess = true;
+                }
+            }
+            if ($gradeaccess) {
+                $reporttab->add(get_string('grade'), new moodle_url('/course/user.php', array_merge($reportargs, array('mode'=>'grade'))));
+            }
+
+            // Check the number of nodes in the report node... if there are none remove
+            // the node
+            if (count($reporttab->children)===0) {
+                $usernode->remove_child($reporttab);
             }
         }
-        if ($gradeaccess) {
-            $reporttab->add(get_string('grade'), new moodle_url('/course/user.php', array_merge($reportargs, array('mode'=>'grade'))));
-        }
 
-        // Check the number of nodes in the report node... if there are none remove
-        // the node
-        if (count($reporttab->children)===0) {
-            $usernode->remove_child($reporttab);
-        }
 
         // If the user is the current user add the repositories for the current user
         if ($iscurrentuser) {
@@ -1355,6 +1362,23 @@
         return true;
     }
 
+    private function add_my_pages($node, $subpages, $baseurl, $defaultname, $baseargs = array()) {
+        global $CFG;
+
+        foreach($subpages as $page) {
+            $name = $page->name;
+            $params = $baseargs;
+            if ($page->name == '__default') {
+                $name = $defaultname;
+            } else {
+                $params['pageid'] = $page->id;
+            }
+            $url = new moodle_url($baseurl, $params);
+
+            $node->add($name, $url, null, null, null, null, false);
+        }
+    }
+
     /**
      * This method simply checks to see if a given module can extend the navigation.
      *
@@ -2686,7 +2710,11 @@
                 $usersetting->add(get_string('userdeleted'), null, self::TYPE_SETTING);
             } else {
                 // We can edit the user so show the user deleted message and link it to the profile
-                $profileurl = new moodle_url('/user/view.php', array('id'=>$user->id, 'course'=>$course->id));
+                if ($course->id == SITEID) {
+                    $profileurl = new moodle_url('/user/profile.php', array('id'=>$user->id));
+                } else {
+                    $profileurl = new moodle_url('/user/view.php', array('id'=>$user->id, 'course'=>$course->id));
+                }
                 $usersetting->add(get_string('userdeleted'), $profileurl, self::TYPE_SETTING);
             }
             return true;
@@ -2779,11 +2807,18 @@
         }
 
         // Messaging
+        // TODO this is adding itself to the messaging settings for other people based on one's own setting
         if (has_capability('moodle/user:editownmessageprofile', $systemcontext)) {
             $url = new moodle_url('/message/edit.php', array('id'=>$user->id, 'course'=>$course->id));
             $usersetting->add(get_string('editmymessage', 'message'), $url, self::TYPE_SETTING);
         }
 
+        // Login as ...
+        if (!$user->deleted and !$currentuser && !session_is_loggedinas() && has_capability('moodle/user:loginas', $coursecontext) && !is_siteadmin($user->id)) {
+            $url = new moodle_url('/course/loginas.php', array('id'=>$course->id, 'user'=>$user->id, 'sesskey'=>sesskey()));
+            $usersetting->add(get_string('loginas'), $url, self::TYPE_SETTING);
+        }
+
         return $usersetting;
     }
 
Index: lib/outputrenderers.php
===================================================================
RCS file: /cvsroot/moodle/moodle/lib/outputrenderers.php,v
retrieving revision 1.189
diff -u -r1.189 outputrenderers.php
--- lib/outputrenderers.php	4 May 2010 08:29:06 -0000	1.189
+++ lib/outputrenderers.php	4 May 2010 09:24:45 -0000
@@ -407,7 +407,8 @@
             $context = get_context_instance(CONTEXT_COURSE, $course->id);
 
             $fullname = fullname($USER, true);
-            $username = "<a href=\"$CFG->wwwroot/user/view.php?id=$USER->id&amp;course=$course->id\">$fullname</a>";
+            // Since Moodle 2.0 this link always goes to the public profile page (not the course profile page)
+            $username = "<a href=\"$CFG->wwwroot/user/profile.php?id=$USER->id\">$fullname</a>";
             if (is_mnet_remote_user($USER) and $idprovider = $DB->get_record('mnet_host', array('id'=>$USER->mnethostid))) {
                 $username .= " from <a href=\"{$idprovider->wwwroot}\">{$idprovider->name}</a>";
             }
@@ -1675,7 +1676,11 @@
             $courseid = $userpicture->courseid;
         }
 
-        $url = new moodle_url('/user/view.php', array('id' => $user->id, 'course' => $courseid));
+        if ($courseid == SITEID) {
+            $url = new moodle_url('/user/profile.php', array('id' => $user->id));
+        } else {
+            $url = new moodle_url('/user/view.php', array('id' => $user->id, 'course' => $courseid));
+        }
 
         $attributes = array('href'=>$url);
 
Index: lib/tablelib.php
===================================================================
RCS file: /cvsroot/moodle/moodle/lib/tablelib.php,v
retrieving revision 1.59
diff -u -r1.59 tablelib.php
--- lib/tablelib.php	13 Apr 2010 20:34:28 -0000	1.59
+++ lib/tablelib.php	4 May 2010 09:24:45 -0000
@@ -757,10 +757,15 @@
      */
     function col_fullname($row){
         global $COURSE, $CFG;
-        if (!$this->download){
 
-            return '<a href="'.$CFG->wwwroot.'/user/view.php?id='.$row->{$this->useridfield}.
-                    '&amp;course='.$COURSE->id.'">'.fullname($row).'</a>';
+        if (!$this->download){
+            if ($COURSE->id == SITEID) {
+                return '<a href="'.$CFG->wwwroot.'/user/profile.php?id='.$row->{$this->useridfield}.  '">'.
+                        fullname($row).'</a>';
+            } else {
+                return '<a href="'.$CFG->wwwroot.'/user/view.php?id='.$row->{$this->useridfield}.
+                        '&amp;course='.$COURSE->id.'">'.fullname($row).'</a>';
+            }
         } else {
             return fullname($row);
         }
Index: lib/db/access.php
===================================================================
RCS file: /cvsroot/moodle/moodle/lib/db/access.php,v
retrieving revision 1.134
diff -u -r1.134 access.php
--- lib/db/access.php	2 May 2010 17:05:35 -0000	1.134
+++ lib/db/access.php	4 May 2010 09:24:45 -0000
@@ -493,6 +493,51 @@
         )
     ),
 
+    // can the user manage the system default profile page?
+    'moodle/user:managesyspages' => array(
+
+        'riskbitmap' => RISK_SPAM | RISK_PERSONAL | RISK_CONFIG,
+
+        'captype' => 'write',
+        'contextlevel' => CONTEXT_SYSTEM,
+        'legacy' => array(
+            'manager' => CAP_ALLOW
+        )
+    ),
+
+    // can the user manage another user's profile page?
+    'moodle/user:manageblocks' => array(
+
+        'riskbitmap' => RISK_SPAM | RISK_PERSONAL,
+
+        'captype' => 'write',
+        'contextlevel' => CONTEXT_USER
+    ),
+
+    // can the user manage their own profile page?
+    'moodle/user:manageownblocks' => array(
+
+        'riskbitmap' => RISK_SPAM | RISK_PERSONAL,
+
+        'captype' => 'write',
+        'contextlevel' => CONTEXT_SYSTEM,
+        'legacy' => array(
+            'user' => CAP_ALLOW,
+        )
+    ),
+
+    // can the user manage the system default dashboard page?
+    'moodle/my:configsyspages' => array(
+
+        'riskbitmap' => RISK_SPAM | RISK_PERSONAL | RISK_CONFIG,
+
+        'captype' => 'write',
+        'contextlevel' => CONTEXT_SYSTEM,
+        'legacy' => array(
+            'manager' => CAP_ALLOW
+        )
+    ),
+
     'moodle/role:assign' => array(
 
         'riskbitmask' => RISK_SPAM | RISK_PERSONAL | RISK_XSS,
Index: lib/db/install.xml
===================================================================
RCS file: /cvsroot/moodle/moodle/lib/db/install.xml,v
retrieving revision 1.248
diff -u -r1.248 install.xml
--- lib/db/install.xml	2 May 2010 17:35:52 -0000	1.248
+++ lib/db/install.xml	4 May 2010 09:24:48 -0000
@@ -587,7 +587,7 @@
         <INDEX NAME="userid-contactid" UNIQUE="true" FIELDS="userid, contactid"/>
       </INDEXES>
     </TABLE>
-    <TABLE NAME="modules" COMMENT="modules available in the site" PREVIOUS="message_contacts" NEXT="sessions">
+    <TABLE NAME="modules" COMMENT="modules available in the site" PREVIOUS="message_contacts" NEXT="my_pages">
       <FIELDS>
         <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="true" NEXT="name"/>
         <FIELD NAME="name" TYPE="char" LENGTH="20" NOTNULL="true" SEQUENCE="false" PREVIOUS="id" NEXT="version"/>
@@ -604,7 +604,22 @@
         <INDEX NAME="name" UNIQUE="false" FIELDS="name"/>
       </INDEXES>
     </TABLE>
-    <TABLE NAME="sessions" COMMENT="Database based session storage - now recommended" PREVIOUS="modules" NEXT="timezone">
+    <TABLE NAME="my_pages" COMMENT="Extra user pages for the My Moodle system" PREVIOUS="modules" NEXT="sessions">
+      <FIELDS>
+        <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="true" NEXT="userid"/>
+        <FIELD NAME="userid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" COMMENT="The user who owns this page or 0 for system defaults" PREVIOUS="id" NEXT="name"/>
+        <FIELD NAME="name" TYPE="char" LENGTH="200" NOTNULL="true" SEQUENCE="false" COMMENT="The page name (freeform text)" PREVIOUS="userid" NEXT="private"/>
+        <FIELD NAME="private" TYPE="int" LENGTH="1" NOTNULL="true" UNSIGNED="true" DEFAULT="1" SEQUENCE="false" COMMENT="Whether or not the page is private (dashboard) or public (profile)" PREVIOUS="name" NEXT="sortorder"/>
+        <FIELD NAME="sortorder" TYPE="int" LENGTH="6" NOTNULL="true" UNSIGNED="false" DEFAULT="0" SEQUENCE="false" COMMENT="The order of the pages for a user" PREVIOUS="private"/>
+      </FIELDS>
+      <KEYS>
+        <KEY NAME="id" TYPE="primary" FIELDS="id"/>
+      </KEYS>
+      <INDEXES>
+        <INDEX NAME="user_idx" UNIQUE="false" FIELDS="userid, private"/>
+      </INDEXES>
+    </TABLE>
+    <TABLE NAME="sessions" COMMENT="Database based session storage - now recommended" PREVIOUS="my_pages" NEXT="timezone">
       <FIELDS>
         <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="true" NEXT="state"/>
         <FIELD NAME="state" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" COMMENT="0 means normal session" PREVIOUS="id" NEXT="sid"/>
@@ -2596,4 +2611,12 @@
       </INDEXES>
     </TABLE>
   </TABLES>
-</XMLDB>
\ No newline at end of file
+  <STATEMENTS>
+    <STATEMENT NAME="insert my_pages" TYPE="insert" TABLE="my_pages" COMMENT="Initial insert of records on table my_pages">
+      <SENTENCES>
+        <SENTENCE TEXT="(userid, name, private, sortorder) VALUES (0, '__default', 0, 0)" />
+        <SENTENCE TEXT="(userid, name, private, sortorder) VALUES (0, '__default', 1, 0)" />
+      </SENTENCES>
+    </STATEMENT>
+  </STATEMENTS>
+</XMLDB>
Index: lib/db/upgrade.php
===================================================================
RCS file: /cvsroot/moodle/moodle/lib/db/upgrade.php,v
retrieving revision 1.402
diff -u -r1.402 upgrade.php
--- lib/db/upgrade.php	2 May 2010 17:35:52 -0000	1.402
+++ lib/db/upgrade.php	4 May 2010 09:24:49 -0000
@@ -3928,6 +3928,49 @@
     }
 
 
+    if ($result && $oldversion < 2010050400) {  // my_pages for My Moodle and Public Profile pages
+
+    /// Define table my_pages to be created
+        $table = new xmldb_table('my_pages');
+
+    /// Adding fields to table my_pages
+        $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
+        $table->add_field('userid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, 0);
+        $table->add_field('name', XMLDB_TYPE_CHAR, '200', null, XMLDB_NOTNULL, null, null);
+        $table->add_field('private', XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, 0);
+        $table->add_field('sortorder', XMLDB_TYPE_INTEGER, '6', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
+
+
+    /// Adding keys to table my_pages
+        $table->add_key('id', XMLDB_KEY_PRIMARY, array('id'));
+
+    /// Adding indexes to table my_pages
+        $table->add_index('useridprivate', XMLDB_INDEX_NOTUNIQUE, array('userid', 'private'));
+
+    /// Conditionally launch create table for my_pages
+        if (!$dbman->table_exists($table)) {
+            $dbman->create_table($table);
+        }
+
+    /// Add two lines of data into this new table
+        $mypage = new object();
+        $mypage->userid = 0;
+        $mypage->name = '__default';
+        $mypage->private = 0;
+        $mypage->sortorder  = 0;
+        if (!$DB->record_exists('my_pages', array('userid'=>0, 'private'=>0))) {
+            $result = $result && $DB->insert_record('my_pages', $mypage);
+        }
+        $mypage->private = 1;
+        if (!$DB->record_exists('my_pages', array('userid'=>0, 'private'=>1))) {
+            $result = $result && $DB->insert_record('my_pages', $mypage);
+        }
+
+    /// Main savepoint reached
+        upgrade_main_savepoint($result, 2010050400);
+    }
+
+
     return $result;
 }
 
Index: mod/forum/user.php
===================================================================
RCS file: /cvsroot/moodle/moodle/mod/forum/user.php,v
retrieving revision 1.52
diff -u -r1.52 user.php
--- mod/forum/user.php	17 Feb 2010 16:59:43 -0000	1.52
+++ mod/forum/user.php	4 May 2010 09:24:54 -0000
@@ -94,11 +94,7 @@
 $PAGE->set_title("$course->shortname: $fullname: $strmode");
 $PAGE->set_heading($course->fullname);
 echo $OUTPUT->header();
-
-$currenttab = $mode;
-$showroles = 1;
-require($CFG->dirroot.'/user/tabs.php');   /// Prints out tabs as part of user page
-
+echo $OUTPUT->heading($fullname);
 
 switch ($mode) {
     case 'posts' :
Index: my/index.php
===================================================================
RCS file: /cvsroot/moodle/moodle/my/index.php,v
retrieving revision 1.47
diff -u -r1.47 index.php
--- my/index.php	19 Apr 2010 06:30:32 -0000	1.47
+++ my/index.php	4 May 2010 09:24:54 -0000
@@ -1,98 +1,141 @@
 <?php
 
-    // this is the 'my moodle' page
-
-    require_once(dirname(__FILE__) . '/../config.php');
-    require_once($CFG->dirroot.'/course/lib.php');
-
-    require_login();
-
-    $strmymoodle = get_string('mymoodle','my');
-
-    if (isguestuser()) {
-        $PAGE->set_title($strmymoodle);
-        echo $OUTPUT->header();
-        echo $OUTPUT->confirm(get_string('noguest', 'my') . '<br /><br />' . get_string('liketologin'), get_login_url(), $CFG->wwwroot);
-        echo $OUTPUT->footer();
-        die;
-    }
-
-    $edit = optional_param('edit', -1, PARAM_BOOL);
-    $blockaction = optional_param('blockaction', '', PARAM_ALPHA);
-
-    $PAGE->set_context(get_context_instance(CONTEXT_USER, $USER->id));
-    $PAGE->set_url('/my/index.php');
-    $PAGE->set_pagelayout('mydashboard');
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * My Moodle -- a user's personal dashboard
+ *
+ * - each user can currently have their own page (cloned from system and then customised)
+ * - only the user can see their own dashboard
+ * - users can add any blocks they want
+ * - the administrators can define a default site dashboard for users who have
+ *   not created their own dashboard
+ *
+ * This script implements the user's view of the dashboard, and allows editing
+ * of the dashboard.
+ *
+ * @package    moodlecore
+ * @subpackage my
+ * @copyright  2010 Remote-Learner.net
+ * @author     Hubert Chathi <hubert@remote-learner.net>
+ * @author     Olav Jordan <olav.jordan@remote-learner.net>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+require_once(dirname(__FILE__) . '/../config.php');
+require_once($CFG->dirroot . '/my/lib.php');
+
+redirect_if_major_upgrade_required();
+
+$edit   = optional_param('edit', null, PARAM_BOOL);    // Turn editing on and off
+
+require_login();
+
+$strmymoodle = get_string('myhome');
+
+if (isguestuser()) {  // Force them to see system default, no editing allowed
+    $userid = 0; 
+    $USER->editing = $edit = 0;  // Just in case
+    $context = get_context_instance(CONTEXT_SYSTEM);
+    $PAGE->set_blocks_editing_capability('moodle/my:configsyspages');  // unlikely :)
+    $header = "$SITE->shortname: $strmymoodle (GUEST)";
+
+} else {        // We are trying to view or edit our own My Moodle page
+    $userid = $USER->id;  // Owner of the page
+    $context = get_context_instance(CONTEXT_USER, $USER->id);
     $PAGE->set_blocks_editing_capability('moodle/my:manageblocks');
+    $header = "$SITE->shortname: $strmymoodle";
+}
 
-    if (($edit != -1) and $PAGE->user_allowed_editing()) {
-        $USER->editing = $edit;
+// Get the My Moodle page info.  Should always return something unless the database is broken.
+if (!$currentpage = my_get_page($userid, MY_PAGE_PRIVATE)) {
+    print_error('mymoodlesetup');
+}
+
+if (!$currentpage->userid) {
+    $context = get_context_instance(CONTEXT_SYSTEM);  // So we even see non-sticky blocks
+}
+
+// Start setting up the page
+$params = array();
+$PAGE->set_context($context);
+$PAGE->set_url('/my/index.php', $params);
+$PAGE->set_pagelayout('mydashboard');
+$PAGE->set_pagetype('my-index');
+$PAGE->blocks->add_region('content');
+$PAGE->set_subpage($currentpage->id);
+$PAGE->set_title($header);
+$PAGE->set_heading($header);
+
+// Toggle the editing state and switches
+if ($PAGE->user_allowed_editing()) {
+    if ($edit !== null) {             // Editing state was specified
+        $USER->editing = $edit;       // Change editing state
+        if (!$currentpage->userid && $edit) {
+            // If we are viewing a system page as ordinary user, and the user turns
+            // editing on, copy the system pages as new user pages, and get the
+            // new page record
+            if (!$currentpage = my_copy_page($USER->id, MY_PAGE_PRIVATE)) {
+                print_error('mymoodlesetup');
+            }
+            $context = get_context_instance(CONTEXT_USER, $USER->id);
+            $PAGE->set_context($context);
+            $PAGE->set_subpage($currentpage->id);
+        }
+    } else {                          // Editing state is in session
+        if ($currentpage->userid) {   // It's a page we can edit, so load from session
+            if (!empty($USER->editing)) {
+                $edit = 1;
+            } else {
+                $edit = 0;
+            }
+        } else {                      // It's a system page and they are not allowed to edit system pages
+            $USER->editing = $edit = 0;          // Disable editing completely, just to be safe
+        }
     }
 
-    if (!empty($USER->editing)) {
-        $string = get_string('updatemymoodleoff');
-        $edit = '0';
+    // Add button for editing page
+    $params = array('edit' => !$edit);
+
+    if (!$currentpage->userid) {
+        // viewing a system page -- let the user customise it
+        $editstring = get_string('updatemymoodleon');
+        $params['edit'] = 1;
+    } else if (empty($edit)) {
+        $editstring = get_string('updatemymoodleon');
     } else {
-        $string = get_string('updatemymoodleon');
-        $edit = '1';
+        $editstring = get_string('updatemymoodleoff');
     }
 
-    $url = new moodle_url("$CFG->wwwroot/my/index.php", array('edit' => $edit));
-    $button = $OUTPUT->single_button($url, $string);
-
-    $header = $SITE->shortname . ': ' . $strmymoodle;
-
-    $PAGE->set_title($strmymoodle);
-    $PAGE->set_heading($header);
+    $url = new moodle_url("$CFG->wwwroot/my/index.php", $params);
+    $button = $OUTPUT->single_button($url, $editstring);
     $PAGE->set_button($button);
-    echo $OUTPUT->header();
-
-/// The main overview in the middle of the page
 
-    // limits the number of courses showing up
-    $courses_limit = 21;
-    if (isset($CFG->mycoursesperpage)) {
-        $courses_limit = $CFG->mycoursesperpage;
-    }
-
-    $morecourses = false;
-    if ($courses_limit > 0) {
-        $courses_limit = $courses_limit + 1;
-    }
+} else {
+    $USER->editing = $edit = 0;
+}
 
-    $courses = get_my_courses($USER->id, 'visible DESC,sortorder ASC', '*', false, $courses_limit);
-    $site = get_site();
-    $course = $site; //just in case we need the old global $course hack
-
-    if (($courses_limit > 0) && (count($courses) >= $courses_limit)) {
-        //remove the 'marker' course that we retrieve just to see if we have more than $courses_limit
-        array_pop($courses);
-        $morecourses = true;
-    }
+// HACK WARNING!  This loads up all this page's blocks in the system context
+if ($currentpage->userid == 0) {
+    $CFG->blockmanagerclass = 'my_syspage_block_manager';
+}
 
 
-    if (array_key_exists($site->id,$courses)) {
-        unset($courses[$site->id]);
-    }
-
-    foreach ($courses as $c) {
-        if (isset($USER->lastcourseaccess[$c->id])) {
-            $courses[$c->id]->lastaccess = $USER->lastcourseaccess[$c->id];
-        } else {
-            $courses[$c->id]->lastaccess = 0;
-        }
-    }
-
-    if (empty($courses)) {
-        echo $OUTPUT->box(get_string('nocourses','my'));
-    } else {
-        print_overview($courses);
-    }
-
-    // if more than 20 courses
-    if ($morecourses) {
-        echo '<br />...';
-    }
+echo $OUTPUT->header();
 
-    echo $OUTPUT->footer();
+echo $OUTPUT->blocks_for_region('content');
 
+echo $OUTPUT->footer();
Index: my/indexsys.php
===================================================================
RCS file: my/indexsys.php
diff -N my/indexsys.php
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ my/indexsys.php	4 May 2010 09:24:54 -0000
@@ -0,0 +1,111 @@
+<?php
+
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * My Moodle -- a user's personal dashboard
+ *
+ * - each user can currently have their own page (cloned from system and then customised)
+ * - only the user can see their own dashboard
+ * - users can add any blocks they want
+ * - the administrators can define a default site dashboard for users who have
+ *   not created their own dashboard
+ *
+ * This script implements the user's view of the dashboard, and allows editing
+ * of the dashboard.
+ *
+ * @package    moodlecore
+ * @subpackage my
+ * @copyright  2010 Remote-Learner.net
+ * @author     Hubert Chathi <hubert@remote-learner.net>
+ * @author     Olav Jordan <olav.jordan@remote-learner.net>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+require_once(dirname(__FILE__) . '/../config.php');
+require_once($CFG->dirroot . '/my/lib.php');
+require_once($CFG->libdir.'/adminlib.php');
+
+$edit   = optional_param('edit', null, PARAM_BOOL);    // Turn editing on and off
+
+require_login();
+
+$strmymoodle = get_string('myhome');
+
+$context = get_context_instance(CONTEXT_SYSTEM);
+require_capability('moodle/my:configsyspages', $context);
+$PAGE->set_blocks_editing_capability('moodle/my:configsyspages');
+$header = "$SITE->shortname: $strmymoodle (DEFAULT)";
+
+// Start setting up the page
+$params = array();
+$PAGE->set_url('/my/indexsys.php', $params);
+$PAGE->set_pagelayout('mydashboard');
+$PAGE->set_pagetype('my-index');
+$PAGE->set_context($context);
+$PAGE->set_title($header);
+$PAGE->set_heading($header);
+$PAGE->blocks->add_region('content');
+
+// TODO: Make the page be selected properly in the Settings block
+
+// Get the My Moodle page info.  Should always return something unless the database is broken.
+if (!$currentpage = my_get_page(0, MY_PAGE_PRIVATE)) {
+    print_error('mymoodlesetup');
+}
+$PAGE->set_subpage($currentpage->id);
+
+
+// Toggle the editing state and switches
+if ($PAGE->user_allowed_editing()) {
+    if ($edit !== null) {             // Editing state was specified
+        $USER->editing = $edit;       // Change editing state
+    } else {                          // Editing state is in session
+        if (!empty($USER->editing)) {
+            $edit = 1;
+        } else {
+            $edit = 0;
+        }
+    }
+
+    // Add button for editing page
+    $params['edit'] = !$edit;
+
+    if (empty($edit)) {
+        $editstring = get_string('updatemymoodleon');
+    } else {
+        $editstring = get_string('updatemymoodleoff');
+    }
+
+    $url = new moodle_url("$CFG->wwwroot/my/indexsys.php", $params);
+    $button = $OUTPUT->single_button($url, $editstring);
+    $PAGE->set_button($button);
+
+} else {
+    $USER->editing = $edit = 0;
+}
+
+// HACK WARNING!  This loads up all this page's blocks in the system context
+if ($currentpage->userid == 0) {
+    $CFG->blockmanagerclass = 'my_syspage_block_manager';
+}
+
+
+echo $OUTPUT->header();
+
+echo $OUTPUT->blocks_for_region('content');
+
+echo $OUTPUT->footer();
Index: my/lib.php
===================================================================
RCS file: my/lib.php
diff -N my/lib.php
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ my/lib.php	4 May 2010 09:24:54 -0000
@@ -0,0 +1,122 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * My Moodle -- a user's personal dashboard
+ *
+ * This file contains common functions for the dashboard and profile pages.
+ *
+ * @package    moodlecore
+ * @subpackage my
+ * @copyright  2010 Remote-Learner.net
+ * @author     Hubert Chathi <hubert@remote-learner.net>
+ * @author     Olav Jordan <olav.jordan@remote-learner.net>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+define('MY_PAGE_PUBLIC', 0); 
+define('MY_PAGE_PRIVATE', 1);
+
+require_once("$CFG->libdir/blocklib.php");
+
+/* 
+ * For a given user, this returns the $page information for their My Moodle page
+ *
+ */
+function my_get_page($userid, $private=MY_PAGE_PRIVATE) {
+    global $DB, $CFG;
+
+    if (empty($CFG->forcedefaultmymoodle)) {   // We ignore custom My Moodle pages if admin has forced them
+        // Does the user have their own page defined?  If so, return it.
+        if ($customised = $DB->get_record('my_pages', array('userid' => $userid, 'private' => $private))) {
+            return $customised;
+        }
+    }
+
+    // Otherwise return the system default page
+    return $DB->get_record('my_pages', array('userid' => 0, 'name' => '__default', 'private' => $private));
+}
+
+
+/*
+ * This copies a system default page to the current user
+ *
+ */
+function my_copy_page($userid, $private=MY_PAGE_PRIVATE, $pagetype='my-index') {
+    global $DB;
+
+    if ($customised = $DB->record_exists('my_pages', array('userid' => $userid, 'private' => $private))) {
+        return $customised;  // We're done!
+    }
+
+    // Get the system default page
+    if (!$systempage = $DB->get_record('my_pages', array('userid' => 0, 'private' => $private))) {
+        return false;  // error
+    }
+
+    // Clone the basic system page record
+    $page = clone($systempage);
+    unset($page->id);
+    $page->userid = $userid;
+    if (!$page->id = $DB->insert_record('my_pages', $page)) {
+        return false;
+    }
+    
+    // Clone ALL the associated blocks as well
+    $systemcontext = get_context_instance(CONTEXT_SYSTEM);
+    $usercontext = get_context_instance(CONTEXT_USER, $userid);
+
+    $blockinstances = $DB->get_records('block_instances', 
+                           array('parentcontextid' => $systemcontext->id,
+                                 'pagetypepattern' => $pagetype,
+                                 'subpagepattern' => $systempage->id,
+                                           ));
+    foreach ($blockinstances as $instance) {
+        unset($instance->id);
+        $instance->parentcontextid = $usercontext->id;
+        $instance->subpagepattern = $page->id;
+        if ($instance->id = $DB->insert_record('block_instances', $instance)) {
+            $blockcontext = get_context_instance(CONTEXT_BLOCK, $instance->id);  // Just creates the context record
+        }
+    }
+
+    // FIXME: block position overrides should be merged in with block instance
+    //$blockpositions = $DB->get_records('block_positions', array('subpage' => $page->name));
+    //foreach($blockpositions as $positions) {
+    //    $positions->subpage = $page->name;
+    //    $DB->insert_record('block_positions', $tc);
+    //}
+
+    return $page;
+}
+
+class my_syspage_block_manager extends block_manager {
+    // HACK WARNING!
+    // TODO: figure out a better way to do this
+    /**
+     * Load blocks using the system context, rather than the user's context.
+     *
+     * This is needed because the My Moodle pages set the page context to the
+     * user's context for access control, etc.  But the blocks for the system
+     * pages are stored in the system context.
+     */
+    public function load_blocks($includeinvisible = null) {
+        $origcontext = $this->page->context;
+        $this->page->context = get_context_instance(CONTEXT_SYSTEM);
+        parent::load_blocks($includeinvisible);
+        $this->page->context = $origcontext;
+    }
+}
Index: my/page_form.php
===================================================================
RCS file: my/page_form.php
diff -N my/page_form.php
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ my/page_form.php	4 May 2010 09:24:54 -0000
@@ -0,0 +1,154 @@
+<?php
+
+/**
+ * forms for adding and deleting pages
+ *
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+require_once($CFG->dirroot . '/lib/formslib.php');
+
+/**
+ * form for adding in sub pages
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class my_page_add_form extends moodleform {
+    /**
+     * defines items in the form
+     */
+    public function definition() {
+        $mform = &$this->_form;
+
+        $mform->addElement('text', 'pagename', get_string('name'));
+        $mform->setType('pagename', PARAM_TEXT);
+        $mform->addRule('pagename', null, 'required', null, 'client');
+
+        $mform->addElement('text', 'sortorder', get_string('sortorder'));
+        $mform->setType('sortorder', PARAM_INT);
+        $mform->setDefault('sortorder', 0);
+
+        $this->add_action_buttons();
+    }
+}
+
+/**
+ * form for deleteing sub pages
+ */
+class my_page_delete_form extends moodleform {
+    /**
+     * defines items in the form
+     */
+    public function definition() {
+        global $USER, $DB;
+
+        $mform = &$this->_form;
+
+        $mypages = $DB->get_records_select('my_pages', 'userid = ? AND name != ""', array('userid' => $USER->id), 'sortorder');
+
+        if(is_array($mypages)) {
+            foreach($mypages as $mypage) {
+                $mform->addElement('advcheckbox', "page[$mypage->id]", get_string('removepage', null, $mypage->name), null, null, array(-1, $mypage->id));
+            }
+
+            $this->add_action_buttons();
+        }
+    }
+}
+
+/**
+ * form for deleting system sub pages
+ */
+class my_page_deletesys_form extends moodleform {
+    /**
+     * defines system pages to delete
+     */
+    public function definition() {
+        global $DB;
+
+        $mform = &$this->_form;
+
+        $mypages = $DB->get_records_select('my_pages', 'userid = ? AND name != ""', array('userid' => 0), 'sortorder');
+
+        if(is_array($mypages)) {
+            foreach($mypages as $mypage) {
+                $mform->addElement('advcheckbox', "page[$mypage->id]", get_string('removepage', null, $mypage->name), null, null, array(-1, $mypage->id));
+            }
+
+            $this->add_action_buttons();
+        }
+    }
+}
+
+/**
+ * form for configuring a sub page
+ * setting name and sort order
+ */
+class my_page_config_form extends moodleform {
+    /**
+     * defines items in the form
+     */
+    public function definition() {
+        global $USER, $DB;
+
+        $mform = &$this->_form;
+
+        $mypages = $DB->get_records_select('my_pages', 'userid = ? AND name != ?', array('userid' => $USER->id, 'name' => ''), 'sortorder');
+
+        if(is_array($mypages)) {
+            $prepend = array(' ' . get_string('sortorder') . ': ');
+
+            foreach($mypages as $mypage) {
+                $mform->addElement('static', "name[$mypage->id]", '<b>' . $mypage->name . ':</b>');
+
+                $group = array();
+                $group[] = $mform->createElement('text', 'page');
+                $group[] = $mform->createElement('text', 'order');
+
+                $mform->addGroup($group, "config[$mypage->id]", get_string('name') . ': ', $prepend);
+
+                $mform->addGroupRule("config[$mypage->id]", array("order" => array(array(null, 'numeric', null, 'client'), "page" => array(null, 'required', null, 'client'))));
+            }
+
+            $this->add_action_buttons();
+        }
+    }
+}
+
+/**
+ * form for configuring a sub page
+ * setting name and sort order
+ */
+class my_page_configsys_form extends moodleform {
+    /**
+     * defines items in the form
+     */
+    public function definition() {
+        global $USER, $DB;
+
+        $mform = &$this->_form;
+
+        $mypages = $DB->get_records_select('my_pages', 'userid = ? AND name != ?', array('userid' => 0, 'name' => ''), 'sortorder');
+
+        if(is_array($mypages)) {
+            $prepend = array(' ' . get_string('sortorder') . ': '
+                                 //,' ' . get_string('locked') . ': '
+                                );
+
+            foreach($mypages as $mypage) {
+                $mform->addElement('static', "name[$mypage->id]", '<b>' . $mypage->name . ':</b>');
+
+                $group = array();
+                $group[] = $mform->createElement('text', 'page');
+                $group[] = $mform->createElement('text', 'order');
+                //$group[] = $mform->createElement('checkbox', 'locked');         //display only no field in database to set a page to be locked
+
+                $mform->addGroup($group, "config[$mypage->id]", get_string('name') . ': ', $prepend);
+
+                $mform->addGroupRule("config[$mypage->id]", array("order" => array(array(null, 'numeric', null, 'client'), "page" => array(null, 'required', null, 'client'))));
+            }
+
+            $this->add_action_buttons();
+        }
+    }
+}
+?>
Index: notes/edit.php
===================================================================
RCS file: /cvsroot/moodle/moodle/notes/edit.php,v
retrieving revision 1.19
diff -u -r1.19 edit.php
--- notes/edit.php	16 Jan 2010 15:39:59 -0000	1.19
+++ notes/edit.php	4 May 2010 09:24:54 -0000
@@ -29,8 +29,8 @@
 
     $url->param('courseid', $courseid);
     $url->param('userid', $userid);
-    if ($publishstate !== NOTES_STATE_PUBLIC) {
-        $url->param('publishstate', $publishstate);
+    if ($state !== NOTES_STATE_PUBLIC) {
+        $url->param('publishstate', $state);
     }
 }
 
Index: notes/index.php
===================================================================
RCS file: /cvsroot/moodle/moodle/notes/index.php,v
retrieving revision 1.22
diff -u -r1.22 index.php
--- notes/index.php	19 Apr 2010 06:30:34 -0000	1.22
+++ notes/index.php	4 May 2010 09:24:54 -0000
@@ -89,11 +89,11 @@
 $PAGE->set_heading($course->fullname);
 
 echo $OUTPUT->header();
-echo $OUTPUT->heading(fullname($user));
-
-$showroles = 1;
-$currenttab = 'notes';
-require($CFG->dirroot .'/user/tabs.php');
+if ($userid) {
+    echo $OUTPUT->heading(fullname($user).': '.$strnotes);
+} else {
+    echo $OUTPUT->heading($course->shortname.': '.$strnotes);
+}
 
 $strsitenotes = get_string('sitenotes', 'notes');
 $strcoursenotes = get_string('coursenotes', 'notes');
Index: user/edit.php
===================================================================
RCS file: /cvsroot/moodle/moodle/user/edit.php,v
retrieving revision 1.201
diff -u -r1.201 edit.php
--- user/edit.php	20 Apr 2010 03:42:55 -0000	1.201
+++ user/edit.php	4 May 2010 09:24:55 -0000
@@ -252,11 +252,6 @@
 
 echo $OUTPUT->header();
 
-/// Print tabs at the top
-$showroles = 1;
-$currenttab = 'editprofile';
-require('tabs.php');
-
 if ($email_changed) {
     echo $email_changed_html;
 } else {
Index: user/editadvanced.php
===================================================================
RCS file: /cvsroot/moodle/moodle/user/editadvanced.php,v
retrieving revision 1.71
diff -u -r1.71 editadvanced.php
--- user/editadvanced.php	4 May 2010 02:27:02 -0000	1.71
+++ user/editadvanced.php	4 May 2010 09:24:55 -0000
@@ -259,10 +259,7 @@
     $PAGE->set_heading($course->fullname);
 
     echo $OUTPUT->header();
-    /// Print tabs at the top
-    $showroles = 1;
-    $currenttab = 'editprofile';
-    require('tabs.php');
+    echo $OUTPUT->heading($userfullname);
 }
 
 /// Finally display THE form
Index: user/index.php
===================================================================
RCS file: /cvsroot/moodle/moodle/user/index.php,v
retrieving revision 1.271
diff -u -r1.271 index.php
--- user/index.php	21 Apr 2010 07:36:34 -0000	1.271
+++ user/index.php	4 May 2010 09:24:55 -0000
@@ -140,6 +140,8 @@
     $PAGE->navbar->add(get_string('participants'));
     $PAGE->set_title("$course->shortname: ".get_string('participants'));
     $PAGE->set_heading($course->fullname);
+    $PAGE->set_pagetype('course-view-' . $course->format);
+    $PAGE->set_other_editing_capability('moodle/course:manageactivities');
 
     echo $OUTPUT->header();
 
@@ -150,6 +152,7 @@
         exit;
     }
 
+
     // Should use this variable so that we don't break stuff every time a variable is added or changed.
     $baseurl = new moodle_url('/user/index.php', array(
             'contextid' => $context->id,
@@ -169,11 +172,8 @@
         $filtertype = 'group';
         $filterselect = $currentgroup;
     }
-    $currenttab = 'participants';
-    $user = $USER;
-    $userindexpage = true;
 
-    require_once($CFG->dirroot .'/user/tabs.php');
+
 
 /// Get the hidden field list
     if (has_capability('moodle/course:viewhiddenuserfields', $context)) {
Index: user/profile.php
===================================================================
RCS file: user/profile.php
diff -N user/profile.php
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ user/profile.php	4 May 2010 09:24:55 -0000
@@ -0,0 +1,372 @@
+<?php
+
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * Public Profile -- a user's public profile page
+ *
+ * - each user can currently have their own page (cloned from system and then customised)
+ * - users can add any blocks they want
+ * - the administrators can define a default site public profile for users who have
+ *   not created their own public profile
+ *
+ * This script implements the user's view of the public profile, and allows editing
+ * of the public profile.
+ *
+ * @package    moodlecore
+ * @subpackage my
+ * @copyright  2010 Remote-Learner.net
+ * @author     Hubert Chathi <hubert@remote-learner.net>
+ * @author     Olav Jordan <olav.jordan@remote-learner.net>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+require_once(dirname(__FILE__) . '/../config.php');
+require_once($CFG->dirroot . '/my/lib.php');
+require_once($CFG->dirroot . '/user/profile/lib.php');
+
+$userid = optional_param('id', 0, PARAM_INT);
+$edit   = optional_param('edit', null, PARAM_BOOL);    // Turn editing on and off
+
+if (!empty($CFG->forceloginforprofiles)) {
+    require_login();
+    if (isguestuser()) {
+        redirect(get_login_url());
+    }
+} else if (!empty($CFG->forcelogin)) {
+    require_login();
+}
+
+$userid = $userid ? $userid : $USER->id;       // Owner of the page
+$user = $DB->get_record('user', array('id' => $userid));
+$currentuser = ($user->id == $USER->id);
+$context = $usercontext = get_context_instance(CONTEXT_USER, $userid, MUST_EXIST);
+
+if (!$currentuser &&
+    !empty($CFG->forceloginforprofiles) && 
+    !has_capability('moodle/user:viewdetails', $context) && 
+    !has_coursemanager_role($userid)) {
+    // Course managers can be browsed at site level. If not forceloginforprofiles, allow access (bug #4366)
+    $struser = get_string('user');
+    $PAGE->set_title("$SITE->shortname: $struser");
+    $PAGE->set_heading("$SITE->shortname: $struser");
+    $PAGE->set_url('/user/profile.php', array('id'=>$userid));
+    $PAGE->navbar->add($struser);
+    echo $OUTPUT->header();
+    echo $OUTPUT->heading(get_string('usernotavailable', 'error'));
+    echo $OUTPUT->footer();
+    exit;
+}
+
+// Get the profile page.  Should always return something unless the database is broken.
+if (!$currentpage = my_get_page($userid, MY_PAGE_PUBLIC)) {
+    print_error('mymoodlesetup');
+}
+
+if (!$currentpage->userid) {
+    $context = get_context_instance(CONTEXT_SYSTEM);  // A trick so that we even see non-sticky blocks
+}
+
+$PAGE->set_context($context);
+$PAGE->set_pagelayout('mydashboard');
+$PAGE->set_pagetype('user-profile');
+
+// Set up block editing capabilities
+if (isguestuser()) {     // Guests can never edit their profile
+    $USER->editing = $edit = 0;  // Just in case
+    $PAGE->set_blocks_editing_capability('moodle/my:configsyspages');  // unlikely :)
+} else {
+    if ($currentuser) {
+        $PAGE->set_blocks_editing_capability('moodle/user:manageownblocks');
+    } else {
+        $PAGE->set_blocks_editing_capability('moodle/user:manageblocks');
+    }
+}
+
+
+
+// Start setting up the page
+$strpublicprofile = get_string('publicprofile');
+
+$params = array('id'=>$userid);
+$PAGE->set_url('/user/profile.php', $params);
+$PAGE->blocks->add_region('content');
+$PAGE->set_subpage($currentpage->id);
+$PAGE->set_title("$SITE->shortname: $strpublicprofile");
+$PAGE->set_heading("$SITE->shortname: $strpublicprofile");
+$PAGE->navigation->extend_for_user($user);
+
+
+// Toggle the editing state and switches
+if ($PAGE->user_allowed_editing()) {
+    if ($edit !== null) {             // Editing state was specified
+        $USER->editing = $edit;       // Change editing state
+        if (!$currentpage->userid && $edit) {
+            // If we are viewing a system page as ordinary user, and the user turns
+            // editing on, copy the system pages as new user pages, and get the
+            // new page record
+            if (!$currentpage = my_copy_page($USER->id, MY_PAGE_PUBLIC, 'user-profile')) {
+                print_error('mymoodlesetup');
+            }
+            $PAGE->set_context($usercontext);
+            $PAGE->set_subpage($currentpage->id);
+        }
+    } else {                          // Editing state is in session
+        if ($currentpage->userid) {   // It's a page we can edit, so load from session
+            if (!empty($USER->editing)) {
+                $edit = 1;
+            } else {
+                $edit = 0;
+            }
+        } else {                      // It's a system page and they are not allowed to edit system pages
+            $USER->editing = $edit = 0;          // Disable editing completely, just to be safe
+        }
+    }
+
+    // Add button for editing page
+    $params = array('edit' => !$edit);
+
+    if (!$currentpage->userid) {
+        // viewing a system page -- let the user customise it
+        $editstring = get_string('updatemymoodleon');
+        $params['edit'] = 1;
+    } else if (empty($edit)) {
+        $editstring = get_string('updatemymoodleon');
+    } else {
+        $editstring = get_string('updatemymoodleoff');
+    }
+
+    $url = new moodle_url("$CFG->wwwroot/user/profile.php", $params);
+    $button = $OUTPUT->single_button($url, $editstring);
+    $PAGE->set_button($button);
+
+} else {
+    $USER->editing = $edit = 0;
+}
+
+// HACK WARNING!  This loads up all this page's blocks in the system context
+if ($currentpage->userid == 0) {
+    $CFG->blockmanagerclass = 'my_syspage_block_manager';
+}
+
+// TODO WORK OUT WHERE THE NAV BAR IS!
+echo $OUTPUT->header();
+
+
+// Print the standard content of this page, the basic profile info
+
+echo $OUTPUT->heading(fullname($user));
+
+if (is_mnet_remote_user($user)) {
+    $sql = "
+         SELECT DISTINCT h.id, h.name, h.wwwroot,
+                a.name as application, a.display_name
+           FROM {mnet_host} h, {mnet_application} a
+          WHERE h.id = ? AND h.applicationid = a.id
+       ORDER BY a.display_name, h.name";
+
+    $remotehost = $DB->get_record_sql($sql, array($user->mnethostid));
+
+    echo '<p class="errorboxcontent">'.get_string('remoteappuser', $remotehost->application)." <br />\n";
+    if ($currentuser) {
+        if ($remotehost->application =='moodle') {
+            echo "Remote {$remotehost->display_name}: <a href=\"{$remotehost->wwwroot}/user/edit.php\">{$remotehost->name}</a> ".get_string('editremoteprofile')." </p>\n";
+        } else {
+            echo "Remote {$remotehost->display_name}: <a href=\"{$remotehost->wwwroot}/\">{$remotehost->name}</a> ".get_string('gotoyourserver')." </p>\n";
+        }
+    } else {
+        echo "Remote {$remotehost->display_name}: <a href=\"{$remotehost->wwwroot}/\">{$remotehost->name}</a></p>\n";
+    }
+}
+
+echo '<div class="profilepicture">';
+echo $OUTPUT->user_picture($user, array('size'=>100));
+echo '</div>';
+
+echo '<div class="description">';
+// Print the description
+
+if ($user->description && !isset($hiddenfields['description'])) {
+    if (!empty($CFG->profilesforenrolledusersonly) && !$currentuser && !$DB->record_exists('role_assignments', array('userid'=>$user->id))) {
+        echo get_string('profilenotshown', 'moodle');
+    } else {
+        $user->description = file_rewrite_pluginfile_urls($user->description, 'pluginfile.php', $usercontext->id, 'user_profile', $user->id);
+        echo format_text($user->description, $user->descriptionformat);
+    }
+}
+echo '</div>';
+
+// Print all the little details in a list
+
+echo '<table class="list" summary="">';
+
+if (! isset($hiddenfields['country']) && $user->country) {
+    print_row(get_string('country') . ':', get_string($user->country, 'countries'));
+}
+
+if (! isset($hiddenfields['city']) && $user->city) {
+    print_row(get_string('city') . ':', $user->city);
+}
+
+if (has_capability('moodle/user:viewhiddendetails', $context)) {
+    if ($user->address) {
+        print_row(get_string("address").":", "$user->address");
+    }
+    if ($user->phone1) {
+        print_row(get_string("phone").":", "$user->phone1");
+    }
+    if ($user->phone2) {
+        print_row(get_string("phone2").":", "$user->phone2");
+    }
+}
+
+if ($user->maildisplay == 1
+   or ($user->maildisplay == 2 && !isguestuser())
+   or has_capability('moodle/course:useremail', $context)) {
+
+    $emailswitch = '';
+
+    if ($currentuser or has_capability('moodle/course:useremail', $context)) {   /// Can use the enable/disable email stuff
+        if (!empty($enable) and confirm_sesskey()) {     /// Recieved a parameter to enable the email address
+            $DB->set_field('user', 'emailstop', 0, array('id'=>$user->id));
+            $user->emailstop = 0;
+        }
+        if (!empty($disable) and confirm_sesskey()) {     /// Recieved a parameter to disable the email address
+            $DB->set_field('user', 'emailstop', 1, array('id'=>$user->id));
+            $user->emailstop = 1;
+        }
+    }
+
+    if (has_capability('moodle/course:useremail', $context)) {   /// Can use the enable/disable email stuff
+        if ($user->emailstop) {
+            $switchparam = 'enable';
+            $switchtitle = get_string('emaildisable');
+            $switchclick = get_string('emailenableclick');
+            $switchpix   = 't/emailno';
+        } else {
+            $switchparam = 'disable';
+            $switchtitle = get_string('emailenable');
+            $switchclick = get_string('emaildisableclick');
+            $switchpix   = 't/email';
+        }
+        $emailswitch = "&nbsp;<a title=\"$switchclick\" ".
+                       "href=\"profile.php?id=$user->id&amp;$switchparam=1&amp;sesskey=".sesskey()."\">".
+                       "<img src=\"" . $OUTPUT->pix_url("$switchpix") . "\" alt=\"$switchclick\" /></a>";
+
+    } else if ($currentuser) {         /// Can only re-enable an email this way
+        if ($user->emailstop) {   // Include link that tells how to re-enable their email
+            $switchparam = 'enable';
+            $switchtitle = get_string('emaildisable');
+            $switchclick = get_string('emailenableclick');
+
+            $emailswitch = "&nbsp;(<a title=\"$switchclick\" ".
+                           "href=\"profile.php?id=$user->id&amp;enable=1&amp;sesskey=".sesskey()."\">$switchtitle</a>)";
+        }
+    }
+
+    print_row(get_string("email").":", obfuscate_mailto($user->email, '', $user->emailstop)."$emailswitch");
+}
+
+if ($user->url && !isset($hiddenfields['webpage'])) {
+    $url = $user->url;
+    if (strpos($user->url, '://') === false) {
+        $url = 'http://'. $url;
+    }
+    print_row(get_string("webpage") .":", '<a href="'.s($url).'">'.s($user->url).'</a>');
+}
+
+if ($user->icq && !isset($hiddenfields['icqnumber'])) {
+    print_row(get_string('icqnumber').':',"<a href=\"http://web.icq.com/wwp?uin=".urlencode($user->icq)."\">".s($user->icq)." <img src=\"http://web.icq.com/whitepages/online?icq=".urlencode($user->icq)."&amp;img=5\" alt=\"\" /></a>");
+}
+
+if ($user->skype && !isset($hiddenfields['skypeid'])) {
+    print_row(get_string('skypeid').':','<a href="callto:'.urlencode($user->skype).'">'.s($user->skype).
+        ' <img src="http://mystatus.skype.com/smallicon/'.urlencode($user->skype).'" alt="'.get_string('status').'" '.
+        ' /></a>');
+}
+if ($user->yahoo && !isset($hiddenfields['yahooid'])) {
+    print_row(get_string('yahooid').':', '<a href="http://edit.yahoo.com/config/send_webmesg?.target='.urlencode($user->yahoo).'&amp;.src=pg">'.s($user->yahoo)." <img src=\"http://opi.yahoo.com/online?u=".urlencode($user->yahoo)."&m=g&t=0\" alt=\"\"></a>");
+}
+if ($user->aim && !isset($hiddenfields['aimid'])) {
+    print_row(get_string('aimid').':', '<a href="aim:goim?screenname='.urlencode($user->aim).'">'.s($user->aim).'</a>');
+}
+if ($user->msn && !isset($hiddenfields['msnid'])) {
+    print_row(get_string('msnid').':', s($user->msn));
+}
+
+/// Print the Custom User Fields
+profile_display_fields($user->id);
+
+
+if (!isset($hiddenfields['mycourses'])) {
+    if ($mycourses = get_my_courses($user->id, 'visible DESC,sortorder ASC', null, false, 21)) {
+        $shown=0;
+        $courselisting = '';
+        foreach ($mycourses as $mycourse) {
+            if ($mycourse->category) {
+                $class = '';
+                if ($mycourse->visible == 0) {
+                    // get_my_courses will filter courses $USER cannot see
+                    // if we get one with visible 0 it just means it's hidden
+                    // ... but not from $USER
+                    $class = 'class="dimmed"';
+                }
+                $courselisting .= "<a href=\"{$CFG->wwwroot}/user/view.php?id={$user->id}&amp;course={$mycourse->id}\" $class >" . format_string($mycourse->fullname) . "</a>, ";
+            }
+            $shown++;
+            if($shown==20) {
+                $courselisting.= "...";
+                break;
+            }
+        }
+        print_row(get_string('courseprofiles').':', rtrim($courselisting,', '));
+    }
+}
+if (!isset($hiddenfields['firstaccess'])) {
+    if ($user->firstaccess) {
+        $datestring = userdate($user->firstaccess)."&nbsp; (".format_time(time() - $user->firstaccess).")";
+    } else {
+        $datestring = get_string("never");
+    }
+    print_row(get_string("firstaccess").":", $datestring);
+}
+if (!isset($hiddenfields['lastaccess'])) {
+    if ($user->lastaccess) {
+        $datestring = userdate($user->lastaccess)."&nbsp; (".format_time(time() - $user->lastaccess).")";
+    } else {
+        $datestring = get_string("never");
+    }
+    print_row(get_string("lastaccess").":", $datestring);
+}
+
+/// Printing tagged interests
+if (!empty($CFG->usetags)) {
+    if ($interests = tag_get_tags_csv('user', $user->id) ) {
+        print_row(get_string('interests') .": ", $interests);
+    }
+}
+
+echo "</table>";
+
+
+echo $OUTPUT->blocks_for_region('content');
+
+echo $OUTPUT->footer();
+
+
+function print_row($left, $right) {
+    echo "\n<tr><td class=\"label c0\">$left</td><td class=\"info c1\">$right</td></tr>\n";
+}
Index: user/profilesys.php
===================================================================
RCS file: user/profilesys.php
diff -N user/profilesys.php
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ user/profilesys.php	4 May 2010 09:24:55 -0000
@@ -0,0 +1,108 @@
+<?php
+
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * System Public Profile.
+ *
+ * This script allows the site administrator to edit the default site
+ * profile.
+ *
+ * @package    moodlecore
+ * @subpackage my
+ * @copyright  2010 Remote-Learner.net
+ * @author     Hubert Chathi <hubert@remote-learner.net>
+ * @author     Olav Jordan <olav.jordan@remote-learner.net>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+require_once(dirname(__FILE__) . '/../config.php');
+require_once($CFG->dirroot . '/my/lib.php');
+require_once($CFG->libdir.'/adminlib.php');
+
+$edit   = optional_param('edit', null, PARAM_BOOL);    // Turn editing on and off
+
+require_login();
+
+$strpublicprofile = get_string('publicprofile');
+
+$context = get_context_instance(CONTEXT_SYSTEM);
+require_capability('moodle/my:configsyspages', $context);
+$PAGE->set_blocks_editing_capability('moodle/my:configsyspages');
+$header = "$SITE->shortname: $strpublicprofile (DEFAULT)";
+
+// Start setting up the page
+$params = array();
+$PAGE->set_url('/user/profilesys.php', $params);
+$PAGE->set_pagelayout('mydashboard');
+$PAGE->set_pagetype('user-profile');
+$PAGE->set_context($context);
+$PAGE->set_title($header);
+$PAGE->set_heading($header);
+$PAGE->blocks->add_region('content');
+
+// TODO: Make the page be selected properly in the Settings block
+
+// Get the Public Profile page info.  Should always return something unless the database is broken.
+if (!$currentpage = my_get_page(0, MY_PAGE_PUBLIC)) {
+    print_error('publicprofilesetup');
+}
+$PAGE->set_subpage($currentpage->id);
+
+
+// Toggle the editing state and switches
+if ($PAGE->user_allowed_editing()) {
+    if ($edit !== null) {             // Editing state was specified
+        $USER->editing = $edit;       // Change editing state
+    } else {                          // Editing state is in session
+        if (!empty($USER->editing)) {
+            $edit = 1;
+        } else {
+            $edit = 0;
+        }
+    }
+
+    // Add button for editing page
+    $params['edit'] = !$edit;
+
+    if (empty($edit)) {
+        $editstring = get_string('updatemymoodleon');
+    } else {
+        $editstring = get_string('updatemymoodleoff');
+    }
+
+    $url = new moodle_url("$CFG->wwwroot/my/profilesys.php", $params);
+    $button = $OUTPUT->single_button($url, $editstring);
+    $PAGE->set_button($button);
+
+} else {
+    $USER->editing = $edit = 0;
+}
+
+// HACK WARNING!  This loads up all this page's blocks in the system context
+if ($currentpage->userid == 0) {
+    $CFG->blockmanagerclass = 'my_syspage_block_manager';
+}
+
+
+echo $OUTPUT->header();
+
+echo $OUTPUT->blocks_for_region('content');
+
+print_object($currentpage);
+print_object($context);
+
+echo $OUTPUT->footer();
Index: user/view.php
===================================================================
RCS file: /cvsroot/moodle/moodle/user/view.php,v
retrieving revision 1.235
diff -u -r1.235 view.php
--- user/view.php	19 Apr 2010 10:47:49 -0000	1.235
+++ user/view.php	4 May 2010 09:24:55 -0000
@@ -32,22 +32,25 @@
 $enable    = optional_param('enable', 0, PARAM_BOOL);       // enable email
 $disable   = optional_param('disable', 0, PARAM_BOOL);      // disable email
 
-if (empty($id)) {         // See your own profile by default
+if (empty($id)) {            // See your own profile by default
     require_login();
     $id = $USER->id;
 }
 
-$url = new moodle_url('/user/view.php', array('id'=>$id));
-if ($courseid != SITEID) {
-    $url->param('course', $courseid);
+if ($courseid == SITEID) {   // Since Moodle 2.0 all site-level profiles are shown by profile.php
+    redirect($CFG->wwwroot.'/user/profile.php?id='.$id);  // Immediate redirect
 }
+
+$url = new moodle_url('/user/view.php', array('id'=>$id,'course'=>$courseid));
 $PAGE->set_url($url);
 
 $user = $DB->get_record('user', array('id'=>$id), '*', MUST_EXIST);
 $course = $DB->get_record('course', array('id'=>$courseid), '*', MUST_EXIST);
+$currentuser = ($user->id == $USER->id);
 
 $systemcontext = get_context_instance(CONTEXT_SYSTEM);
-$usercontext = get_context_instance(CONTEXT_USER, $user->id, MUST_EXIST);
+$coursecontext = get_context_instance(CONTEXT_COURSE, $course->id);
+$usercontext   = get_context_instance(CONTEXT_USER, $user->id, MUST_EXIST);
 
 // Require login first
 if (isguestuser($user)) {
@@ -55,31 +58,13 @@
     print_error('invaliduserid');
 }
 
-$currentuser = ($user->id == $USER->id);
-
-if ($course->id == SITEID) {
-    $isfrontpage = true;
-    // do not use frontpage course context because there is no frontpage profile, instead it is the site profile
-    $coursecontext = $systemcontext;
-} else {
-    $isfrontpage = false;
-    $coursecontext = get_context_instance(CONTEXT_COURSE, $course->id);
-}
-
-$PAGE->set_context($usercontext);
+$PAGE->set_context($coursecontext);
+$PAGE->set_pagetype('course-view-' . $course->format);
+$PAGE->set_other_editing_capability('moodle/course:manageactivities');
 
 $isparent = false;
-if ($isfrontpage) {
-    if (!empty($CFG->forceloginforprofiles)) {
-        require_login();
-        if (isguestuser()) {
-            redirect(get_login_url());
-        }
-    } else if (!empty($CFG->forcelogin)) {
-        require_login();
-    }
 
-} else if (!$currentuser
+if (!$currentuser
   and $DB->record_exists('role_assignments', array('userid'=>$USER->id, 'contextid'=>$usercontext->id))
   and has_capability('moodle/user:viewdetails', $usercontext)) {
     // TODO: very ugly hack - do not force "parents" to enrol into course their child is enrolled in,
@@ -104,7 +89,7 @@
 /// Now test the actual capabilities and enrolment in course
 if ($currentuser) {
     // me
-    if (!$isfrontpage and !is_enrolled($coursecontext) and !is_viewing($coursecontext)) { // Need to have full access to a course to see the rest of own info
+    if (!is_enrolled($coursecontext) and !is_viewing($coursecontext)) { // Need to have full access to a course to see the rest of own info
         echo $OUTPUT->header();
         echo $OUTPUT->heading(get_string('notenrolled', '', $fullname));
         if (!empty($_SERVER['HTTP_REFERER'])) {
@@ -119,43 +104,30 @@
     $PAGE->set_title("$strpersonalprofile: ");
     $PAGE->set_heading("$strpersonalprofile: ");
 
-    if ($isfrontpage) {
-        // Reduce possibility of "browsing" userbase at site level
-        if (!empty($CFG->forceloginforprofiles) and !has_capability('moodle/user:viewdetails', $usercontext) and !has_coursemanager_role($user->id)) {
-            // Course managers can be browsed at site level. If not forceloginforprofiles, allow access (bug #4366)
-            $PAGE->navbar->add($struser);
+    // check course level capabilities
+    if (!has_capability('moodle/user:viewdetails', $coursecontext) && // normal enrolled user or mnager
+        !has_capability('moodle/user:viewdetails', $usercontext)) {   // usually parent
+        print_error('cannotviewprofile');
+    }
+
+    if (!is_enrolled($coursecontext, $user->id)) {
+        // TODO: the only potential problem is that managers and inspectors might post in forum, but the link
+        //       to profile would not work - maybe a new capability - moodle/user:freely_acessile_profile_for_anybody
+        //       or test for course:inspect capability
+        if (has_capability('moodle/role:assign', $coursecontext)) {
+            $PAGE->navbar->add($fullname);
+            echo $OUTPUT->header();
+            echo $OUTPUT->heading(get_string('notenrolled', '', $fullname));
+        } else {
             echo $OUTPUT->header();
-            echo $OUTPUT->heading(get_string('usernotavailable', 'error'));
-            echo $OUTPUT->footer();
-            exit;
+            $PAGE->navbar->add($struser);
+            echo $OUTPUT->heading(get_string('notenrolledprofile'));
         }
-
-    } else {
-        // check course level capabilities
-        if (!has_capability('moodle/user:viewdetails', $coursecontext) && // normal enrolled user or mnager
-            !has_capability('moodle/user:viewdetails', $usercontext)) {   // usually parent
-            print_error('cannotviewprofile');
-        }
-
-        if (!is_enrolled($coursecontext, $user->id)) {
-            // TODO: the only potential problem is that managers and inspectors might post in forum, but the link
-            //       to profile would not work - maybe a new capability - moodle/user:freely_acessile_profile_for_anybody
-            //       or test for course:inspect capability
-            if (has_capability('moodle/role:assign', $coursecontext)) {
-                $PAGE->navbar->add($fullname);
-                echo $OUTPUT->header();
-                echo $OUTPUT->heading(get_string('notenrolled', '', $fullname));
-            } else {
-                echo $OUTPUT->header();
-                $PAGE->navbar->add($struser);
-                echo $OUTPUT->heading(get_string('notenrolledprofile'));
-            }
-            if (!empty($_SERVER['HTTP_REFERER'])) {
-                echo $OUTPUT->continue_button($_SERVER['HTTP_REFERER']);
-            }
-            echo $OUTPUT->footer();
-            exit;
+        if (!empty($_SERVER['HTTP_REFERER'])) {
+            echo $OUTPUT->continue_button($_SERVER['HTTP_REFERER']);
         }
+        echo $OUTPUT->footer();
+        exit;
     }
 
     // If groups are in use and enforced throughout the course, then make sure we can meet in at least one course level group
@@ -181,6 +153,7 @@
 $PAGE->set_heading($course->fullname);
 $PAGE->set_pagelayout('standard');
 echo $OUTPUT->header();
+echo $OUTPUT->heading(fullname($user));
 
 if ($user->deleted) {
     echo $OUTPUT->heading(get_string('userdeleted'));
@@ -194,11 +167,9 @@
 
 add_to_log($course->id, "user", "view", "view.php?id=$user->id&course=$course->id", "$user->id");
 
-if (!$isfrontpage) {
-    $user->lastaccess = false;
-    if ($lastaccess = $DB->get_record('user_lastaccess', array('userid'=>$user->id, 'courseid'=>$course->id))) {
-        $user->lastaccess = $lastaccess->timeaccess;
-    }
+$user->lastaccess = false;
+if ($lastaccess = $DB->get_record('user_lastaccess', array('userid'=>$user->id, 'courseid'=>$course->id))) {
+    $user->lastaccess = $lastaccess->timeaccess;
 }
 
 
@@ -209,18 +180,6 @@
     $hiddenfields = array_flip(explode(',', $CFG->hiddenuserfields));
 }
 
-/// Print tabs at top
-/// This same call is made in:
-///     /user/view.php
-///     /user/edit.php
-///     /course/user.php
-
-$currenttab = 'profile';
-$showroles = 1;
-if (!$user->deleted) {
-    include('tabs.php');
-}
-
 if (is_mnet_remote_user($user)) {
     $sql = "
          SELECT DISTINCT h.id, h.name, h.wwwroot,
@@ -243,30 +202,33 @@
     }
 }
 
-echo '<table class="userinfobox" summary="">';
-echo '<tr>';
-echo '<td class="side">';
-echo $OUTPUT->user_picture($user, array('courseid'=>$course->id, 'size'=>100));
-echo '</td><td class="content">';
+echo '<div class="fullprofilelink">';
+echo html_writer::link($CFG->wwwroot.'/user/profile.php?id='.$id, get_string('fullprofile'));
+echo '</div>';
+
+echo '<div class="profilepicture">';
+echo $OUTPUT->user_picture($user, array('size'=>100));
+echo '</div>';
 
 // Print the description
-
+echo '<div class="description">';
 if ($user->description && !isset($hiddenfields['description'])) {
-    if (!$isfrontpage && !empty($CFG->profilesforenrolledusersonly) && !$DB->record_exists('role_assignments', array('userid'=>$id))) {
+    if (!empty($CFG->profilesforenrolledusersonly) && !$DB->record_exists('role_assignments', array('userid'=>$id))) {
         echo get_string('profilenotshown', 'moodle').'<hr />';
     } else {
         $user->description = file_rewrite_pluginfile_urls($user->description, 'pluginfile.php', $usercontext->id, 'user_profile', $id);
         echo format_text($user->description, $user->descriptionformat)."<hr />";
     }
 }
+echo '</div>';
+
 
 // Print all the little details in a list
 
-echo '<table class="list">';
+echo '<table class="list" summary="">';
 
 if (! isset($hiddenfields['country']) && $user->country) {
-    $countries = get_string_manager()->get_list_of_countries();
-    print_row(get_string('country') . ':', $countries[$user->country]);
+    print_row(get_string('country') . ':', get_string($user->country, 'countries'));
 }
 
 if (! isset($hiddenfields['city']) && $user->city) {
@@ -286,7 +248,7 @@
 }
 
 if ($user->maildisplay == 1
-   or ($user->maildisplay == 2 and !$isfrontpage and !isguestuser())
+   or ($user->maildisplay == 2 && !isguestuser())
    or has_capability('moodle/course:useremail', $coursecontext)) {
 
     $emailswitch = '';
@@ -337,7 +299,7 @@
     if (strpos($user->url, '://') === false) {
         $url = 'http://'. $url;
     }
-    print_row(get_string("webpage") .":", '<a href="'.s($url).'">'.s($user->url).'</a>');
+    print_row(get_string('webpage') .':', '<a href="'.s($url).'">'.s($user->url).'</a>');
 }
 
 if ($user->icq && !isset($hiddenfields['icqnumber'])) {
@@ -390,7 +352,7 @@
                 break;
             }
         }
-        print_row(get_string('courses').':', rtrim($courselisting,', '));
+        print_row(get_string('courseprofiles').':', rtrim($courselisting,', '));
     }
 }
 if (!isset($hiddenfields['firstaccess'])) {
@@ -439,8 +401,6 @@
 
 echo "</table>";
 
-echo "</td></tr></table>";
-
 $userauth = get_auth_plugin($user->auth);
 
 $passwordchangeurl = false;
@@ -454,107 +414,10 @@
     }
 }
 
-//  Print other functions
-echo '<div class="buttons clearfix">';
-
-if ($passwordchangeurl) {
-    $params = array('id'=>$course->id);
-
-    if (session_is_loggedinas()) {
-        $passwordchangeurl = ''; // do not use actual change password url - might contain sensitive data
-    } else {
-        $parts = explode('?', $passwordchangeurl);
-        $passwordchangeurl = reset($parts);
-        $after = next($parts);
-        preg_match_all('/([^&=]+)=([^&=]+)/', $after, $matches);
-        if (count($matches)) {
-            foreach($matches[0] as $key=>$match) {
-                $params[$matches[1][$key]] = $matches[2][$key];
-            }
-        }
-    }
-    echo "<form action=\"$passwordchangeurl\" method=\"get\">";
-    echo "<div>";
-    foreach($params as $key=>$value) {
-        echo '<input type="hidden" name="'.$key.'" value="'.s($value).'" />';
-    }
-    if (session_is_loggedinas()) {
-        // changing of password when "Logged in as" is not allowed
-        echo "<input type=\"submit\" value=\"".get_string("changepassword")."\" disabled=\"disabled\" />";
-    } else {
-        echo "<input type=\"submit\" value=\"".get_string("changepassword")."\" />";
-    }
-    echo "</div>";
-    echo "</form>";
-}
-
-if (!$isfrontpage && empty($course->metacourse)) {   // Mostly only useful at course level
-
-    if ($currentuser) {
-        if (is_enrolled($coursecontext, NULL, 'moodle/role:unassignself')) {
-            echo '<form action="'.$CFG->wwwroot.'/course/unenrol.php" method="get">';
-            echo '<div>';
-            echo '<input type="hidden" name="id" value="'.$course->id.'" />';
-            echo '<input type="hidden" name="user" value="'.$user->id.'" />';
-            echo '<input type="submit" value="'.s(get_string('unenrolme', '', $course->shortname)).'" />';
-            echo '</div>';
-            echo '</form>';
-        }
-    } else {
-        if (is_enrolled($coursecontext, $user->id, 'moodle/role:assign')) { // I can unassign roles
-            // add some button to unenroll user
-        }
-    }
-}
-
-if (!$user->deleted and !$currentuser && !session_is_loggedinas() && has_capability('moodle/user:loginas', $coursecontext) && !is_siteadmin($user->id)) {
-    echo '<form action="'.$CFG->wwwroot.'/course/loginas.php" method="get">';
-    echo '<div>';
-    echo '<input type="hidden" name="id" value="'.$course->id.'" />';
-    echo '<input type="hidden" name="user" value="'.$user->id.'" />';
-    echo '<input type="hidden" name="sesskey" value="'.sesskey().'" />';
-    echo '<input type="submit" value="'.get_string('loginas').'" />';
-    echo '</div>';
-    echo '</form>';
-}
-
-if (!$user->deleted and !empty($CFG->messaging) and !isguestuser() and has_capability('moodle/site:sendmessage', $systemcontext)) {
-    if (isloggedin() and $currentuser) {
-        if ($countmessages = $DB->count_records('message', array('useridto'=>$user->id))) {
-            $messagebuttonname = get_string("messages", "message")."($countmessages)";
-        } else {
-            $messagebuttonname = get_string("messages", "message");
-        }
-        echo "<form onclick=\"this.target='message'\" action=\"../message/index.php\" method=\"get\">";
-        echo "<div>";
-        echo "<input type=\"submit\" value=\"$messagebuttonname\" onclick=\"return openpopup('/message/index.php', 'message', 'menubar=0,location=0,scrollbars,status,resizable,width=400,height=500', 0);\" />";
-        echo "</div>";
-        echo "</form>";
-    } else {
-        echo "<form onclick=\"this.target='message$user->id'\" action=\"../message/discussion.php\" method=\"get\">";
-        echo "<div>";
-        echo "<input type=\"hidden\" name=\"id\" value=\"$user->id\" />";
-        echo "<input type=\"submit\" value=\"".get_string("sendmessage", "message")."\" onclick=\"return openpopup('/message/discussion.php?id=$user->id', 'message_$user->id', 'menubar=0,location=0,scrollbars,status,resizable,width=400,height=500', 0);\" />";
-        echo "</div>";
-        echo "</form>";
-    }
-}
-
-// Authorize.net: User Payments
-// TODO: replace this hack with proper callback into all plugins
-if ($course->enrol == 'authorize' || (empty($course->enrol) && $CFG->enrol == 'authorize')) {
-    echo "<form action=\"../enrol/authorize/index.php\" method=\"get\">";
-    echo "<div>";
-    echo "<input type=\"hidden\" name=\"course\" value=\"$course->id\" />";
-    echo "<input type=\"hidden\" name=\"user\" value=\"$user->id\" />";
-    echo "<input type=\"submit\" value=\"".get_string('payments')."\" />";
-    echo "</div>";
-    echo "</form>";
-}
-echo "</div>\n";
+// Buttons gone!  TODO: Make sure there's a good way to message someone from the profile pages
 
 if ($CFG->debugdisplay && debugging('', DEBUG_DEVELOPER) && $currentuser) {  // Show user object
-    echo '<hr />';
+    echo '<br /><br /><hr />';
     echo $OUTPUT->heading('DEBUG MODE:  User session variables');
     print_object($USER);
 }
