MDL-45898 myprofile: Redesign my profile page

Part of MDL-45774.

Contributions by John Okely, Jetha Chan and Damyon Wiese (squashed branch).

AMOS BEGIN
CPY [coursebadges,core_badges], [badges,core_badges]
AMOS END
This commit is contained in:
Ankit Agarwal
2015-04-10 17:17:32 +08:00
committed by Adrian Greeve
parent 479fa47d0b
commit b19cc4ef25
26 changed files with 1039 additions and 469 deletions
+82
View File
@@ -0,0 +1,82 @@
<?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/>.
/**
* Defines various library functions.
*
* @package core_badges
* @copyright 2015 onwards Ankit Agarwal
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
/**
* Add nodes to myprofile page.
*
* @param \core_user\output\myprofile\tree $tree Tree object
* @param stdClass $user user object
* @param bool $iscurrentuser
* @param stdClass $course Course object
*
* @return bool
*/
function core_badges_myprofile_navigation(\core_user\output\myprofile\tree $tree, $user, $iscurrentuser, $course) {
global $CFG, $PAGE, $USER, $SITE;
require_once($CFG->dirroot . '/badges/renderer.php');
if (empty($CFG->enablebadges) || (!empty($course) || empty($CFG->badges_allowcoursebadges))) {
// Y U NO LIKE BADGES ?
return true;
}
$category = new core_user\output\myprofile\category('badges', get_string('badges', 'badges'), null);
$url = new moodle_url("/badges/mybadges.php");
// Add category.
$tree->add_category($category);
// Determine context.
if (isloggedin()) {
$context = context_user::instance($USER->id);
} else {
$context = context_system::instance();
}
$courseid = empty($course) ? 0 : $course->id;
if ($USER->id == $user->id || has_capability('moodle/badges:viewotherbadges', $context)) {
$records = badges_get_user_badges($user->id, $courseid, null, null, null, true);
$renderer = new core_badges_renderer($PAGE, '');
// Local badges.
if ($records) {
$title = get_string('localbadgesp', 'badges', format_string($SITE->fullname));
$content = $renderer->print_badges_list($records, $user->id, true);
$localnode = $mybadges = new core_user\output\myprofile\node('badges', 'localbadges', $title, null, null, $content);
$tree->add_node($localnode);
}
// External badges.
if ($courseid == 0 && !empty($CFG->badges_allowexternalbackpack)) {
$backpack = get_backpack_settings($user->id);
if (isset($backpack->totalbadges) && $backpack->totalbadges !== 0) {
$title = get_string('externalbadgesp', 'badges');
$content = $renderer->print_badges_list($backpack->badges, $user->id, true, true);
$externalnode = $mybadges = new core_user\output\myprofile\node('badges', 'externalbadges', $title, null, null,
$content);
$tree->add_node($externalnode);
}
}
}
}
+28
View File
@@ -1013,3 +1013,31 @@ function blog_page_type_list($pagetype, $parentcontext, $currentcontext) {
'blog-edit'=>get_string('page-blog-edit', 'blog')
);
}
/**
* Add nodes to myprofile page.
*
* @param \core_user\output\myprofile\tree $tree Tree object
* @param stdClass $user user object
* @param bool $iscurrentuser
* @param stdClass $course Course object
*
* @return bool
*/
function core_blog_myprofile_navigation(core_user\output\myprofile\tree $tree, $user, $iscurrentuser, $course) {
if (!blog_is_enabled_for_user() || isguestuser($user)) {
// The guest user cannot post, so it is not possible to view any posts.
// Also blogs might be disabled.
// May as well just bail aggressively here.
return true;
}
$url = new moodle_url("/blog/index.php", array('userid' => $user->id));
if ($iscurrentuser) {
$title = get_string('myprofilemyblogs', 'core_blog');
} else {
$title = get_string('myprofileuserblogs', 'core_blog', fullname($user));
}
$blognode = new core_user\output\myprofile\node('miscellaneous', 'blogs', $title, null, $url);
$tree->add_node($blognode);
return true;
}
+1
View File
@@ -94,6 +94,7 @@ $string['backpackimport'] = 'Badge import settings';
$string['backpackimport_help'] = 'After backpack connection is successfully established, badges from your backpack can be displayed on your "My Badges" page and your profile page.
In this area, you can select collections of badges from your backpack that you would like to display in your profile.';
$string['badges'] = 'Badges';
$string['badgedetails'] = 'Badge details';
$string['badgeimage'] = 'Image';
$string['badgeimage_help'] = 'This is an image that will be used when this badge is issued.
+2
View File
@@ -108,6 +108,8 @@ $string['invalidgroupid'] = 'Invalid group ID';
$string['invalidurl'] = 'This URL is unreachable';
$string['linktooriginalentry'] = 'Link to original blog entry';
$string['maxexternalblogsperuser'] = 'Maximum number of external blogs per user';
$string['myprofilemyblogs'] = 'My blog entries';
$string['myprofileuserblogs'] = 'View all blog entries by {$a}';
$string['name'] = 'Name';
$string['name_help'] = 'Enter a descriptive name for your external blog. (If no name is supplied, the title of your external blog will be used).';
$string['noentriesyet'] = 'No visible entries here';
+2 -1
View File
@@ -192,7 +192,8 @@ $string['registerhostson'] = 'Register all hosts is currently <b>on</b>';
$string['remotecourses'] = 'Remote courses';
$string['remotehost'] = 'Remote host';
$string['remotehosts'] = 'Remote hosts';
$string['remoteuserinfo'] = 'Remote {$a->remotetype} user - profile fetched from <a href="{$a->remoteurl}">{$a->remotename}</a>';
$string['remoteuser'] = 'Remote {$a->remotetype} user';
$string['remoteuserinfo'] = 'Profile fetched from <a href="{$a->remoteurl}">{$a->remotename}</a>';
$string['requiresopenssl'] = 'Networking requires the OpenSSL extension';
$string['restore'] = 'Restore';
$string['returnvalue'] = 'Return value';
+4 -1
View File
@@ -317,6 +317,7 @@ $string['coursecompletion'] = 'Course completion';
$string['coursecompletions'] = 'Course completions';
$string['coursecreators'] = 'Course creator';
$string['coursecreatorsdescription'] = 'Course creators can create new courses.';
$string['coursedetails'] = 'Course details';
$string['coursedisplay'] = 'Course layout';
$string['coursedisplay_help'] = 'This setting determines whether the whole course is displayed on one page or split over several pages.';
$string['coursedisplay_single'] = 'Show all sections on one page';
@@ -331,6 +332,7 @@ $string['courseformatdata'] = 'Course format data';
$string['courseformats'] = 'Course formats';
$string['courseformatoptions'] = 'Formatting options for {$a}';
$string['courseformatudpate'] = 'Update format';
$string['courseprofiles'] = 'Course profiles';
$string['coursegrades'] = 'Course grades';
$string['coursehelpcategory'] = 'Position the course on the course listing and may make it easier for students to find it.';
$string['coursehelpforce'] = 'Force the course group mode to every activity in the course.';
@@ -356,7 +358,6 @@ $string['courselegacyfiles_link'] = 'coursefiles2';
$string['courselegacyfilesofcourse'] = 'Legacy course files: {$a}';
$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';
@@ -1905,6 +1906,7 @@ $string['uploadserverlimit'] = 'Uploaded file exceeded the maximum size limit se
$string['uploadthisfile'] = 'Upload this file';
$string['url'] = 'URL';
$string['used'] = 'Used';
$string['userdetails'] = 'User details';
$string['usedinnplaces'] = 'Used in {$a} places';
$string['usemessageform'] = 'or use the form below to send a message to the selected students';
$string['user'] = 'User';
@@ -1929,6 +1931,7 @@ $string['usernameoremail'] = 'Enter either username or email address';
$string['usernotconfirmed'] = 'Could not confirm {$a}';
$string['userpic'] = 'User picture';
$string['users'] = 'Users';
$string['userspreferences'] = 'User {$a}\'s preferences';
$string['userselectorautoselectunique'] = 'If only one user matches the search, select them automatically';
$string['userselectorpreserveselected'] = 'Keep selected users, even if they no longer match the search';
$string['userselectorsearchanywhere'] = 'Match the search text anywhere in the displayed fields';
+2
View File
@@ -43,6 +43,8 @@ $string['eventnotesviewed'] = 'Notes viewed';
$string['groupaddnewnote'] = 'Add a common note';
$string['invalidid'] = 'Invalid note ID specified';
$string['invaliduserid'] = 'Invalid user id: {$a}';
$string['myprofileownnotes'] = 'My notes';
$string['myprofileothernotes'] = 'Notes by {$a}';
$string['nocontent'] = 'Note content can not be empty';
$string['nonotes'] = 'There are no notes of this type yet';
$string['nopermissiontodelete'] = 'You may not delete this note';
-42
View File
@@ -1140,48 +1140,6 @@ function badges_download($userid) {
}
}
/**
* Print badges on user profile page.
*
* @param int $userid User ID.
* @param int $courseid Course if we need to filter badges (optional).
*/
function profile_display_badges($userid, $courseid = 0) {
global $CFG, $PAGE, $USER, $SITE;
require_once($CFG->dirroot . '/badges/renderer.php');
// Determine context.
if (isloggedin()) {
$context = context_user::instance($USER->id);
} else {
$context = context_system::instance();
}
if ($USER->id == $userid || has_capability('moodle/badges:viewotherbadges', $context)) {
$records = badges_get_user_badges($userid, $courseid, null, null, null, true);
$renderer = new core_badges_renderer($PAGE, '');
// Print local badges.
if ($records) {
$left = get_string('localbadgesp', 'badges', format_string($SITE->fullname));
$right = $renderer->print_badges_list($records, $userid, true);
echo html_writer::tag('dt', $left);
echo html_writer::tag('dd', $right);
}
// Print external badges.
if ($courseid == 0 && !empty($CFG->badges_allowexternalbackpack)) {
$backpack = get_backpack_settings($userid);
if (isset($backpack->totalbadges) && $backpack->totalbadges !== 0) {
$left = get_string('externalbadgesp', 'badges');
$right = $renderer->print_badges_list($backpack->badges, $userid, true, true);
echo html_writer::tag('dt', $left);
echo html_writer::tag('dd', $right);
}
}
}
}
/**
* Checks if badges can be pushed to external backpack.
*
+45
View File
@@ -4220,3 +4220,48 @@ function message_current_user_is_involved($user1, $user2) {
}
return true;
}
/**
* Print badges on user profile page.
*
* @deprecated since Moodle 2.9 MDL-45898 - please do not use this function any more.
* @param int $userid User ID.
* @param int $courseid Course if we need to filter badges (optional).
*/
function profile_display_badges($userid, $courseid = 0) {
global $CFG, $PAGE, $USER, $SITE;
require_once($CFG->dirroot . '/badges/renderer.php');
debugging('profile_display_badges() is deprecated.', DEBUG_DEVELOPER);
// Determine context.
if (isloggedin()) {
$context = context_user::instance($USER->id);
} else {
$context = context_system::instance();
}
if ($USER->id == $userid || has_capability('moodle/badges:viewotherbadges', $context)) {
$records = badges_get_user_badges($userid, $courseid, null, null, null, true);
$renderer = new core_badges_renderer($PAGE, '');
// Print local badges.
if ($records) {
$left = get_string('localbadgesp', 'badges', format_string($SITE->fullname));
$right = $renderer->print_badges_list($records, $userid, true);
echo html_writer::tag('dt', $left);
echo html_writer::tag('dd', $right);
}
// Print external badges.
if ($courseid == 0 && !empty($CFG->badges_allowexternalbackpack)) {
$backpack = get_backpack_settings($userid);
if (isset($backpack->totalbadges) && $backpack->totalbadges !== 0) {
$left = get_string('externalbadgesp', 'badges');
$right = $renderer->print_badges_list($backpack->badges, $userid, true, true);
echo html_writer::tag('dt', $left);
echo html_writer::tag('dd', $right);
}
}
}
}
+423
View File
@@ -0,0 +1,423 @@
<?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/>.
/**
* Defines core nodes for my profile navigation tree.
*
* @package core
* @copyright 2015 onwards Ankit Agarwal
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
/**
* Defines core nodes for my profile navigation tree.
*
* @param \core_user\output\myprofile\tree $tree Tree object
* @param stdClass $user user object
* @param bool $iscurrentuser is the user viewing profile, current user ?
* @param stdClass $course course object
*
* @return bool
*/
function core_myprofile_navigation(core_user\output\myprofile\tree $tree, $user, $iscurrentuser, $course) {
global $CFG, $USER, $DB;
$usercontext = context_user::instance($user->id, MUST_EXIST);
$systemcontext = context_system::instance();
$context = !empty($course) ? context_course::instance($course->id) : $systemcontext;
$courseid = !empty($course) ? $course->id : SITEID;
$contactcategory = new core_user\output\myprofile\category('contact', get_string('userdetails'));
$miscategory = new core_user\output\myprofile\category('miscellaneous', get_string('miscellaneous'));
$reportcategory = new core_user\output\myprofile\category('reports', get_string('reports'), 'miscellaneous');
$admincategory = new core_user\output\myprofile\category('administration', get_string('administration'), 'miscellaneous');
$coursedetailscategory = new core_user\output\myprofile\category('coursedetails', get_string('coursedetails'), 'contact');
// Add categories.
$tree->add_category($contactcategory);
$tree->add_category($miscategory);
$tree->add_category($reportcategory);
$tree->add_category($admincategory);
$tree->add_category($coursedetailscategory);
// Add core nodes.
// Full profile node.
if (!empty($course)) {
if (empty($CFG->forceloginforprofiles) || $iscurrentuser ||
has_capability('moodle/user:viewdetails', context_user::instance($user->id))
|| has_coursecontact_role($user->id)) {
$url = new moodle_url('/user/profile.php', array('id' => $user->id));
$node = new core_user\output\myprofile\node('miscellaneous', 'fullprofile', get_string('fullprofile'), null, $url);
$tree->add_node($node);
}
}
// Edit profile.
if (isloggedin() && !isguestuser($user) && !is_mnet_remote_user($user)) {
if (($iscurrentuser || is_siteadmin($USER) || !is_siteadmin($user)) && has_capability('moodle/user:update',
$systemcontext)) {
$url = new moodle_url('/user/editadvanced.php', array('id' => $user->id, 'course' => $courseid));
$node = new core_user\output\myprofile\node('administration', 'editprofile', get_string('editmyprofile'), null, $url);
$tree->add_node($node);
} else if ((has_capability('moodle/user:editprofile', $usercontext) && !is_siteadmin($user))
|| ($iscurrentuser && has_capability('moodle/user:editownprofile', $systemcontext))) {
$userauthplugin = false;
if (!empty($user->auth)) {
$userauthplugin = get_auth_plugin($user->auth);
}
if ($userauthplugin && $userauthplugin->can_edit_profile()) {
$url = $userauthplugin->edit_profile_url();
if (empty($url)) {
$url = new moodle_url('/user/edit.php', array('userid' => $user->id, 'course' => $id));
}
$node = new core_user\output\myprofile\node('administration', 'editprofile',
get_string('editmyprofile'), null, $url);
$tree->add_node($node);
}
}
}
// Preference page.
if ($iscurrentuser || is_siteadmin()) {
$url = new moodle_url('/user/preferences.php', array('userid' => $user->id));
$title = $iscurrentuser ? get_string('mypreferences') : get_string('userspreferences', 'moodle', fullname($user));
$node = new core_user\output\myprofile\node('administration', 'preferences', $title, null, $url);
$tree->add_node($node);
}
// Login as ...
if (!$user->deleted && !$iscurrentuser &&
!\core\session\manager::is_loggedinas() && has_capability('moodle/user:loginas',
$context) && !is_siteadmin($user->id)) {
$url = new moodle_url('/course/loginas.php',
array('id' => $courseid, 'user' => $user->id, 'sesskey' => sesskey()));
$node = new core_user\output\myprofile\node('administration', 'loginas', get_string('loginas'), null, $url);
$tree->add_node($node);
}
// Contact details.
if (has_capability('moodle/user:viewhiddendetails', $usercontext)) {
$hiddenfields = array();
} else {
$hiddenfields = array_flip(explode(',', $CFG->hiddenuserfields));
}
if (has_capability('moodle/site:viewuseridentity', $context)) {
$identityfields = array_flip(explode(',', $CFG->showuseridentity));
} else {
$identityfields = array();
}
if (is_mnet_remote_user($user)) {
$sql = "SELECT 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";
$remotehost = $DB->get_record_sql($sql, array($user->mnethostid));
$remoteuser = new stdclass();
$remoteuser->remotetype = $remotehost->display_name;
$hostinfo = new stdclass();
$hostinfo->remotename = $remotehost->name;
$hostinfo->remoteurl = $remotehost->wwwroot;
$node = new core_user\output\myprofile\node('contact', 'mnet', get_string('remoteuser', 'mnet', $remoteuser), null, null,
get_string('remoteuserinfo', 'mnet', $hostinfo), null, 'remoteuserinfo');
$tree->add_node($node);
}
// Printing tagged interests. We want this only for full profile.
if (!empty($CFG->usetags) && empty($course)) {
if ($interests = tag_get_tags_csv('user', $user->id) ) {
$node = new core_user\output\myprofile\node('contact', 'interests', get_string('interests'), null, null, $interests);
$tree->add_node($node);
}
}
if (!isset($hiddenfields['country']) && $user->country) {
$node = new core_user\output\myprofile\node('contact', 'country', get_string('country'), null, null,
get_string($user->country, 'countries'));
$tree->add_node($node);
}
if (!isset($hiddenfields['city']) && $user->city) {
$node = new core_user\output\myprofile\node('contact', 'city', get_string('city'), null, null, $user->city);
$tree->add_node($node);
}
if (isset($identityfields['address']) && $user->address) {
$node = new core_user\output\myprofile\node('contact', 'address', get_string('address'), null, null, $user->address);
$tree->add_node($node);
}
if (isset($identityfields['phone1']) && $user->phone1) {
$node = new core_user\output\myprofile\node('contact', 'phone1', get_string('phone'), null, null, $user->phone1);
$tree->add_node($node);
}
if (isset($identityfields['phone2']) && $user->phone2) {
$node = new core_user\output\myprofile\node('contact', 'phone2', get_string('phone2'), null, null, $user->phone2);
$tree->add_node($node);
}
if (isset($identityfields['institution']) && $user->institution) {
$node = new core_user\output\myprofile\node('contact', 'institution', get_string('institution'), null, null,
$user->institution);
$tree->add_node($node);
}
if (isset($identityfields['department']) && $user->department) {
$node = new core_user\output\myprofile\node('contact', 'department', get_string('department'), null, null,
$user->institution);
$tree->add_node($node);
}
if (isset($identityfields['idnumber']) && $user->idnumber) {
$node = new core_user\output\myprofile\node('contact', 'idnumber', get_string('idnumber'), null, null,
$user->institution);
$tree->add_node($node);
}
if (isset($identityfields['email']) and ($iscurrentuser
or $user->maildisplay == 1
or has_capability('moodle/course:useremail', $usercontext)
or ($user->maildisplay == 2 and enrol_sharing_course($user, $USER)))) {
$node = new core_user\output\myprofile\node('contact', 'email', get_string('email'), null, null,
obfuscate_mailto($user->email, ''));
$tree->add_node($node);
}
if ($user->url && !isset($hiddenfields['webpage'])) {
$url = $user->url;
if (strpos($user->url, '://') === false) {
$url = 'http://'. $url;
}
$webpageurl = new moodle_url($url);
$node = new core_user\output\myprofile\node('contact', 'webpage', get_string('webpage'), null, $webpageurl);
$tree->add_node($node);
}
if (!isset($hiddenfields['mycourses'])) {
$showallcourses = optional_param('showallcourses', 0, PARAM_INT);
if ($mycourses = enrol_get_all_users_courses($user->id, true, null, 'visible DESC, sortorder ASC')) {
$shown = 0;
$courselisting = html_writer::start_tag('ul');
foreach ($mycourses as $mycourse) {
if ($mycourse->category) {
context_helper::preload_from_record($mycourse);
$ccontext = context_course::instance($mycourse->id);
if (!isset($course) || $mycourse->id != $course->id) {
$linkattributes = null;
if ($mycourse->visible == 0) {
if (!has_capability('moodle/course:viewhiddencourses', $ccontext)) {
continue;
}
$linkattributes['class'] = 'dimmed';
}
$params = array('id' => $user->id, 'course' => $mycourse->id);
if ($showallcourses) {
$params['showallcourses'] = 1;
}
$url = new moodle_url('/user/view.php', $params);
$courselisting .= html_writer::tag('li', html_writer::link($url, $ccontext->get_context_name(false),
$linkattributes));
} else {
$courselisting .= html_writer::tag('li', $course->fullname);
}
}
$shown++;
if (!$showallcourses && $shown == $CFG->navcourselimit) {
$url = null;
if (isset($course)) {
$url = new moodle_url('/user/view.php',
array('id' => $user->id, 'course' => $course->id, 'showallcourses' => 1));
} else {
$url = new moodle_url('/user/profile.php', array('id' => $user->id, 'showallcourses' => 1));
}
$courselisting .= html_writer::tag('li', html_writer::link($url, get_string('viewmore'),
array('title' => get_string('viewmore'))));
break;
}
}
$courselisting .= html_writer::end_tag('ul');
if (!empty($mycourses)) {
// Add this node only if there are courses to display.
$node = new core_user\output\myprofile\node('coursedetails', 'courseprofiles',
get_string('courseprofiles'), null, null, rtrim($courselisting, ', '));
$tree->add_node($node);
}
}
}
if (!empty($course)) {
// Show roles in this course.
if ($rolestring = get_user_roles_in_course($user->id, $course->id)) {
$node = new core_user\output\myprofile\node('coursedetails', 'roles', get_string('roles'), null, null, $rolestring);
$tree->add_node($node);
}
// Show groups this user is in.
if (!isset($hiddenfields['groups']) && !empty($course)) {
$accessallgroups = has_capability('moodle/site:accessallgroups', $context);
if ($usergroups = groups_get_all_groups($course->id, $user->id)) {
$groupstr = '';
foreach ($usergroups as $group) {
if ($course->groupmode == SEPARATEGROUPS and !$accessallgroups and $user->id != $USER->id) {
if (!groups_is_member($group->id, $user->id)) {
continue;
}
}
if ($course->groupmode != NOGROUPS) {
$groupstr .= ' <a href="'.$CFG->wwwroot.'/user/index.php?id='.$course->id.'&amp;group='.$group->id.'">'
.format_string($group->name).'</a>,';
} else {
// The user/index.php shows groups only when course in group mode.
$groupstr .= ' '.format_string($group->name);
}
}
if ($groupstr !== '') {
$node = new core_user\output\myprofile\node('coursedetails', 'groups',
get_string('group'), null, null, rtrim($groupstr, ', '));
$tree->add_node($node);
}
}
}
if (!isset($hiddenfields['suspended'])) {
if ($user->suspended) {
$node = new core_user\output\myprofile\node('coursedetails', 'suspended',
null, null, null, get_string('suspended', 'auth'));
$tree->add_node($node);
}
}
echo html_writer::end_tag('dl');
}
if ($user->icq && !isset($hiddenfields['icqnumber'])) {
$imurl = new moodle_url('http://web.icq.com/wwp', array('uin' => $user->icq) );
$iconurl = new moodle_url('http://web.icq.com/whitepages/online', array('icq' => $user->icq, 'img' => '5'));
$statusicon = html_writer::tag('img', '',
array('src' => $iconurl, 'class' => 'icon icon-post', 'alt' => get_string('status')));
$node = new core_user\output\myprofile\node('contact', 'icqnumber', get_string('icqnumber'), null, null,
html_writer::link($imurl, s($user->icq) . $statusicon));
$tree->add_node($node);
}
if ($user->skype && !isset($hiddenfields['skypeid'])) {
$imurl = 'skype:'.urlencode($user->skype).'?call';
$iconurl = new moodle_url('http://mystatus.skype.com/smallicon/'.urlencode($user->skype));
if (is_https()) {
// Bad luck, skype devs are lazy to set up SSL on their servers - see MDL-37233.
$statusicon = '';
} else {
$statusicon = html_writer::empty_tag('img',
array('src' => $iconurl, 'class' => 'icon icon-post', 'alt' => get_string('status')));
}
$node = new core_user\output\myprofile\node('contact', 'skypeid', get_string('skypeid'), null, null,
html_writer::link($imurl, s($user->skype) . $statusicon));
$tree->add_node($node);
}
if ($user->yahoo && !isset($hiddenfields['yahooid'])) {
$imurl = new moodle_url('http://edit.yahoo.com/config/send_webmesg', array('.target' => $user->yahoo, '.src' => 'pg'));
$iconurl = new moodle_url('http://opi.yahoo.com/online', array('u' => $user->yahoo, 'm' => 'g', 't' => '0'));
$statusicon = html_writer::tag('img', '',
array('src' => $iconurl, 'class' => 'iconsmall icon-post', 'alt' => get_string('status')));
$node = new core_user\output\myprofile\node('contact', 'yahooid', get_string('yahooid'), null, null,
html_writer::link($imurl, s($user->yahoo) . $statusicon));
$tree->add_node($node);
}
if ($user->aim && !isset($hiddenfields['aimid'])) {
$imurl = 'aim:goim?screenname='.urlencode($user->aim);
$node = new core_user\output\myprofile\node('contact', 'aimid', get_string('aimid'), null, null,
html_writer::link($imurl, s($user->aim)));
$tree->add_node($node);
}
if ($user->msn && !isset($hiddenfields['msnid'])) {
$node = new core_user\output\myprofile\node('contact', 'msnid', get_string('msnid'), null, null,
s($user->msn));
$tree->add_node($node);
}
if ($categories = $DB->get_records('user_info_category', null, 'sortorder ASC')) {
foreach ($categories as $category) {
if ($fields = $DB->get_records('user_info_field', array('categoryid' => $category->id), 'sortorder ASC')) {
foreach ($fields as $field) {
require_once($CFG->dirroot.'/user/profile/field/'.$field->datatype.'/field.class.php');
$newfield = 'profile_field_'.$field->datatype;
$formfield = new $newfield($field->id, $user->id);
if ($formfield->is_visible() and !$formfield->is_empty()) {
$node = new core_user\output\myprofile\node('contact', $formfield->field->shortname,
format_string($formfield->field->name), null, null, $formfield->display_data());
$tree->add_node($node);
}
}
}
}
}
// First access. (Why only for sites ?)
if (!isset($hiddenfields['firstaccess']) && empty($course)) {
if ($user->firstaccess) {
$datestring = userdate($user->firstaccess)."&nbsp; (".format_time(time() - $user->firstaccess).")";
} else {
$datestring = get_string("never");
}
$node = new core_user\output\myprofile\node('miscellaneous', 'firstaccess', get_string('firstsiteaccess'), null, null,
$datestring);
$tree->add_node($node);
}
// Last access.
if (!isset($hiddenfields['lastaccess'])) {
if (empty($course)) {
$string = get_string('lastsiteaccess');
if ($user->lastaccess) {
$datestring = userdate($user->lastaccess) . "&nbsp; (" . format_time(time() - $user->lastaccess) . ")";
} else {
$datestring = get_string("never");
}
} else {
$string = get_string('lastcourseaccess');
if ($lastaccess = $DB->get_record('user_lastaccess', array('userid' => $user->id, 'courseid' => $course->id))) {
$datestring = userdate($lastaccess->timeaccess)."&nbsp; (".format_time(time() - $lastaccess->timeaccess).")";
} else {
$datestring = get_string("never");
}
}
$node = new core_user\output\myprofile\node('miscellaneous', 'lastaccess', $string, null, null,
$datestring);
$tree->add_node($node);
}
// Last ip.
if (has_capability('moodle/user:viewlastip', $usercontext) && !isset($hiddenfields['lastip'])) {
if ($user->lastip) {
$iplookupurl = new moodle_url('/iplookup/index.php', array('ip' => $user->lastip, 'user' => $USER->id));
$ipstring = html_writer::link($iplookupurl, $user->lastip);
} else {
$ipstring = get_string("none");
}
$node = new core_user\output\myprofile\node('miscellaneous', 'lastip', get_string('lastip'), null, null,
$ipstring);
$tree->add_node($node);
}
}
+1
View File
@@ -38,6 +38,7 @@ information provided here is intended especially for developers.
for the library. See MDL-49519 for details.
* The outdated lib/google/Google_Client.php and related files have been completely removed. To use
the new client, read lib/google/readme_moodle.txt, please.
* profile_display_badges() has been deprecated. See MDL-48935 for details.
=== 2.8 ===
+4
View File
@@ -325,6 +325,10 @@ $string['more'] = 'more';
$string['movedmarker'] = '(Moved)';
$string['movethisdiscussionto'] = 'Move this discussion to ...';
$string['mustprovidediscussionorpost'] = 'You must provide either a discussion id or post id to export';
$string['myprofileownpost'] = 'My forum posts';
$string['myprofileotherpost'] = 'Forum posts by {$a}';
$string['myprofileowndis'] = 'My forum discussions';
$string['myprofileotherdis'] = 'Forum discussions by {$a}';
$string['namenews'] = 'News forum';
$string['namenews_help'] = 'The news forum is a special forum for announcements that is automatically created when a course is created. A course can have only one news forum. Only teachers and administrators can post in the news forum. The "Latest news" block will display recent discussions from the news forum.';
$string['namesocial'] = 'Social forum';
+38 -1
View File
@@ -7802,7 +7802,6 @@ function forum_view($forum, $course, $cm, $context) {
* @since Moodle 2.9
*/
function forum_discussion_view($modcontext, $forum, $discussion) {
$params = array(
'context' => $modcontext,
'objectid' => $discussion->id,
@@ -7813,3 +7812,41 @@ function forum_discussion_view($modcontext, $forum, $discussion) {
$event->add_record_snapshot('forum', $forum);
$event->trigger();
}
/**
* Add nodes to myprofile page.
*
* @param \core_user\output\myprofile\tree $tree Tree object
* @param stdClass $user user object
* @param bool $iscurrentuser
* @param stdClass $course Course object
*
* @return bool
*/
function mod_forum_myprofile_navigation(core_user\output\myprofile\tree $tree, $user, $iscurrentuser, $course) {
if (isguestuser($user)) {
// The guest user cannot post, so it is not possible to view any posts.
// May as well just bail aggressively here.
return false;
}
$postsurl = new moodle_url('/mod/forum/user.php', array('id' => $user->id));
if (!empty($course)) {
$postsurl->param('coursre', $course->id);
}
$string = $iscurrentuser ? get_string('myprofileownpost', 'mod_forum') :
get_string('myprofileotherpost', 'mod_forum', fullname($user));
$node = new core_user\output\myprofile\node('miscellaneous', 'forumposts', $string, null, $postsurl);
$tree->add_node($node);
$discussionssurl = new moodle_url('/mod/forum/user.php', array('id' => $user->id, 'mode' => 'discussions'));
if (!empty($course)) {
$postsurl->param('coursre', $course->id);
}
$string = $iscurrentuser ? get_string('myprofileowndis', 'mod_forum') :
get_string('myprofileotherdis', 'mod_forum', fullname($user));
$node = new core_user\output\myprofile\node('miscellaneous', 'forumdiscussions', $string, null,
$discussionssurl);
$tree->add_node($node);
return true;
}
+35 -2
View File
@@ -17,8 +17,9 @@
/**
* Library of functions and constants for notes
*
* @package core_notes
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @package core_notes
* @copyright 2007 onwards Yu Zhang
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
@@ -366,3 +367,35 @@ function note_view($context, $userid) {
));
$event->trigger();
}
/**
* Add nodes to myprofile page.
*
* @param \core_user\output\myprofile\tree $tree Tree object
* @param stdClass $user user object
* @param bool $iscurrentuser
* @param stdClass $course Course object
*
* @return bool
*/
function core_notes_myprofile_navigation(core_user\output\myprofile\tree $tree, $user, $iscurrentuser, $course) {
$url = new moodle_url("/notes/index.php", array('user' => $user->id));
$title = $iscurrentuser ? get_string('myprofileownnotes', 'core_notes') :
get_string('myprofileothernotes', 'core_notes', fullname($user));;
if (empty($course)) {
// Site level profile.
if (!has_capability('moodle/notes:view', context_system::instance())) {
// No cap, nothing to do.
return false;
}
$url->param('course', 0);
} else {
if (!has_capability('moodle/notes:view', context_course::instance($course->id))) {
// No cap, nothing to do.
return false;
}
$url->param('course', $course->id);
}
$notesnode = new core_user\output\myprofile\node('miscellaneous', 'notes', $title, null, $url);
$tree->add_node($notesnode);
}
+32
View File
@@ -148,3 +148,35 @@ function report_log_page_type_list($pagetype, $parentcontext, $currentcontext) {
);
return $array;
}
/**
* Add nodes to myprofile page.
*
* @param \core_user\output\myprofile\tree $tree Tree object
* @param stdClass $user user object
* @param bool $iscurrentuser
* @param stdClass $course Course object
*
* @return bool
*/
function report_log_myprofile_navigation(core_user\output\myprofile\tree $tree, $user, $iscurrentuser, $course) {
if (!empty($course)) {
list($all, $today) = report_log_can_access_user_report($user, $course);
if ($today) {
// Today's log.
$url = new moodle_url('/report/log/user.php',
array('id' => $user->id, 'course' => $course->id, 'mode' => 'today'));
$node = new core_user\output\myprofile\node('reports', 'todayslogs', get_string('todaylogs'), null, $url);
$tree->add_node($node);
}
if ($all) {
// All logs.
$url = new moodle_url('/report/log/user.php',
array('id' => $user->id, 'course' => $course->id, 'mode' => 'all'));
$node = new core_user\output\myprofile\node('reports', 'alllogs', get_string('alllogs'), null, $url);
$tree->add_node($node);
}
}
return true;
}
+23
View File
@@ -119,3 +119,26 @@ function report_outline_supports_logstore($instance) {
}
return false;
}
/**
* Add nodes to myprofile page.
*
* @param \core_user\output\myprofile\tree $tree Tree object
* @param stdClass $user user object
* @param bool $iscurrentuser
* @param stdClass $course Course object
*
* @return bool
*/
function report_outline_myprofile_navigation(core_user\output\myprofile\tree $tree, $user, $iscurrentuser, $course) {
if (!empty($course) && report_outline_can_access_user_report($user, $course)) {
$url = new moodle_url('/report/outline/user.php',
array('id' => $user->id, 'course' => $course->id, 'mode' => 'outline'));
$node = new core_user\output\myprofile\node('reports', 'outline', get_string('outlinereport'), null, $url);
$tree->add_node($node);
$url = new moodle_url('/report/outline/user.php',
array('id' => $user->id, 'course' => $course->id, 'mode' => 'complete'));
$node = new core_user\output\myprofile\node('reports', 'complete', get_string('completereport'), null, $url);
$tree->add_node($node);
}
}
+3 -1
View File
@@ -6,6 +6,8 @@
.userprofile dl dt, .userprofile dl dd {padding-top:3px; padding-bottom:3px;}
.userprofile dl dt {margin:0; font-weight:bold; display:block; float:left; width:110px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.userprofile dl dd {margin:0; margin-left:120px;}
.userprofile .profile_tree { column-count: 2; -webkit-column-count: 2; -moz-column-count: 2; }
.userprofile .profile_tree section { display: inline-block; width: 100%; }
.user-box {margin:8px;width:115px;height:160px;text-align:center;float:left;clear: none;}
@@ -76,4 +78,4 @@
.dir-rtl #groupeditform .members {
float: right;
text-align: right;
}
}
+25 -4
View File
@@ -6,6 +6,14 @@
.userprofile .description {
margin-bottom: 20px;
}
.userprofile .profile_tree {
.content-columns(2);
}
.userprofile .profile_tree section {
display: inline-block;
width: 100%;
}
.userprofile dl.list {
.dl-horizontal;
}
@@ -17,6 +25,22 @@
float: left;
clear: none;
}
#page-user-profile .node_category, .path-user .node_category {
li {
list-style-type: square;
&.contentnode {
list-style-type: none;
}
}
}
#page-user-profile.dir-ltr .node_category .contentnode, .path-user.dir-ltr .node_category .contentnode {
margin-left: -25px;
}
#page-user-profile.dir-rtl .node_category .contentnode , .path-user.dir-rtl .node_category .contentnode {
margin-right: -25px;
}
.dir-rtl {
.userprofile .description {
margin-right:0;
@@ -177,9 +201,6 @@
margin-right: auto;
}
/** Overide for RTL layout **/
.dir-rtl .userprofilebox .descriptionbox {
margin: 0;
}
.dir-rtl .userlist table#participants td,
.dir-rtl .userlist table#participants th {
text-align: right;
@@ -239,4 +260,4 @@
.preferences-group {
float: right;
}
}
}
File diff suppressed because one or more lines are too long
+55 -6
View File
@@ -55,10 +55,15 @@ class category implements \renderable {
*/
private $nodes = array();
/**
* @var string HTML class attribute for this category. Classes should be separated by a space, e.g. 'class1 class2'
*/
private $classes;
/**
* @var array list of properties publicly accessible via __get.
*/
private $properties = array('after', 'name', 'title', 'nodes');
private $properties = array('after', 'name', 'title', 'nodes', 'classes');
/**
* Constructor for category class.
@@ -66,11 +71,13 @@ class category implements \renderable {
* @param string $name Category name.
* @param string $title category title.
* @param null|string $after Name of category after which this category should appear.
* @param null|string $classes a list of css classes.
*/
public function __construct($name, $title, $after = null) {
public function __construct($name, $title, $after = null, $classes = null) {
$this->after = $after;
$this->name = $name;
$this->title = $title;
$this->classes = $classes;
}
/**
@@ -81,7 +88,7 @@ class category implements \renderable {
*
* @throws \coding_exception
*/
public function add_node(\core_user\output\myprofile\node $node) {
public function add_node(node $node) {
$name = $node->name;
if (isset($this->nodes[$name])) {
throw new \coding_exception("Node with name $name already exists");
@@ -100,13 +107,28 @@ class category implements \renderable {
*/
public function sort_nodes() {
$tempnodes = array();
$this->validate_after_order();
// First content noes.
foreach ($this->nodes as $node) {
$after = $node->after;
if ($after == null) {
// Can go anywhere in the cat.
$content = $node->content;
if ($after == null && !empty($content)) {
// Can go anywhere in the cat. Also show content nodes first.
$tempnodes = array_merge($tempnodes, array($node->name => $node), $this->find_nodes_after($node));
}
}
// Now nodes with no content.
foreach ($this->nodes as $node) {
$after = $node->after;
$content = $node->content;
if ($after == null && empty($content)) {
// Can go anywhere in the cat. Also show content nodes first.
$tempnodes = array_merge($tempnodes, array($node->name => $node), $this->find_nodes_after($node));
}
}
if (count($tempnodes) !== count($this->nodes)) {
// Orphan nodes found.
throw new \coding_exception('Some of the nodes specified contains invalid \'after\' property');
@@ -114,6 +136,33 @@ class category implements \renderable {
$this->nodes = $tempnodes;
}
/**
* Verifies that node with content can come after node with content only . Also verifies the same thing for nodes without
* content.
* @throws \coding_exception
*/
protected function validate_after_order() {
$nodearray = $this->nodes;
foreach ($this->nodes as $node) {
$after = $node->after;
if (!empty($after)) {
if (empty($nodearray[$after])) {
throw new \coding_exception('node {$node->name} specified contains invalid \'after\' property');
} else {
// Valid node found.
$afternode = $nodearray[$after];
$beforecontent = $node->content;
$aftercontent = $afternode->content;
if ((empty($beforecontent) && !empty($aftercontent)) || (!empty($beforecontent) && empty($aftercontent))) {
// Only node with content are allowed after content nodes. Same goes for no content nodes.
throw new \coding_exception('node {$node->name} specified contains invalid \'after\' property');
}
}
}
}
}
/**
* Given a node object find all node objects that should appear after it.
*
@@ -127,7 +176,7 @@ class category implements \renderable {
foreach ($nodearray as $nodeelement) {
if ($nodeelement->after === $node->name) {
// Find all nodes that comes after this node as well.
$return = array_merge($return, array($nodeelement), $this->find_nodes_after($nodeelement));
$return = array_merge($return, array($nodeelement->name => $nodeelement), $this->find_nodes_after($nodeelement));
}
}
return $return;
+11 -3
View File
@@ -69,10 +69,15 @@ class node implements \renderable {
*/
private $icon;
/**
* @var string HTML class attribute for this node. Classes should be separated by a space, e.g. 'class1 class2'
*/
private $classes;
/**
* @var array list of properties accessible via __get.
*/
private $properties = array('parentcat', 'after', 'name', 'title', 'url', 'content', 'icon');
private $properties = array('parentcat', 'after', 'name', 'title', 'url', 'content', 'icon', 'classes');
/**
* Constructor for the node.
@@ -84,15 +89,18 @@ class node implements \renderable {
* @param null|string|\moodle_url $url Url that this node should link to.
* @param null|string $content Content to display under this node.
* @param null|string|\pix_icon $icon Icon for this node.
* @param null|string $classes a list of css classes.
*/
public function __construct($parentcat, $name, $title, $after = null, $url = null, $content = null, $icon = null) {
public function __construct($parentcat, $name, $title, $after = null, $url = null, $content = null, $icon = null,
$classes = null) {
$this->parentcat = $parentcat;
$this->after = $after;
$this->name = $name;
$this->title = $title;
$this->url = new \moodle_url($url);
$this->url = is_null($url) ? null : new \moodle_url($url);
$this->content = $content;
$this->icon = $icon;
$this->classes = $classes;
}
/**
+120
View File
@@ -0,0 +1,120 @@
<?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/>.
/**
* myprofile renderer.
*
* @package core_user
* @copyright 2015 onwards Ankit Agarwal <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core_user\output\myprofile;
defined('MOODLE_INTERNAL') || die;
/**
* Report log renderer's for printing reports.
*
* @since Moodle 2.9
* @package core_user
* @copyright 2015 onwards Ankit Agarwal <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class renderer extends \plugin_renderer_base {
/**
* Render the whole tree.
*
* @param tree $tree
*
* @return string
*/
public function render_tree(tree $tree) {
$return = \html_writer::start_tag('div', array('class' => 'profile_tree'));
$categories = $tree->categories;
foreach ($categories as $category) {
$return .= $this->render($category);
}
$return .= \html_writer::end_tag('div');
return $return;
}
/**
* Render a category.
*
* @param category $category
*
* @return string
*/
public function render_category(category $category) {
$classes = $category->classes;
if (empty($classes)) {
$return = \html_writer::start_tag('section', array('class' => 'node_category'));
} else {
$return = \html_writer::start_tag('section', array('class' => 'node_category ' . $classes));
}
$return .= \html_writer::tag('h3', $category->title);
$nodes = $category->nodes;
if (empty($nodes)) {
// No nodes, nothing to render.
return '';
}
$return .= \html_writer::start_tag('ul');
foreach ($nodes as $node) {
$return .= $this->render($node);
}
$return .= \html_writer::end_tag('ul');
$return .= \html_writer::end_tag('section');
return $return;
}
/**
* Render a node.
*
* @param node $node
*
* @return string
*/
public function render_node(node $node) {
$return = '';
if (is_object($node->url)) {
$header = \html_writer::link($node->url, $node->title);
} else {
$header = $node->title;
}
$icon = $node->icon;
if (!empty($icon)) {
$header .= $this->render($icon);
}
$content = $node->content;
$classes = $node->classes;
if (!empty($content)) {
// There is some content to display below this make this a header.
$return = \html_writer::tag('dt', $header);
$return .= \html_writer::tag('dd', $content);
$return = \html_writer::tag('dl', $return);
if ($classes) {
$return = \html_writer::tag('li', $return, array('class' => 'contentnode ' . $classes));
} else {
$return = \html_writer::tag('li', $return, array('class' => 'contentnode'));
}
} else {
$return = \html_writer::span($header);
$return = \html_writer::tag('li', $return, array('class' => $classes));
}
return $return;
}
}
+9 -236
View File
@@ -41,7 +41,6 @@ require_once($CFG->libdir.'/filelib.php');
$userid = optional_param('id', 0, PARAM_INT);
$edit = optional_param('edit', null, PARAM_BOOL); // Turn editing on and off.
$reset = optional_param('reset', null, PARAM_BOOL);
$showallcourses = optional_param('showallcourses', 0, PARAM_INT);
$PAGE->set_url('/user/profile.php', array('id' => $userid));
@@ -115,18 +114,6 @@ if (isguestuser()) { // Guests can never edit their profile.
}
}
if (has_capability('moodle/user:viewhiddendetails', $context)) {
$hiddenfields = array();
} else {
$hiddenfields = array_flip(explode(',', $CFG->hiddenuserfields));
}
if (has_capability('moodle/site:viewuseridentity', $context)) {
$identityfields = array_flip(explode(',', $CFG->showuseridentity));
} else {
$identityfields = array();
}
// Start setting up the page.
$strpublicprofile = get_string('publicprofile');
@@ -213,240 +200,26 @@ profile_view($user, $usercontext);
echo $OUTPUT->header();
echo '<div class="userprofile">';
// Print the standard content of this page, the basic profile info.
echo $OUTPUT->heading(fullname($user));
if (is_mnet_remote_user($user)) {
$sql = "SELECT 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";
$remotehost = $DB->get_record_sql($sql, array($user->mnethostid));
$a = new stdclass();
$a->remotetype = $remotehost->display_name;
$a->remotename = $remotehost->name;
$a->remoteurl = $remotehost->wwwroot;
echo $OUTPUT->box(get_string('remoteuserinfo', 'mnet', $a), 'remoteuserinfo');
}
echo '<div class="userprofilebox clearfix"><div class="profilepicture">';
echo $OUTPUT->user_picture($user, array('size' => 100));
echo '</div>';
echo '<div class="descriptionbox"><div class="description">';
// Print the description.
if ($user->description && !isset($hiddenfields['description'])) {
echo '<div class="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', null);
$options = array('overflowdiv' => true);
echo format_text($user->description, $user->descriptionformat, $options);
echo format_text($user->description, $user->descriptionformat);
}
echo '</div>';
}
echo '</div>';
// Print all the little details in a list.
echo html_writer::start_tag('dl', array('class' => 'list'));
if (!isset($hiddenfields['country']) && $user->country) {
echo html_writer::tag('dt', get_string('country'));
echo html_writer::tag('dd', get_string($user->country, 'countries'));
}
if (!isset($hiddenfields['city']) && $user->city) {
echo html_writer::tag('dt', get_string('city'));
echo html_writer::tag('dd', $user->city);
}
if (isset($identityfields['address']) && $user->address) {
echo html_writer::tag('dt', get_string('address'));
echo html_writer::tag('dd', $user->address);
}
if (isset($identityfields['phone1']) && $user->phone1) {
echo html_writer::tag('dt', get_string('phone'));
echo html_writer::tag('dd', $user->phone1);
}
if (isset($identityfields['phone2']) && $user->phone2) {
echo html_writer::tag('dt', get_string('phone2'));
echo html_writer::tag('dd', $user->phone2);
}
if (isset($identityfields['institution']) && $user->institution) {
echo html_writer::tag('dt', get_string('institution'));
echo html_writer::tag('dd', $user->institution);
}
if (isset($identityfields['department']) && $user->department) {
echo html_writer::tag('dt', get_string('department'));
echo html_writer::tag('dd', $user->department);
}
if (isset($identityfields['idnumber']) && $user->idnumber) {
echo html_writer::tag('dt', get_string('idnumber'));
echo html_writer::tag('dd', $user->idnumber);
}
if (isset($identityfields['email']) and ($currentuser
or $user->maildisplay == 1
or has_capability('moodle/course:useremail', $context)
or ($user->maildisplay == 2 and enrol_sharing_course($user, $USER)))) {
echo html_writer::tag('dt', get_string('email'));
echo html_writer::tag('dd', obfuscate_mailto($user->email, ''));
}
if (!isset($hiddenfields['timezone'])) {
echo html_writer::tag('dt', get_string('timezone'));
echo html_writer::tag('dd', core_date::get_localised_timezone(core_date::get_user_timezone($user)));
}
if ($user->url && !isset($hiddenfields['webpage'])) {
$url = $user->url;
if (strpos($user->url, '://') === false) {
$url = 'http://'. $url;
}
$webpageurl = new moodle_url($url);
echo html_writer::tag('dt', get_string('webpage'));
echo html_writer::tag('dd', html_writer::link($webpageurl, s($user->url)));
}
if ($user->icq && !isset($hiddenfields['icqnumber'])) {
$imurl = new moodle_url('http://web.icq.com/wwp', array('uin' => $user->icq) );
$iconurl = new moodle_url('http://web.icq.com/whitepages/online', array('icq' => $user->icq, 'img' => '5'));
$statusicon = html_writer::tag('img', '', array('src' => $iconurl, 'class' => 'icon icon-post', 'alt' => get_string('status')));
echo html_writer::tag('dt', get_string('icqnumber'));
echo html_writer::tag('dd', html_writer::link($imurl, s($user->icq) . $statusicon));
}
if ($user->skype && !isset($hiddenfields['skypeid'])) {
$imurl = 'skype:'.urlencode($user->skype).'?call';
$iconurl = new moodle_url('http://mystatus.skype.com/smallicon/'.urlencode($user->skype));
if (is_https()) {
// Bad luck, skype devs are lazy to set up SSL on their servers - see MDL-37233.
$statusicon = '';
} else {
$statusicon = html_writer::empty_tag('img',
array('src' => $iconurl, 'class' => 'icon icon-post', 'alt' => get_string('status')));
}
echo html_writer::tag('dt', get_string('skypeid'));
echo html_writer::tag('dd', html_writer::link($imurl, s($user->skype) . $statusicon));
}
if ($user->yahoo && !isset($hiddenfields['yahooid'])) {
$imurl = new moodle_url('http://edit.yahoo.com/config/send_webmesg', array('.target' => $user->yahoo, '.src' => 'pg'));
$iconurl = new moodle_url('http://opi.yahoo.com/online', array('u' => $user->yahoo, 'm' => 'g', 't' => '0'));
$statusicon = html_writer::tag('img', '',
array('src' => $iconurl, 'class' => 'iconsmall icon-post', 'alt' => get_string('status')));
echo html_writer::tag('dt', get_string('yahooid'));
echo html_writer::tag('dd', html_writer::link($imurl, s($user->yahoo) . $statusicon));
}
if ($user->aim && !isset($hiddenfields['aimid'])) {
$imurl = 'aim:goim?screenname='.urlencode($user->aim);
echo html_writer::tag('dt', get_string('aimid'));
echo html_writer::tag('dd', html_writer::link($imurl, s($user->aim)));
}
if ($user->msn && !isset($hiddenfields['msnid'])) {
echo html_writer::tag('dt', get_string('msnid'));
echo html_writer::tag('dd', s($user->msn));
}
// Print the Custom User Fields.
profile_display_fields($user->id);
if (!isset($hiddenfields['mycourses'])) {
if ($mycourses = enrol_get_all_users_courses($user->id, true, null, 'visible DESC, sortorder ASC')) {
$shown = 0;
$courselisting = '';
foreach ($mycourses as $mycourse) {
if ($mycourse->category) {
context_helper::preload_from_record($mycourse);
$ccontext = context_course::instance($mycourse->id);
$linkattributes = null;
if ($mycourse->visible == 0) {
if (!has_capability('moodle/course:viewhiddencourses', $ccontext)) {
continue;
}
$linkattributes['class'] = 'dimmed';
}
$params = array('id' => $user->id, 'course' => $mycourse->id);
if ($showallcourses) {
$params['showallcourses'] = 1;
}
$url = new moodle_url('/user/view.php', $params);
$courselisting .= html_writer::link($url, $ccontext->get_context_name(false), $linkattributes);
$courselisting .= ', ';
}
$shown++;
if (!$showallcourses && $shown == $CFG->navcourselimit) {
$url = new moodle_url('/user/profile.php', array('id' => $user->id, 'showallcourses' => 1));
$courselisting .= html_writer::link($url, '...', array('title' => get_string('viewmore')));
break;
}
}
echo html_writer::tag('dt', get_string('courseprofiles'));
echo html_writer::tag('dd', rtrim($courselisting, ', '));
}
}
if (!isset($hiddenfields['firstaccess'])) {
if ($user->firstaccess) {
$datestring = userdate($user->firstaccess)."&nbsp; (".format_time(time() - $user->firstaccess).")";
} else {
$datestring = get_string("never");
}
echo html_writer::tag('dt', get_string('firstsiteaccess'));
echo html_writer::tag('dd', $datestring);
}
if (!isset($hiddenfields['lastaccess'])) {
if ($user->lastaccess) {
$datestring = userdate($user->lastaccess)."&nbsp; (".format_time(time() - $user->lastaccess).")";
} else {
$datestring = get_string("never");
}
echo html_writer::tag('dt', get_string('lastsiteaccess'));
echo html_writer::tag('dd', $datestring);
}
if (has_capability('moodle/user:viewlastip', $usercontext) && !isset($hiddenfields['lastip'])) {
if ($user->lastip) {
$iplookupurl = new moodle_url('/iplookup/index.php', array('ip' => $user->lastip, 'user' => $user->id));
$ipstring = html_writer::link($iplookupurl, $user->lastip);
} else {
$ipstring = get_string("none");
}
echo html_writer::tag('dt', get_string('lastip'));
echo html_writer::tag('dd', $ipstring);
}
// Printing tagged interests.
if (!empty($CFG->usetags)) {
if ($interests = tag_get_tags_csv('user', $user->id) ) {
echo html_writer::tag('dt', get_string('interests'));
echo html_writer::tag('dd', $interests);
}
}
if (!isset($hiddenfields['suspended'])) {
if ($user->suspended) {
echo html_writer::tag('dt', '&nbsp;');
echo html_writer::tag('dd', get_string('suspended', 'auth'));
}
}
require_once($CFG->libdir . '/badgeslib.php');
if (!empty($CFG->enablebadges)) {
profile_display_badges($user->id);
}
echo html_writer::end_tag('dl');
echo "</div></div>"; // Closing desriptionbox and userprofilebox.
echo $OUTPUT->custom_block_region('content');
// Render custom blocks.
$renderer = $PAGE->get_renderer('core_user', 'myprofile');
$tree = core_user\output\myprofile\manager::build_tree($user, $currentuser);
echo $renderer->render($tree);
echo '</div>'; // Userprofile class.
echo $OUTPUT->footer();
+7
View File
@@ -40,6 +40,13 @@ class phpunit_fixture_myprofile_category extends \core_user\output\myprofile\cat
public function find_nodes_after($node) {
return parent::find_nodes_after($node);
}
/**
* Make protected method public for testing.
*/
public function validate_after_order() {
parent::validate_after_order();
}
}
/**
+81 -5
View File
@@ -41,14 +41,15 @@ class core_user_myprofile_testcase extends advanced_testcase {
*/
public function test_node__construct() {
$node = new \core_user\output\myprofile\node('parentcat', 'nodename',
'nodetitle', 'after', 'www.google.com', 'description');
'nodetitle', 'after', 'www.google.com', 'description', new pix_icon('i/course', ''), 'class1 class2');
$this->assertSame('parentcat', $node->parentcat);
$this->assertSame('nodename', $node->name);
$this->assertSame('nodetitle', $node->title);
$this->assertSame('after', $node->after);
$url = new moodle_url('www.google.com');
$this->assertEquals($url, $node->url);
$this->assertSame('description', $node->content);
$this->assertEquals(new pix_icon('i/course', ''), $node->icon);
$this->assertSame('class1 class2', $node->classes);
}
/**
@@ -80,10 +81,45 @@ class core_user_myprofile_testcase extends advanced_testcase {
* Test category::__construct().
*/
public function test_category__construct() {
$category = new \core_user\output\myprofile\category('categoryname', 'title', 'after');
$category = new \core_user\output\myprofile\category('categoryname', 'title', 'after', 'class1 class2');
$this->assertSame('categoryname', $category->name);
$this->assertSame('title', $category->title);
$this->assertSame('after', $category->after);
$this->assertSame('class1 class2', $category->classes);
}
public function test_validate_after_order1() {
$category = new \phpunit_fixture_myprofile_category('category', 'title', null);
// Create nodes.
$node1 = new \core_user\output\myprofile\node('category', 'node1', 'nodetitle', null, null, 'content');
$node2 = new \core_user\output\myprofile\node('category', 'node2', 'nodetitle', 'node1', null, 'content');
$node3 = new \core_user\output\myprofile\node('category', 'node3', 'nodetitle', 'node2', null, null);
$category->add_node($node3);
$category->add_node($node2);
$category->add_node($node1);
$this->setExpectedException('coding_exception');
$category->validate_after_order();
}
public function test_validate_after_order2() {
$category = new \phpunit_fixture_myprofile_category('category', 'title', null);
// Create nodes.
$node1 = new \core_user\output\myprofile\node('category', 'node1', 'nodetitle', null, null, null);
$node2 = new \core_user\output\myprofile\node('category', 'node2', 'nodetitle', 'node1', null, 'content');
$node3 = new \core_user\output\myprofile\node('category', 'node3', 'nodetitle', 'node2', null, null);
$category->add_node($node3);
$category->add_node($node2);
$category->add_node($node1);
$this->setExpectedException('coding_exception');
$category->validate_after_order();
}
/**
@@ -132,7 +168,7 @@ class core_user_myprofile_testcase extends advanced_testcase {
/**
* Test category::sort_nodes().
*/
public function test_sort_nodes() {
public function test_sort_nodes1() {
$category = new \phpunit_fixture_myprofile_category('category', 'title', null);
// Create nodes.
@@ -175,12 +211,52 @@ class core_user_myprofile_testcase extends advanced_testcase {
$this->assertCount(2, $return);
// Add a node with invalid 'after' and make sure an exception is thrown.
$node7 = new \core_user\output\myprofile\node('category', 'node6', 'nodetitle', 'noderandom');
$node7 = new \core_user\output\myprofile\node('category', 'node7', 'nodetitle', 'noderandom');
$category->add_node($node7);
$this->setExpectedException('coding_exception');
$category->sort_nodes();
}
/**
* Test category::sort_nodes() with a mix of content and non content nodes.
*/
public function test_sort_nodes2() {
$category = new \phpunit_fixture_myprofile_category('category', 'title', null);
// Create nodes.
$node1 = new \core_user\output\myprofile\node('category', 'node1', 'nodetitle', null, null, 'content');
$node2 = new \core_user\output\myprofile\node('category', 'node2', 'nodetitle', 'node1', null, 'content');
$node3 = new \core_user\output\myprofile\node('category', 'node3', 'nodetitle', null);
$node4 = new \core_user\output\myprofile\node('category', 'node4', 'nodetitle', 'node3');
$node5 = new \core_user\output\myprofile\node('category', 'node5', 'nodetitle', 'node3');
$node6 = new \core_user\output\myprofile\node('category', 'node6', 'nodetitle', 'node1', null, 'content');
// Add the nodes in random order.
$category->add_node($node3);
$category->add_node($node2);
$category->add_node($node4);
$category->add_node($node1);
$category->add_node($node5);
$category->add_node($node6);
// After node 1 we should have node2 - node6 - node3 - node4 - node5.
$category->sort_nodes();
$nodes = $category->nodes;
$this->assertCount(6, $nodes);
$node = array_shift($nodes);
$this->assertEquals($node1, $node);
$node = array_shift($nodes);
$this->assertEquals($node2, $node);
$node = array_shift($nodes);
$this->assertEquals($node6, $node);
$node = array_shift($nodes);
$this->assertEquals($node3, $node);
$node = array_shift($nodes);
$this->assertEquals($node4, $node);
$node = array_shift($nodes);
$this->assertEquals($node5, $node);
}
/**
* Test tree::add_node().
*/
+5 -166
View File
@@ -205,32 +205,7 @@ if ($user->deleted) {
// Trigger a user profile viewed event.
profile_view($user, $coursecontext, $course);
// Get the hidden field list.
if (has_capability('moodle/user:viewhiddendetails', $coursecontext)) {
$hiddenfields = array();
} else {
$hiddenfields = array_flip(explode(',', $CFG->hiddenuserfields));
}
if (is_mnet_remote_user($user)) {
$sql = "SELECT 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";
$remotehost = $DB->get_record_sql($sql, array($user->mnethostid));
$a = new stdclass();
$a->remotetype = $remotehost->display_name;
$a->remotename = $remotehost->name;
$a->remoteurl = $remotehost->wwwroot;
echo $OUTPUT->box(get_string('remoteuserinfo', 'mnet', $a), 'remoteuserinfo');
}
echo '<div class="userprofilebox clearfix">';
// Print the description.
echo '<div class="descriptionbox"><div class="description">';
echo '<div class="description">';
if ($user->description && !isset($hiddenfields['description'])) {
if (!empty($CFG->profilesforenrolledusersonly) && !$DB->record_exists('role_assignments', array('userid' => $id))) {
echo get_string('profilenotshown', 'moodle');
@@ -245,147 +220,11 @@ if ($user->description && !isset($hiddenfields['description'])) {
echo format_text($user->description, $user->descriptionformat, $options);
}
}
echo '</div>';
// Print all the little details in a list.
echo html_writer::start_tag('dl', array('class' => 'list'));
// Show email if any of the following conditions match.
// 1. User is viewing his own profile.
// 2. Has allowed everyone to see email
// 3. User has allowed course members to can see email and current user is in same course
// 4. Has either course:viewhiddenuserfields or site:viewuseridentity capability.
if ($currentuser
or $user->maildisplay == 1
or ($user->maildisplay == 2 && is_enrolled($coursecontext, $USER))
or has_capability('moodle/course:viewhiddenuserfields', $coursecontext)
or has_capability('moodle/site:viewuseridentity', $coursecontext)) {
echo html_writer::tag('dt', get_string('email'));
echo html_writer::tag('dd', obfuscate_mailto($user->email, ''));
}
// Show last time this user accessed this course.
if (!isset($hiddenfields['lastaccess'])) {
if ($lastaccess = $DB->get_record('user_lastaccess', array('userid' => $user->id, 'courseid' => $course->id))) {
$datestring = userdate($lastaccess->timeaccess)."&nbsp; (".format_time(time() - $lastaccess->timeaccess).")";
} else {
$datestring = get_string("never");
}
echo html_writer::tag('dt', get_string('lastcourseaccess'));
echo html_writer::tag('dd', $datestring);
}
// Show roles in this course.
if ($rolestring = get_user_roles_in_course($id, $course->id)) {
echo html_writer::tag('dt', get_string('roles'));
echo html_writer::tag('dd', $rolestring);
}
// Show groups this user is in.
if (!isset($hiddenfields['groups'])) {
$accessallgroups = has_capability('moodle/site:accessallgroups', $coursecontext);
if ($usergroups = groups_get_all_groups($course->id, $user->id)) {
$groupstr = '';
foreach ($usergroups as $group) {
if ($course->groupmode == SEPARATEGROUPS and !$accessallgroups and $user->id != $USER->id) {
if (!groups_is_member($group->id, $user->id)) {
continue;
}
}
if ($course->groupmode != NOGROUPS) {
$groupstr .= ' <a href="'.$CFG->wwwroot.'/user/index.php?id='.$course->id.'&amp;group='.$group->id.'">'.format_string($group->name).'</a>,';
} else {
$groupstr .= ' '.format_string($group->name); // The user/index.php shows groups only when course in group mode.
}
}
if ($groupstr !== '') {
echo html_writer::tag('dt', get_string('group'));
echo html_writer::tag('dd', rtrim($groupstr, ', '));
}
}
}
// Show other courses they may be in.
if (!isset($hiddenfields['mycourses'])) {
if ($mycourses = enrol_get_all_users_courses($user->id, true, null, 'visible DESC,sortorder ASC')) {
$shown = 0;
$courselisting = '';
foreach ($mycourses as $mycourse) {
if ($mycourse->category) {
context_helper::preload_from_record($mycourse);
$ccontext = context_course::instance($mycourse->id);
$cfullname = $ccontext->get_context_name(false);
if ($mycourse->id != $course->id) {
$linkattributes = null;
if ($mycourse->visible == 0) {
if (!has_capability('moodle/course:viewhiddencourses', $ccontext)) {
continue;
}
$linkattributes['class'] = 'dimmed';
}
$params = array('id' => $user->id, 'course' => $mycourse->id);
if ($showallcourses) {
$params['showallcourses'] = 1;
}
$url = new moodle_url('/user/view.php', $params);
$courselisting .= html_writer::link($url, $ccontext->get_context_name(false), $linkattributes);
$courselisting .= ', ';
} else {
$courselisting .= $cfullname . ", ";
$PAGE->navbar->add($cfullname);
}
}
$shown++;
if (!$showallcourses && $shown >= 20) {
$url = new moodle_url('/user/view.php', array('id' => $user->id, 'course' => $courseid, 'showallcourses' => 1));
$courselisting .= html_writer::link($url, '...', array('title' => get_string('viewmore')));
break;
}
}
echo html_writer::tag('dt', get_string('courseprofiles'));
echo html_writer::tag('dd', rtrim($courselisting, ', '));
}
}
if (!empty($CFG->enablebadges) && !empty($CFG->badges_allowcoursebadges)) {
profile_display_badges($user->id, $courseid);
}
if (!isset($hiddenfields['suspended'])) {
if ($user->suspended) {
echo html_writer::tag('dt', "&nbsp;");
echo html_writer::tag('dd', get_string('suspended', 'auth'));
}
}
if (has_capability('moodle/user:viewlastip', $usercontext) && !isset($hiddenfields['lastip'])) {
if ($user->lastip) {
$iplookupurl = new moodle_url('/iplookup/index.php', array('ip' => $user->lastip, 'user' => $USER->id));
$ipstring = html_writer::link($iplookupurl, $user->lastip);
} else {
$ipstring = get_string("none");
}
echo html_writer::tag('dt', get_string('lastip'));
echo html_writer::tag('dd', $ipstring);
}
echo html_writer::end_tag('dl');
echo "</div></div>"; // Closing desriptionbox and userprofilebox.
if (empty($CFG->forceloginforprofiles) || $currentuser || has_capability('moodle/user:viewdetails', $usercontext)
|| has_coursecontact_role($id)) {
echo '<div class="fullprofilelink">';
echo html_writer::link($CFG->wwwroot.'/user/profile.php?id='.$id, get_string('fullprofile'));
echo '</div>';
}
// TODO Add more useful overview info for teachers here, see below.
// Show links to notes made about this student (must click to display, for privacy).
// Recent comments made in this course.
// Recent blogs associated with this course and items in it.
// Render custom blocks.
$renderer = $PAGE->get_renderer('core_user', 'myprofile');
$tree = core_user\output\myprofile\manager::build_tree($user, $currentuser, $course);
echo $renderer->render($tree);
echo '</div>'; // Userprofile class.