".&mt('Select Course')."";
+ my ($form,$unameele,$udomele,$desc,$extra_element,$multflag,$selecttype,
+ $typeelement) = @_;
+ my $type = $selecttype;
+ my $linktext = &mt('Select Course');
+ if ($selecttype eq 'Community') {
+ $linktext = &mt('Select Community');
+ } elsif ($selecttype eq 'Course/Community') {
+ $linktext = &mt('Select Course/Community');
+ $type = '';
+ }
+ return ''
+ ."".$linktext.' '
+ .' ';
}
sub selectauthor_link {
@@ -610,6 +782,14 @@ sub selectauthor_link {
&mt('Select Author').'';
}
+sub selectuser_link {
+ my ($form,$unameelem,$domelem,$lastelem,$firstelem,$emailelem,$hdomelem,
+ $coursedom,$linktext,$caller) = @_;
+ return ''.$linktext.' ';
+}
+
sub check_uncheck_jscript {
my $jscript = <<"ENDSCRT";
function checkAll(field) {
@@ -657,6 +837,72 @@ sub select_timezone {
return $output;
}
+sub select_datelocale {
+ my ($name,$selected,$onchange,$includeempty)=@_;
+ my $output=''."\n";
+ if ($includeempty) {
+ $output .= '{'id'};
+ if ($id ne '') {
+ my $en_terr = $locale->{'en_territory'};
+ my $native_terr = $locale->{'native_territory'};
+ my @languages = &Apache::lonlocal::preferred_languages();
+ if (grep(/^en$/,@languages) || !@languages) {
+ if ($en_terr ne '') {
+ $locale_names{$id} = '('.$en_terr.')';
+ } elsif ($native_terr ne '') {
+ $locale_names{$id} = $native_terr;
+ }
+ } else {
+ if ($native_terr ne '') {
+ $locale_names{$id} = $native_terr.' ';
+ } elsif ($en_terr ne '') {
+ $locale_names{$id} = '('.$en_terr.')';
+ }
+ }
+ push (@possibles,$id);
+ }
+ }
+ }
+ foreach my $item (sort(@possibles)) {
+ $output.= ' $item";
+ if ($locale_names{$item} ne '') {
+ $output.=" $locale_names{$item} \n";
+ }
+ $output.="\n";
+ }
+ $output.=" ";
+ return $output;
+}
+
+sub select_language {
+ my ($name,$selected,$includeempty) = @_;
+ my %langchoices;
+ if ($includeempty) {
+ %langchoices = ('' => 'No language preference');
+ }
+ foreach my $id (&languageids()) {
+ my $code = &supportedlanguagecode($id);
+ if ($code) {
+ $langchoices{$code} = &plainlanguagedescription($id);
+ }
+ }
+ return &select_form($selected,$name,%langchoices);
+}
+
=pod
=item * &linked_select_forms(...)
@@ -743,7 +989,8 @@ sub linked_select_forms {
my $first = "document.$formname.$firstselectname";
# output the javascript to do the changing
my $result = '';
- $result.="
END
# output the initial values for the selection lists
@@ -873,16 +1121,18 @@ sub help_open_topic {
if ($text ne "") {
$template .=
"".
- "$text ";
+ "$text ";
}
# Add the graphic
my $title = &mt('Online Help');
- my $helpicon=&lonhttpdurl("/res/adm/pages/help.png");
- $template .= <<"ENDTEMPLATE";
-
-ENDTEMPLATE
- if ($text ne '') { $template.='
' };
+ my $helpicon=&lonhttpdurl("/adm/help/help.png");
+ $template .= ''.
+ ' ';
+ if ($text ne '') {
+ $template.='';
+ }
return $template;
}
@@ -890,29 +1140,40 @@ ENDTEMPLATE
# This is a quicky function for Latex cheatsheet editing, since it
# appears in at least four places
sub helpLatexCheatsheet {
- my $other = shift;
+ my ($topic,$text,$not_author) = @_;
+ my $out;
my $addOther = '';
- if ($other) {
- $addOther = Apache::loncommon::help_open_topic($other, shift,
+ if ($topic) {
+ $addOther = &Apache::loncommon::help_open_topic($topic,$text,
undef, undef, 600) .
'';
}
- return ''.
- $addOther .
- &Apache::loncommon::help_open_topic("Greek_Symbols",&mt('Greek Symbols'),
- undef,undef,600)
- .' '.
- &Apache::loncommon::help_open_topic("Other_Symbols",&mt('Other Symbols'),
- undef,undef,600)
- .'
';
+ $out = ''.
+ $addOther .
+ &Apache::loncommon::help_open_topic("Greek_Symbols",&mt('Greek Symbols'),
+ undef,undef,600).
+ ' '.
+ &Apache::loncommon::help_open_topic("Other_Symbols",&mt('Other Symbols'),
+ undef,undef,600).
+ ' ';
+ unless ($not_author) {
+ $out .= ''.
+ &Apache::loncommon::help_open_topic("Authoring_Output_Tags",&mt('Output Tags'),
+ undef,undef,600).
+ ' ';
+ }
+ $out .= '
';
+ return $out;
}
sub general_help {
my $helptopic='Student_Intro';
if ($env{'request.role'}=~/^(ca|au)/) {
$helptopic='Authoring_Intro';
- } elsif ($env{'request.role'}=~/^cc/) {
+ } elsif ($env{'request.role'}=~/^(cc|co)/) {
$helptopic='Course_Coordination_Intro';
+ } elsif ($env{'request.role'}=~/^dc/) {
+ $helptopic='Domain_Coordination_Intro';
}
return $helptopic;
}
@@ -929,7 +1190,9 @@ sub update_help_link {
my $banner_link = "/adm/helpmenu?page=banner&topic=$topic&component_help=$component_help&faq=$faq&bug=$bug&origurl=$origurl&stamp=$timestamp&stayonpage=$stayOnPage";
my $output .= <<"ENDOUTPUT";
ENDOUTPUT
return $output;
@@ -1006,8 +1269,8 @@ sub help_menu_js {
my $template .= <<"ENDTEMPLATE";
ENDTEMPLATE
return $template;
@@ -1301,6 +1564,7 @@ sub resize_textarea_js {
my $geometry = &viewport_geometry_js();
return <<"RESIZE";
RESIZE
@@ -1502,9 +1767,9 @@ sub create_text_file {
$fh = Apache::File->new('>/home/httpd'.$filename);
if (! defined($fh)) {
$r->log_error("Couldn't open $filename for output $!");
- $r->print("Problems occured in creating the output file. ".
- "This error has been logged. ".
- "Please alert your LON-CAPA administrator.");
+ $r->print(&mt('Problems occurred in creating the output file. '
+ .'This error has been logged. '
+ .'Please alert your LON-CAPA administrator.'));
}
return ($fh,$filename)
}
@@ -1571,7 +1836,7 @@ sub multiple_select_form {
$size = scalar(keys(%$hash));
}
}
- $output.="\n";
+ $output.="\n".'';
my @order;
if (ref($order) eq 'ARRAY') {
@order = @{$order};
@@ -1617,7 +1882,7 @@ sub select_form {
$selectform.=
'&').'" '.
($key eq $def ? 'selected="selected" ' : '').
- ">".&mt($hash{$key})." \n";
+ ">".$hash{$key}."\n";
}
$selectform.=" ";
return $selectform;
@@ -1628,17 +1893,17 @@ sub select_form {
sub display_filter {
if (!$env{'form.show'}) { $env{'form.show'}=10; }
if (!$env{'form.displayfilter'}) { $env{'form.displayfilter'}='currentfolder'; }
- return ''.&mt('Records [_1]',
+ return ''.&mt('Records [_1]',
&Apache::lonmeta::selectbox('show',$env{'form.show'},undef,
(&mt('all'),10,20,50,100,1000,10000))).
- ' '.
+ ' '.
&mt('Filter [_1]',
&select_form($env{'form.displayfilter'},
'displayfilter',
('currentfolder' => 'Current folder/page',
'containing' => 'Containing phrase',
'none' => 'None'))).
- ' ';
+ ' ';
}
sub gradeleveldescription {
@@ -1682,7 +1947,7 @@ sub select_level_form {
=pod
-=item * &select_dom_form($defdom,$name,$includeempty,$showdomdesc)
+=item * &select_dom_form($defdom,$name,$includeempty,$showdomdesc,$onchange,$incdoms)
Returns a string containing a form to
allow a user to select the domain to preform an operation in.
@@ -1691,16 +1956,28 @@ See loncreateuser.pm for an example invo
If the $includeempty flag is set, it also includes an empty choice ("no domain
selected");
-If the $showdomdesc flag is set, the domain name is followed by the domain description.
+If the $showdomdesc flag is set, the domain name is followed by the domain description.
+
+The optional $onchange argument specifies what should occur if the domain selector is changed, e.g., 'this.form.submit()' if the form is to be automatically submitted.
+
+The optional $incdoms is a reference to an array of domains which will be the only available options.
=cut
#-------------------------------------------
sub select_dom_form {
- my ($defdom,$name,$includeempty,$showdomdesc) = @_;
- my @domains = sort {lc($a) cmp lc($b)} (&Apache::lonnet::all_domains());
+ my ($defdom,$name,$includeempty,$showdomdesc,$onchange,$incdoms) = @_;
+ if ($onchange) {
+ $onchange = ' onchange="'.$onchange.'"';
+ }
+ my @domains;
+ if (ref($incdoms) eq 'ARRAY') {
+ @domains = sort {lc($a) cmp lc($b)} (@{$incdoms});
+ } else {
+ @domains = sort {lc($a) cmp lc($b)} (&Apache::lonnet::all_domains());
+ }
if ($includeempty) { @domains=('',@domains); }
- my $selectdomain = "\n";
+ my $selectdomain = "\n";
foreach my $dom (@domains) {
$selectdomain.="'.$dom;
@@ -1756,7 +2033,7 @@ sub home_server_form_item {
if ($numlib > 1) {
$result .= ' '."\n";
if ($default) {
- $result .= ' '.&mt('default').
+ $result .= ' '.&mt('default').
' '."\n";
}
foreach my $hostid (sort(keys(%servers))) {
@@ -2051,14 +2328,14 @@ sub authform_kerberos {
$autharg,$jscall);
my ($authnum,%can_assign) = &get_assignable_auth($in{'domain'});
if ($in{'kerb_def_auth'} eq 'krb5') {
- $check5 = ' checked="on"';
+ $check5 = ' checked="checked"';
} else {
- $check4 = ' checked="on"';
+ $check4 = ' checked="checked"';
}
$krbarg = $in{'kerb_def_dom'};
if (defined($in{'curr_authtype'})) {
if ($in{'curr_authtype'} eq 'krb') {
- $krbcheck = ' checked="on"';
+ $krbcheck = ' checked="checked"';
if (defined($in{'mode'})) {
if ($in{'mode'} eq 'modifyuser') {
$krbcheck = '';
@@ -2066,10 +2343,10 @@ sub authform_kerberos {
}
if (defined($in{'curr_kerb_ver'})) {
if ($in{'curr_krb_ver'} eq '5') {
- $check5 = ' checked="on"';
+ $check5 = ' checked="checked"';
$check4 = '';
} else {
- $check4 = ' checked="on"';
+ $check4 = ' checked="checked"';
$check5 = '';
}
}
@@ -2090,7 +2367,7 @@ sub authform_kerberos {
}
} else {
if ($authnum == 1) {
- $authtype = ' ';
+ $authtype = ' ';
}
}
if (!$can_assign{'krb4'} && !$can_assign{'krb5'}) {
@@ -2099,7 +2376,7 @@ sub authform_kerberos {
if (defined($in{'mode'})) {
if ($in{'mode'} eq 'modifycourse') {
if ($authnum == 1) {
- $authtype = ' ';
+ $authtype = ' ';
}
}
}
@@ -2160,7 +2437,7 @@ sub authform_internal{
if (defined($in{'curr_authtype'})) {
if ($in{'curr_authtype'} eq 'int') {
if ($can_assign{'int'}) {
- $intcheck = 'checked="on" ';
+ $intcheck = 'checked="checked" ';
if (defined($in{'mode'})) {
if ($in{'mode'} eq 'modifyuser') {
$intcheck = '';
@@ -2176,7 +2453,7 @@ sub authform_internal{
}
} else {
if ($authnum == 1) {
- $authtype = ' ';
+ $authtype = ' ';
}
}
if (!$can_assign{'int'}) {
@@ -2185,7 +2462,7 @@ sub authform_internal{
if (defined($in{'mode'})) {
if ($in{'mode'} eq 'modifycourse') {
if ($authnum == 1) {
- $authtype = ' ';
+ $authtype = ' ';
}
}
}
@@ -2200,7 +2477,7 @@ sub authform_internal{
$result = &mt
('[_1] Internally authenticated (with initial password [_2])',
''.$authtype,' '.$autharg);
- $result.=" ".&mt('Visible input').' ';
+ $result.=" ".&mt('Visible input').' ';
return $result;
}
@@ -2215,7 +2492,7 @@ sub authform_local{
if (defined($in{'curr_authtype'})) {
if ($in{'curr_authtype'} eq 'loc') {
if ($can_assign{'loc'}) {
- $loccheck = 'checked="on" ';
+ $loccheck = 'checked="checked" ';
if (defined($in{'mode'})) {
if ($in{'mode'} eq 'modifyuser') {
$loccheck = '';
@@ -2231,7 +2508,7 @@ sub authform_local{
}
} else {
if ($authnum == 1) {
- $authtype = ' ';
+ $authtype = ' ';
}
}
if (!$can_assign{'loc'}) {
@@ -2240,7 +2517,7 @@ sub authform_local{
if (defined($in{'mode'})) {
if ($in{'mode'} eq 'modifycourse') {
if ($authnum == 1) {
- $authtype = ' ';
+ $authtype = ' ';
}
}
}
@@ -2269,7 +2546,7 @@ sub authform_filesystem{
if (defined($in{'curr_authtype'})) {
if ($in{'curr_authtype'} eq 'fsys') {
if ($can_assign{'fsys'}) {
- $fsyscheck = 'checked="on" ';
+ $fsyscheck = 'checked="checked" ';
if (defined($in{'mode'})) {
if ($in{'mode'} eq 'modifyuser') {
$fsyscheck = '';
@@ -2282,7 +2559,7 @@ sub authform_filesystem{
}
} else {
if ($authnum == 1) {
- $authtype = ' ';
+ $authtype = ' ';
}
}
if (!$can_assign{'fsys'}) {
@@ -2291,7 +2568,7 @@ sub authform_filesystem{
if (defined($in{'mode'})) {
if ($in{'mode'} eq 'modifycourse') {
if ($authnum == 1) {
- $authtype = ' ';
+ $authtype = ' ';
}
}
}
@@ -2659,6 +2936,43 @@ sub flush_email_cache {
&Apache::lonnet::devalidate_cache_new('emailscache',$id);
}
+# -------------------------------------------------------------------- getlangs
+
+=pod
+
+=item * &getlangs($uname,$udom)
+
+Gets a user's language preference and returns it as a hash with key:
+language.
+
+=cut
+
+
+sub getlangs {
+ my ($uname,$udom) = @_;
+ if (!$udom) { $udom =$env{'user.domain'}; }
+ if (!$uname) { $uname=$env{'user.name'}; }
+ my $id=$uname.':'.$udom;
+ my ($langs,$cached)=&Apache::lonnet::is_cached_new('userlangs',$id);
+ if ($cached) {
+ return %{$langs};
+ } else {
+ my %loadlangs=&Apache::lonnet::get('environment',['languages'],
+ $udom,$uname);
+ &Apache::lonnet::do_cache_new('userlangs',$id,\%loadlangs);
+ return %loadlangs;
+ }
+}
+
+sub flush_langs_cache {
+ my ($uname,$udom)=@_;
+ if (!$udom) { $udom =$env{'user.domain'}; }
+ if (!$uname) { $uname=$env{'user.name'}; }
+ return if ($udom eq 'public' && $uname eq 'public');
+ my $id=$uname.':'.$udom;
+ &Apache::lonnet::devalidate_cache_new('userlangs',$id);
+}
+
# ------------------------------------------------------------------ Screenname
=pod
@@ -2677,6 +2991,25 @@ sub screenname {
return $names{'screenname'};
}
+# ------------------------------------------------------------- Confirm Wrapper
+=pod
+
+=item confirmwrapper
+
+Wrap messages about completion of operation in box
+
+=cut
+
+sub confirmwrapper {
+ my ($message)=@_;
+ if ($message) {
+ return "\n".''."\n"
+ .$message."\n"
+ .'
'."\n";
+ } else {
+ return $message;
+ }
+}
# ------------------------------------------------------------- Message Wrapper
@@ -2703,7 +3036,7 @@ sub aboutmewrapper {
return;
}
return ''.$link.' ';
+ ($target?' target="$target"':'').' title="'.&mt("View this user's personal information page").'">'.$link.'';
}
# ------------------------------------------------------------ Syllabus Wrapper
@@ -2718,7 +3051,7 @@ sub syllabuswrapper {
}
sub track_student_link {
- my ($linktext,$sname,$sdom,$target,$start) = @_;
+ my ($linktext,$sname,$sdom,$target,$start,$only_body) = @_;
my $link ="/adm/trackstudent?";
my $title = 'View recent activity';
if (defined($sname) && $sname !~ /^\s*$/ &&
@@ -2732,12 +3065,34 @@ sub track_student_link {
$target = '';
}
if ($start) { $link.='&start='.$start; }
+ if ($only_body) { $link .= '&only_body=1'; }
$title = &mt($title);
$linktext = &mt($linktext);
return qq{$linktext }.
&help_open_topic('View_recent_activity');
}
+sub slot_reservations_link {
+ my ($linktext,$sname,$sdom,$target) = @_;
+ my $link ="/adm/slotrequest?command=showresv&origin=aboutme";
+ my $title = 'View slot reservation history';
+ if (defined($sname) && $sname !~ /^\s*$/ &&
+ defined($sdom) && $sdom !~ /^\s*$/) {
+ $link .= "&uname=$sname&udom=$sdom";
+ $title .= ' of this student';
+ }
+ if (defined($target) && $target !~ /^\s*$/) {
+ $target = qq{target="$target"};
+ } else {
+ $target = '';
+ }
+ $title = &mt($title);
+ $linktext = &mt($linktext);
+ return qq{$linktext };
+# FIXME uncomment when help item created: &help_open_topic('Slot_Reservation_History');
+
+}
+
# ===================================================== Display a student photo
@@ -2940,7 +3295,7 @@ sub fileextensions {
sub display_languages {
my %languages=();
- foreach my $lang (&preferred_languages()) {
+ foreach my $lang (&Apache::lonlocal::preferred_languages()) {
$languages{$lang}=1;
}
&get_unprocessed_cgi($ENV{'QUERY_STRING'},['displaylanguage']);
@@ -2952,54 +3307,9 @@ sub display_languages {
return %languages;
}
-sub preferred_languages {
- my @languages=();
- if (($env{'request.role.adv'}) && ($env{'form.languages'})) {
- @languages=(@languages,split(/\s*(\,|\;|\:)\s*/,$env{'form.languages'}));
- }
- if ($env{'course.'.$env{'request.course.id'}.'.languages'}) {
- @languages=(@languages,split(/\s*(\,|\;|\:)\s*/,
- $env{'course.'.$env{'request.course.id'}.'.languages'}));
- }
-
- if ($env{'environment.languages'}) {
- @languages=(@languages,
- split(/\s*(\,|\;|\:)\s*/,$env{'environment.languages'}));
- }
- my $browser=$ENV{'HTTP_ACCEPT_LANGUAGE'};
- if ($browser) {
- my @browser =
- map { (split(/\s*;\s*/,$_))[0] } (split(/\s*,\s*/,$browser));
- push(@languages,@browser);
- }
-
- foreach my $domtype ($env{'user.domain'},$env{'request.role.domain'},
- $Apache::lonnet::perlvar{'lonDefDomain'}) {
- if ($domtype ne '') {
- my %domdefs = &Apache::lonnet::get_domain_defaults($domtype);
- if ($domdefs{'lang_def'} ne '') {
- push(@languages,$domdefs{'lang_def'});
- }
- }
- }
-# turn "en-ca" into "en-ca,en"
- my @genlanguages;
- foreach my $lang (@languages) {
- unless ($lang=~/\w/) { next; }
- push(@genlanguages,$lang);
- if ($lang=~/(\-|\_)/) {
- push(@genlanguages,(split(/(\-|\_)/,$lang))[0]);
- }
- }
- #uniqueify the languages list
- my %count;
- @genlanguages = map { $count{$_}++ == 0 ? $_ : () } @genlanguages;
- return @genlanguages;
-}
-
sub languages {
my ($possible_langs) = @_;
- my @preferred_langs = &preferred_languages();
+ my @preferred_langs = &Apache::lonlocal::preferred_languages();
if (!ref($possible_langs)) {
if( wantarray ) {
return @preferred_langs;
@@ -3020,6 +3330,28 @@ sub languages {
return $preferred_possibilities[0];
}
+sub user_lang {
+ my ($touname,$toudom,$fromcid) = @_;
+ my @userlangs;
+ if (($fromcid ne '') && ($env{'course.'.$fromcid.'.languages'} ne '')) {
+ @userlangs=(@userlangs,split(/\s*(\,|\;|\:)\s*/,
+ $env{'course.'.$fromcid.'.languages'}));
+ } else {
+ my %langhash = &getlangs($touname,$toudom);
+ if ($langhash{'languages'} ne '') {
+ @userlangs = split(/\s*(\,|\;|\:)\s*/,$langhash{'languages'});
+ } else {
+ my %domdefs = &Apache::lonnet::get_domain_defaults($toudom);
+ if ($domdefs{'lang_def'} ne '') {
+ @userlangs = ($domdefs{'lang_def'});
+ }
+ }
+ }
+ my @languages=&Apache::lonlocal::get_genlanguages(@userlangs);
+ my $user_lh = Apache::localize->get_handle(@languages);
+ return $user_lh;
+}
+
###############################################################
## Student Answer Attempts ##
###############################################################
@@ -3158,7 +3490,7 @@ sub relative_to_absolute {
}
$thisdir=~s-/[^/]*$--;
foreach my $link (@rlinks) {
- unless (($link=~/^http:\/\//i) ||
+ unless (($link=~/^https?\:\/\//i) ||
($link=~/^\//) ||
($link=~/^javascript:/i) ||
($link=~/^mailto:/i) ||
@@ -3343,16 +3675,21 @@ sub pprmlink {
sub timehash {
- my @ltime=localtime(shift);
- return ( 'seconds' => $ltime[0],
- 'minutes' => $ltime[1],
- 'hours' => $ltime[2],
- 'day' => $ltime[3],
- 'month' => $ltime[4]+1,
- 'year' => $ltime[5]+1900,
- 'weekday' => $ltime[6],
- 'dayyear' => $ltime[7]+1,
- 'dlsav' => $ltime[8] );
+ my ($thistime) = @_;
+ my $timezone = &Apache::lonlocal::gettimezone();
+ my $dt = DateTime->from_epoch(epoch => $thistime)
+ ->set_time_zone($timezone);
+ my $wday = $dt->day_of_week();
+ if ($wday == 7) { $wday = 0; }
+ return ( 'second' => $dt->second(),
+ 'minute' => $dt->minute(),
+ 'hour' => $dt->hour(),
+ 'day' => $dt->day_of_month(),
+ 'month' => $dt->month(),
+ 'year' => $dt->year(),
+ 'weekday' => $wday,
+ 'dayyear' => $dt->day_of_year(),
+ 'dlsav' => $dt->is_dst() );
}
sub utc_string {
@@ -3362,6 +3699,24 @@ sub utc_string {
sub maketime {
my %th=@_;
+ my ($epoch_time,$timezone,$dt);
+ $timezone = &Apache::lonlocal::gettimezone();
+ eval {
+ $dt = DateTime->new( year => $th{'year'},
+ month => $th{'month'},
+ day => $th{'day'},
+ hour => $th{'hour'},
+ minute => $th{'minute'},
+ second => $th{'second'},
+ time_zone => $timezone,
+ );
+ };
+ if (!$@) {
+ $epoch_time = $dt->epoch;
+ if ($epoch_time) {
+ return $epoch_time;
+ }
+ }
return POSIX::mktime(
($th{'seconds'},$th{'minutes'},$th{'hours'},
$th{'day'},$th{'month'}-1,$th{'year'}-1900,0,0,-1));
@@ -3386,6 +3741,7 @@ sub findallcourses {
if (!%roles) {
%roles = (
cc => 1,
+ co => 1,
in => 1,
ep => 1,
ta => 1,
@@ -3712,7 +4068,7 @@ sub blocking_status {
&Apache::lonnet::coursedescription($course);
$coursedesc = $courseinfo{'description'};
}
- $category = "Group files in the course '$coursedesc'";
+ $category = "Group portfolio files in the course '$coursedesc'";
} else {
$category = 'Portfolio files belonging to ';
if ($env{'user.name'} eq 'public' &&
@@ -3742,6 +4098,60 @@ sub blocking_status {
###############################################
+sub check_ip_acc {
+ my ($acc)=@_;
+ &Apache::lonxml::debug("acc is $acc");
+ if (!defined($acc) || $acc =~ /^\s*$/ || $acc =~/^\s*no\s*$/i) {
+ return 1;
+ }
+ my $allowed=0;
+ my $ip=$env{'request.host'} || $ENV{'REMOTE_ADDR'};
+
+ my $name;
+ foreach my $pattern (split(',',$acc)) {
+ $pattern =~ s/^\s*//;
+ $pattern =~ s/\s*$//;
+ if ($pattern =~ /\*$/) {
+ #35.8.*
+ $pattern=~s/\*//;
+ if ($ip =~ /^\Q$pattern\E/) { $allowed=1; }
+ } elsif ($pattern =~ /(\d+\.\d+\.\d+)\.\[(\d+)-(\d+)\]$/) {
+ #35.8.3.[34-56]
+ my $low=$2;
+ my $high=$3;
+ $pattern=$1;
+ if ($ip =~ /^\Q$pattern\E/) {
+ my $last=(split(/\./,$ip))[3];
+ if ($last <=$high && $last >=$low) { $allowed=1; }
+ }
+ } elsif ($pattern =~ /^\*/) {
+ #*.msu.edu
+ $pattern=~s/\*//;
+ if (!defined($name)) {
+ use Socket;
+ my $netaddr=inet_aton($ip);
+ ($name)=gethostbyaddr($netaddr,AF_INET);
+ }
+ if ($name =~ /\Q$pattern\E$/i) { $allowed=1; }
+ } elsif ($pattern =~ /\d+\.\d+\.\d+\.\d+/) {
+ #127.0.0.1
+ if ($ip =~ /^\Q$pattern\E/) { $allowed=1; }
+ } else {
+ #some.name.com
+ if (!defined($name)) {
+ use Socket;
+ my $netaddr=inet_aton($ip);
+ ($name)=gethostbyaddr($netaddr,AF_INET);
+ }
+ if ($name =~ /\Q$pattern\E$/i) { $allowed=1; }
+ }
+ if ($allowed) { last; }
+ }
+ return $allowed;
+}
+
+###############################################
+
=pod
=head1 Domain Template Functions
@@ -3761,7 +4171,7 @@ sub determinedomain {
my $domain=shift;
if (! $domain) {
# Determine domain if we have not been given one
- $domain = $Apache::lonnet::perlvar{'lonDefDomain'};
+ $domain = &Apache::lonnet::default_login_domain();
if ($env{'user.domain'}) { $domain=$env{'user.domain'}; }
if ($env{'request.role.domain'}) {
$domain=$env{'request.role.domain'};
@@ -3790,7 +4200,14 @@ sub get_domainconf {
if (ref($domconfig{'login'}) eq 'HASH') {
if (keys(%{$domconfig{'login'}})) {
foreach my $key (keys(%{$domconfig{'login'}})) {
- $designhash{$udom.'.login.'.$key}=$domconfig{'login'}{$key};
+ if (ref($domconfig{'login'}{$key}) eq 'HASH') {
+ foreach my $img (keys(%{$domconfig{'login'}{$key}})) {
+ $designhash{$udom.'.login.'.$key.'_'.$img} =
+ $domconfig{'login'}{$key}{$img};
+ }
+ } else {
+ $designhash{$udom.'.login.'.$key}=$domconfig{'login'}{$key};
+ }
}
} else {
$legacy{'login'} = 1;
@@ -4012,7 +4429,7 @@ sub bodytag {
my $font = &designparm($function.'.font',$domain);
my $pgbg = $bgcolor || &designparm($function.'.pgbg',$domain);
- my %design = ( 'style' => 'margin-top: 0px',
+ my %design = ( 'style' => 'margin-top: 0',
'bgcolor' => $pgbg,
'text' => $font,
'alink' => &designparm($function.'.alink',$domain),
@@ -4300,8 +4717,8 @@ sub standard_css {
my $sans = 'Verdana,Arial,Helvetica,sans-serif';
my $mono = 'monospace';
my $data_table_head = $tabbg;
- my $data_table_light = '#EEEEEE';
- my $data_table_dark = '#DDDDDD';
+ my $data_table_light = '#FAFAFA';
+ my $data_table_dark = '#F0F0F0';
my $data_table_darker = '#CCCCCC';
my $data_table_highlight = '#FFFF00';
my $mail_new = '#FFBB77';
@@ -4314,15 +4731,25 @@ sub standard_css {
my $mail_other_hover = '#669999';
my $table_header = '#DDDDDD';
my $feedback_link_bg = '#BBBBBB';
+ my $lg_border_color = '#C8C8C8';
my $border = ($env{'browser.type'} eq 'explorer' ||
- $env{'browser.type'} eq 'safari' ) ? '0px 2px 0px 2px'
- : '0px 3px 0px 4px';
+ $env{'browser.type'} eq 'safari' ) ? '0 2px 0 2px'
+ : '0 3px 0 4px';
return < td {
+ background-color: #CCCCCC;
+ font-weight: bold;
+ text-align: left;
+}
table.LC_data_table tr.LC_odd_row > td,
+table.LC_pick_box tr > td.LC_odd_row,
table.LC_aboutme_port tr td {
background-color: $data_table_light;
padding: 2px;
}
table.LC_data_table tr.LC_even_row > td,
+table.LC_pick_box tr > td.LC_even_row,
table.LC_aboutme_port tr.LC_even_row td {
background-color: $data_table_dark;
+ padding: 2px;
}
table.LC_data_table tr.LC_data_table_highlight td {
background-color: $data_table_darker;
@@ -4642,7 +5102,7 @@ table.LC_nested_outer tr td.LC_subheader
text-align: right;
}
table.LC_nested tr.LC_info_row td {
- background-color: #CCC;
+ background-color: #CCCCCC;
font-weight: bold;
font-size: small;
text-align: center;
@@ -4652,7 +5112,7 @@ table.LC_nested_outer tr th.LC_left_item
text-align: left;
}
table.LC_nested td {
- background-color: #FFF;
+ background-color: #FFFFFF;
font-size: small;
}
table.LC_nested_outer tr th.LC_right_item,
@@ -4663,7 +5123,7 @@ table.LC_nested tr td.LC_right_item {
}
table.LC_nested tr.LC_odd_row td {
- background-color: #EEE;
+ background-color: #EEEEEE;
}
table.LC_createuser {
@@ -4674,7 +5134,7 @@ table.LC_createuser tr.LC_section_row td
}
table.LC_createuser tr.LC_info_row td {
- background-color: #CCC;
+ background-color: #CCCCCC;
font-weight: bold;
text-align: center;
}
@@ -4730,10 +5190,10 @@ table.LC_mail_list tr.LC_mail_odd {
table#LC_portfolio_actions {
width: auto;
background: $pgbg;
- border: 0px;
+ border: none;
border-spacing: 2px 2px;
- padding: 0px;
- margin: 0px;
+ padding: 0;
+ margin: 0;
border-collapse: separate;
}
table#LC_portfolio_actions td.LC_label {
@@ -4789,6 +5249,49 @@ table#LC_browser tr.LC_browser_file_meta
table#LC_browser tr.LC_browser_folder {
background: #CCCCFF;
}
+
+table.LC_data_table tr > td.LC_browser_file,
+table.LC_data_table tr > td.LC_browser_file_published {
+ background: #AAEE77;
+}
+
+table.LC_data_table tr > td.LC_browser_file_locked,
+table.LC_data_table tr > td.LC_browser_file_unpublished {
+ background: #FFAA99;
+}
+
+table.LC_data_table tr > td.LC_browser_file_obsolete {
+ background: #888888;
+}
+
+table.LC_data_table tr > td.LC_browser_file_modified,
+table.LC_data_table tr > td.LC_browser_file_metamodified {
+ background: #F8F866;
+}
+
+table.LC_data_table tr.LC_browser_folder > td {
+ background: #E0E8FF;
+}
+
+table.LC_data_table tr > td.LC_roles_is {
+/* background: #77FF77; */
+}
+table.LC_data_table tr > td.LC_roles_future {
+ background: #FFFF77;
+}
+table.LC_data_table tr > td.LC_roles_will {
+ background: #FFAA77;
+}
+table.LC_data_table tr > td.LC_roles_expired {
+ background: #FF7777;
+}
+table.LC_data_table tr > td.LC_roles_will_not {
+ background: #AAFF77;
+}
+table.LC_data_table tr > td.LC_roles_selected {
+ background: #11CC55;
+}
+
span.LC_current_location {
font-size: x-large;
background: $pgbg;
@@ -4834,9 +5337,9 @@ table.LC_parm_overview_restrictions th {
border-color: $pgbg;
}
table#LC_helpmenu {
- border: 0px;
+ border: none;
height: 55px;
- border-spacing: 0px;
+ border-spacing: 0;
}
table#LC_helpmenu fieldset legend {
@@ -4847,7 +5350,7 @@ table#LC_helpmenu_links {
width: 100%;
border: 1px solid black;
background: $pgbg;
- padding: 0px;
+ padding: 0;
border-spacing: 1px;
}
table#LC_helpmenu_links tr td {
@@ -4889,6 +5392,7 @@ table.LC_pick_box td.LC_pick_box_title {
background: $tabbg;
font-weight: bold;
text-align: right;
+ vertical-align: top;
width: 184px;
padding: 8px;
}
@@ -4909,7 +5413,7 @@ table.LC_pick_box td.LC_pick_box_select
padding: 8px;
}
table.LC_pick_box td.LC_pick_box_separator {
- padding: 0px;
+ padding: 0;
height: 1px;
background: black;
}
@@ -4951,7 +5455,7 @@ table.LC_helpform_receipt td.LC_oddrow_v
background-color: $data_table_light;
}
table.LC_helpform_receipt td.LC_pick_box_separator {
- padding: 0px;
+ padding: 0;
height: 1px;
background: black;
}
@@ -4984,7 +5488,7 @@ table.LC_group_priv_box td.LC_groups_fun
}
table.LC_group_priv td {
text-align: left;
- padding: 0px;
+ padding: 0;
}
table.LC_notify_front_page {
@@ -5005,6 +5509,7 @@ table.LC_notify_front_page td {
background: $tabbg;
vertical-align: middle;
margin: 2ex 0ex 2ex 0ex;
+ padding: 3px;
}
.LC_topic_bar span {
vertical-align: middle;
@@ -5106,7 +5611,7 @@ table.LC_prior_match tr td {
border: 1px solid #000000;
}
-span.LC_nobreak {
+.LC_nobreak {
white-space: nowrap;
}
@@ -5121,7 +5626,7 @@ span.LC_cusr_subheading {
table.LC_docs_documents {
background: #BBBBBB;
- border-width: 0px;
+ border-width: 0;
border-collapse: collapse;
}
@@ -5138,7 +5643,7 @@ table.LC_docs_documents td.LC_docs_docum
}
.LC_docs_entry_move {
- border: 0px;
+ border: none;
border-collapse: collapse;
}
@@ -5194,7 +5699,7 @@ table.LC_sty_end {
}
table.LC_double_column {
- border-width: 0px;
+ border-width: 0;
border-collapse: collapse;
width: 100%;
padding: 2px;
@@ -5333,7 +5838,7 @@ table.LC_edit_problem_header_title {
background: $tabbg;
border-collapse: collapse;
- padding: 0px
+ padding: 0;
}
div.LC_edit_problem_discards {
@@ -5349,8 +5854,39 @@ hr.LC_edit_problem_divide {
color: $tabbg;
background-color: $tabbg;
height: 3px;
- border: 0px;
+ border: none;
+}
+img.stift{
+ border-width:0;
+ vertical-align:middle;
+}
+
+table#LC_mainmenu{
+ margin-top:10px;
+ width:80%;
+
+}
+
+table#LC_mainmenu td.LC_mainmenu_col_fieldset{
+ vertical-align: top;
+ width: 45%;
+}
+.LC_mainmenu_fieldset_category {
+ color: $font;
+ background: $pgbg;
+ font-family: $sans;
+ font-size: small;
+ font-weight: bold;
+}
+fieldset#LC_mainmenu_fieldset {
+ margin:0 10px 10px 0;
+
+}
+
+div.LC_createcourse {
+ margin: 10px 10px 10px 10px;
}
+
END
}
@@ -5478,7 +6014,8 @@ sub xml_begin {
.'';
} else {
- $output='';
+ $output=''.
+ '';
}
return $output;
}
@@ -5619,10 +6156,26 @@ sub start_page {
if ($args->{'html_encode'}) {
$result = &html_encode($result);
}
+ #Breadcrumbs
+ if (exists($args->{'bread_crumbs'}) or exists($args->{'bread_crumbs_component'})) {
+ &Apache::lonhtmlcommon::clear_breadcrumbs();
+ #if any br links exists, add them to the breadcrumbs
+ if (exists($args->{'bread_crumbs'}) and ref($args->{'bread_crumbs'}) eq 'ARRAY') {
+ foreach my $crumb (@{$args->{'bread_crumbs'}}){
+ &Apache::lonhtmlcommon::add_breadcrumb($crumb);
+ }
+ }
+
+ #if bread_crumbs_component exists show it as headline else show only the breadcrumbs
+ if (exists($args->{'bread_crumbs_component'})){
+ $result .= &Apache::lonhtmlcommon::breadcrumbs($args->{'bread_crumbs_component'});
+ } else {
+ $result .= &Apache::lonhtmlcommon::breadcrumbs();
+ }
+ }
return $result;
}
-
=pod
=item * &head()
@@ -5847,13 +6400,13 @@ Returns either 'student','coordinator','
###############################################
sub get_users_function {
my $function = 'student';
- if ($env{'request.role'}=~/^(cc|in|ta|ep)/) {
+ if ($env{'request.role'}=~/^(cc|co|in|ta|ep)/) {
$function='coordinator';
}
if ($env{'request.role'}=~/^(su|dc|ad|li)/) {
$function='admin';
}
- if (($env{'request.role'}=~/^(au|ca)/) ||
+ if (($env{'request.role'}=~/^(au|ca|aa)/) ||
($ENV{'REQUEST_URI'}=~/^(\/priv|\~)/)) {
$function='author';
}
@@ -5864,6 +6417,37 @@ sub get_users_function {
=pod
+=item * &show_course()
+
+Used by lonmenu.pm and lonroles.pm to determine whether to use the word
+'Courses' or 'Roles' in inline navigation and on screen displaying user's roles.
+Inputs:
+None
+
+Outputs:
+Scalar: 1 if 'Course' to be used, 0 otherwise.
+
+=cut
+
+###############################################
+sub show_course {
+ my $course = !$env{'user.adv'};
+ if (!$env{'user.adv'}) {
+ foreach my $env (keys(%env)) {
+ next if ($env !~ m/^user\.priv\./);
+ if ($env !~ m/^user\.priv\.(?:st|cm)/) {
+ $course = 0;
+ last;
+ }
+ }
+ }
+ return $course;
+}
+
+###############################################
+
+=pod
+
=item * &check_user_status()
Determines current status of supplied role for a
@@ -5886,7 +6470,7 @@ sub check_user_status {
my $active_chk = 'none';
my $now = time;
if (@uroles > 0) {
- if (($role eq 'cc') || ($sec eq '') || (!defined($sec))) {
+ if (($role eq 'cc') || ($role eq 'co') || ($sec eq '') || (!defined($sec))) {
$srchstr = '/'.$cdom.'/'.$crs.'_'.$role;
} else {
$srchstr = '/'.$cdom.'/'.$crs.'/'.$sec.'_'.$role;
@@ -6367,6 +6951,8 @@ If the user's status includes multiple t
the largest default quota which applies to the user determines the
default quota returned.
+=back
+
=cut
###############################################
@@ -6379,21 +6965,37 @@ sub default_quota {
['quotas'],$udom);
if (ref($quotahash{'quotas'}) eq 'HASH') {
if ($inststatus ne '') {
- my @statuses = split(/:/,$inststatus);
+ my @statuses = map { &unescape($_); } split(/:/,$inststatus);
foreach my $item (@statuses) {
- if ($quotahash{'quotas'}{$item} ne '') {
- if ($defquota eq '') {
- $defquota = $quotahash{'quotas'}{$item};
- $settingstatus = $item;
- } elsif ($quotahash{'quotas'}{$item} > $defquota) {
- $defquota = $quotahash{'quotas'}{$item};
- $settingstatus = $item;
+ if (ref($quotahash{'quotas'}{'defaultquota'}) eq 'HASH') {
+ if ($quotahash{'quotas'}{'defaultquota'}{$item} ne '') {
+ if ($defquota eq '') {
+ $defquota = $quotahash{'quotas'}{'defaultquota'}{$item};
+ $settingstatus = $item;
+ } elsif ($quotahash{'quotas'}{'defaultquota'}{$item} > $defquota) {
+ $defquota = $quotahash{'quotas'}{'defaultquota'}{$item};
+ $settingstatus = $item;
+ }
+ }
+ } else {
+ if ($quotahash{'quotas'}{$item} ne '') {
+ if ($defquota eq '') {
+ $defquota = $quotahash{'quotas'}{$item};
+ $settingstatus = $item;
+ } elsif ($quotahash{'quotas'}{$item} > $defquota) {
+ $defquota = $quotahash{'quotas'}{$item};
+ $settingstatus = $item;
+ }
}
}
}
}
if ($defquota eq '') {
- $defquota = $quotahash{'quotas'}{'default'};
+ if (ref($quotahash{'quotas'}{'defaultquota'}) eq 'HASH') {
+ $defquota = $quotahash{'quotas'}{'defaultquota'}{'default'};
+ } else {
+ $defquota = $quotahash{'quotas'}{'default'};
+ }
$settingstatus = 'default';
}
} else {
@@ -6499,6 +7101,7 @@ sub user_picker {
# loncreateuser::print_user_query_page()
# has been completed.
next if ($option eq 'alc');
+ next if (($option eq 'crs') && ($env{'form.form'} eq 'requestcrs'));
next if ($option eq 'crs' && !$env{'request.course.id'});
if ($curr_selected{'srchin'} eq $option) {
$srchinsel .= '
@@ -6542,12 +7145,14 @@ sub user_picker {
if ($cancreate) {
$new_user_create = ' &"').'" onclick="javascript:setSearch(\'1\','.$caller.');" />
';
} else {
- my $helplink = ' href="javascript:helpMenu('."'display'".')"';
+ my $helplink = 'javascript:helpMenu('."'display'".')';
my %usertypetext = (
official => 'institutional',
unofficial => 'non-institutional',
);
- $new_user_create = ''.&mt("You are not authorized to create new $usertypetext{$usertype} users in this domain.").' '.&mt('Contact the helpdesk for assistance.',$helplink).' ';
+ $new_user_create = ''.
+ &mt("You are not authorized to create new $usertypetext{$usertype} users in this domain.").' '.
+ &mt('Please contact the [_1]helpdesk[_2] for assistance.','',' ').'
';
}
}
}
@@ -6584,6 +7189,7 @@ ENDSCRIPT
my $output = <<"END_BLOCK";
$new_user_create
-
-
END_BLOCK
+ $output .= &Apache::lonhtmlcommon::start_pick_box().
+ &Apache::lonhtmlcommon::row_title($lt{'doma'}).
+ $domform.
+ &Apache::lonhtmlcommon::row_closure().
+ &Apache::lonhtmlcommon::row_title($lt{'usr'}).
+ $srchbysel.
+ $srchtypesel.
+ ' '.
+ $srchinsel.
+ &Apache::lonhtmlcommon::row_closure(1).
+ &Apache::lonhtmlcommon::end_pick_box().
+ ' ';
return $output;
}
@@ -6799,12 +7402,16 @@ sub instrule_disallow_msg {
$text{'action'} = 'IDs';
}
}
- $response = &mt("The $text{'item'} you chose $text{'match'} the format of $text{'items'} defined for [_1] , but the $text{'item'} $text{'do'} not exist in the institutional directory.",$domdesc).' ';
+ $response = &mt("The $text{'item'} you chose $text{'match'} the format of $text{'items'} defined for [_1], but the $text{'item'} $text{'do'} not exist in the institutional directory.",''.$domdesc.' ').' ';
if ($mode eq 'upload') {
if ($checkitem eq 'username') {
$response .= &mt("You will need to modify your upload file so it will include $text{'action'} with a different format -- $text{'one'} that will not conflict with 'official' institutional $text{'items'}.");
} elsif ($checkitem eq 'id') {
- $response .= &mt("Either upload a file which includes $text{'action'} with a different format -- $text{'one'} that will not conflict with 'official' institutional $text{'items'}, or when associating fields with data columns, omit an association for the ID/Student Number field.");
+ $response .= &mt("Either upload a file which includes $text{'action'} with a different format -- $text{'one'} that will not conflict with 'official' institutional $text{'items'}, or when associating fields with data columns, omit an association for the Student/Employee ID field.");
+ }
+ } elsif ($mode eq 'selfcreate') {
+ if ($checkitem eq 'id') {
+ $response .= &mt("You must either choose $text{'action'} with a different format -- $text{'one'} that will not conflict with 'official' institutional $text{'items'}, or leave the ID field blank.");
}
} else {
if ($checkitem eq 'username') {
@@ -6825,6 +7432,7 @@ sub personal_data_fieldtitles {
middlename => 'Middle Name',
generation => 'Generation',
gen => 'Generation',
+ inststatus => 'Affiliation',
);
return %fieldtitles;
}
@@ -6834,7 +7442,7 @@ sub sorted_inst_types {
my ($usertypes,$order) = &Apache::lonnet::retrieve_inst_usertypes($dom);
my $othertitle = &mt('All users');
if ($env{'request.course.id'}) {
- $othertitle = 'any';
+ $othertitle = &mt('Any users');
}
my @types;
if (ref($order) eq 'ARRAY') {
@@ -6847,9 +7455,6 @@ sub sorted_inst_types {
}
if (keys(%{$usertypes}) > 0) {
$othertitle = &mt('Other users');
- if ($env{'request.course.id'}) {
- $othertitle = 'other';
- }
}
return ($othertitle,$usertypes,\@types);
}
@@ -6897,8 +7502,56 @@ sub get_institutional_codes {
=pod
+=head1 Slot Helpers
+
+=over 4
+
+=item * sorted_slots()
+
+Sorts an array of slot names in order of slot start time (earliest first).
+
+Inputs:
+
+=over 4
+
+slotsarr - Reference to array of unsorted slot names.
+
+slots - Reference to hash of hash, where outer hash keys are slot names.
+
+=back
+
+Returns:
+
+=over 4
+
+sorted - An array of slot names sorted by the start time of the slot.
+
=back
+=back
+
+=cut
+
+
+sub sorted_slots {
+ my ($slotsarr,$slots) = @_;
+ my @sorted;
+ if ((ref($slotsarr) eq 'ARRAY') && (ref($slots) eq 'HASH')) {
+ @sorted =
+ sort {
+ if (ref($slots->{$a}) && ref($slots->{$b})) {
+ return $slots->{$a}{'starttime'} <=> $slots->{$b}{'starttime'}
+ }
+ if (ref($slots->{$a})) { return -1;}
+ if (ref($slots->{$b})) { return 1;}
+ return 0;
+ } @{$slotsarr};
+ }
+ return @sorted;
+}
+
+=pod
+
=head1 HTTP Helpers
=over 4
@@ -7238,7 +7891,6 @@ sub check_for_upload {
}
}
}
- my $getpropath = 1;
if (($current_disk_usage + $filesize) > $disk_quota){
my $msg = ''.
&mt('Unable to upload [_1]. (size = [_2] kilobytes). Disk quota will be exceeded.',''.$fname.' ',$filesize).' '.
@@ -7450,7 +8102,7 @@ sub upfile_select_html {
# xml => &mt('HTML/XML'),
);
my $Str = ' '.
- ' Type: ';
+ ' '.&mt('Type').': ';
foreach my $type (sort(keys(%Types))) {
$Str .= ''.$Types{$type}." \n";
}
@@ -7496,7 +8148,8 @@ sub csv_print_samples {
$r->print(&mt('Samples').' '.&start_data_table().
&start_data_table_header_row());
foreach my $sample (sort({$a <=> $b} keys(%{ $samples->[0] }))) {
- $r->print(''.&mt('Column [_1]',($sample+1)).' '); }
+ $r->print(''.&mt('Column [_1]',($sample+1)).' ');
+ }
$r->print(&end_data_table_header_row());
foreach my $hash (@$samples) {
$r->print(&start_data_table_row());
@@ -7538,9 +8191,9 @@ sub csv_print_select_table {
&end_data_table_header_row()."\n");
foreach my $array_ref (@$d) {
my ($value,$display,$defaultcol)=@{ $array_ref };
- $r->print(&start_data_table_row().''.$display.' ');
+ $r->print(&start_data_table_row().''.$display.' ');
- $r->print('print('');
$r->print(' ');
foreach my $sample (sort({$a <=> $b} keys(%{ $samples->[0] }))) {
@@ -8194,9 +8847,11 @@ sub restore_settings {
=item * &build_recipient_list()
-Build recipient lists for three types of e-mail:
-(a) Error Reports, (b) Package Updates, (c) Help requests, generated by
-lonerrorhandler.pm, CHECKRPMS and lonsupportreq.pm respectively.
+Build recipient lists for five types of e-mail:
+(a) Error Reports, (b) Package Updates, (c) lonstatus warnings/errors
+(d) Help requests, (e) Course requests needing approval, generated by
+lonerrorhandler.pm, CHECKRPMS, loncron, lonsupportreq.pm and
+loncoursequeueadmin.pm respectively.
Inputs:
defmail (scalar - email address of default recipient),
@@ -8220,23 +8875,29 @@ sub build_recipient_list {
my %domconfig =
&Apache::lonnet::get_dom('configuration',['contacts'],$defdom);
if (ref($domconfig{'contacts'}) eq 'HASH') {
- if (ref($domconfig{'contacts'}{$mailing}) eq 'HASH') {
- my @contacts = ('adminemail','supportemail');
- foreach my $item (@contacts) {
- if ($domconfig{'contacts'}{$mailing}{$item}) {
- my $addr = $domconfig{'contacts'}{$item};
- if (!grep(/^\Q$addr\E$/,@recipients)) {
- push(@recipients,$addr);
+ if (exists($domconfig{'contacts'}{$mailing})) {
+ if (ref($domconfig{'contacts'}{$mailing}) eq 'HASH') {
+ my @contacts = ('adminemail','supportemail');
+ foreach my $item (@contacts) {
+ if ($domconfig{'contacts'}{$mailing}{$item}) {
+ my $addr = $domconfig{'contacts'}{$item};
+ if (!grep(/^\Q$addr\E$/,@recipients)) {
+ push(@recipients,$addr);
+ }
}
+ $otheremails = $domconfig{'contacts'}{$mailing}{'others'};
}
- $otheremails = $domconfig{'contacts'}{$mailing}{'others'};
}
+ } elsif ($origmail ne '') {
+ push(@recipients,$origmail);
}
} elsif ($origmail ne '') {
push(@recipients,$origmail);
}
- if ($defmail ne '') {
- push(@recipients,$defmail);
+ if (defined($defmail)) {
+ if ($defmail ne '') {
+ push(@recipients,$defmail);
+ }
}
if ($otheremails) {
my @others;
@@ -8360,6 +9021,8 @@ sub extract_categories {
my $trailstr;
if ($name eq 'instcode') {
$trailstr = &mt('Official courses (with institutional codes)');
+ } elsif ($name eq 'communities') {
+ $trailstr = &mt('Communities');
} else {
$trailstr = $name;
}
@@ -8470,14 +9133,16 @@ Inputs:
cathash - reference to hash of categories defined for the domain (from
configuration.db)
-currcat - scalar with an & separated list of categories assigned to a course.
+currcat - scalar with an & separated list of categories assigned to a course.
+
+type - scalar contains course type (Course or Community).
Returns: $output (markup to be displayed)
=cut
sub assign_categories_table {
- my ($cathash,$currcat) = @_;
+ my ($cathash,$currcat,$type) = @_;
my $output;
if (ref($cathash) eq 'HASH') {
my (@cats,@trails,%allitems,%idx,@jsarray,@path,$maxdepth);
@@ -8486,15 +9151,20 @@ sub assign_categories_table {
if (@cats > 0) {
my $itemcount = 0;
if (ref($cats[0]) eq 'ARRAY') {
- $output = &Apache::loncommon::start_data_table();
my @currcategories;
if ($currcat ne '') {
@currcategories = split('&',$currcat);
}
+ my $table;
for (my $i=0; $i<@{$cats[0]}; $i++) {
my $parent = $cats[0][$i];
- my $css_class = $itemcount%2?' class="LC_odd_row"':'';
next if ($parent eq 'instcode');
+ if ($type eq 'Community') {
+ next unless ($parent eq 'communities');
+ } else {
+ next if ($parent eq 'communities');
+ }
+ my $css_class = $itemcount%2?' class="LC_odd_row"':'';
my $item = &escape($parent).'::0';
my $checked = '';
if (@currcategories > 0) {
@@ -8502,17 +9172,26 @@ sub assign_categories_table {
$checked = ' checked="checked" ';
}
}
- $output .= ''
- .' '.&escape($parent).' ';
+ my $parent_title = $parent;
+ if ($parent eq 'communities') {
+ $parent_title = &mt('Communities');
+ }
+ $table .= ''.
+ ' '.$parent_title.' '.
+ ' ';
my $depth = 1;
push(@path,$parent);
- $output .= &assign_category_rows($itemcount,\@cats,$depth,$parent,\@path,\@currcategories);
+ $table .= &assign_category_rows($itemcount,\@cats,$depth,$parent,\@path,\@currcategories);
pop(@path);
- $output .= ' ';
+ $table .= ' ';
$itemcount ++;
}
- $output .= &Apache::loncommon::end_data_table();
+ if ($itemcount) {
+ $output = &Apache::loncommon::start_data_table().
+ $table.
+ &Apache::loncommon::end_data_table();
+ }
}
}
}
@@ -8570,7 +9249,9 @@ sub assign_category_rows {
}
$text .= ''.
' '.$name.' ';
+ $item.'"'.$checked.' />'.$name.''.
+ ' '.
+ ' ';
if (ref($path) eq 'ARRAY') {
push(@{$path},$name);
$text .= &assign_category_rows($itemcount,$cats,$deeper,$name,$path,$currcategories);
@@ -8755,40 +9436,64 @@ sub check_clone {
my $clonehome=&Apache::lonnet::homeserver($clonecrsunum,$clonecrsudom);
my $clonemsg;
my $can_clone = 0;
-
+ my $lctype = lc($args->{'crstype'});
+ if ($lctype ne 'community') {
+ $lctype = 'course';
+ }
if ($clonehome eq 'no_host') {
- $clonemsg = &mt('No new course created.').$linefeed.&mt('A new course could not be cloned from the specified original - [_1] - because it is a non-existent course.',$args->{'clonecourse'}.':'.$args->{'clonedomain'});
+ if ($args->{'crstype'} eq 'Community') {
+ $clonemsg = &mt('No new community created.').$linefeed.&mt('A new community could not be cloned from the specified original - [_1] - because it is a non-existent community.',$args->{'clonecourse'}.':'.$args->{'clonedomain'});
+ } else {
+ $clonemsg = &mt('No new course created.').$linefeed.&mt('A new course could not be cloned from the specified original - [_1] - because it is a non-existent course.',$args->{'clonecourse'}.':'.$args->{'clonedomain'});
+ }
} else {
my %clonedesc = &Apache::lonnet::coursedescription($cloneid,{'one_time' => 1});
- if ($env{'request.role.domain'} eq $args->{'clonedomain'}) {
- $can_clone = 1;
- } else {
- my %clonehash = &Apache::lonnet::get('environment',['cloners'],
- $args->{'clonedomain'},$args->{'clonecourse'});
- my @cloners = split(/,/,$clonehash{'cloners'});
+ if ($args->{'crstype'} eq 'Community') {
+ if ($clonedesc{'type'} ne 'Community') {
+ $clonemsg = &mt('No new community created.').$linefeed.&mt('A new community could not be cloned from the specified original - [_1] - because it is a course not a community.',$args->{'clonecourse'}.':'.$args->{'clonedomain'});
+ return ($can_clone, $clonemsg, $cloneid, $clonehome);
+ }
+ }
+ if (($env{'request.role.domain'} eq $args->{'clonedomain'}) &&
+ (&Apache::lonnet::allowed('ccc',$env{'request.role.domain'}))) {
+ $can_clone = 1;
+ } else {
+ my %clonehash = &Apache::lonnet::get('environment',['cloners'],
+ $args->{'clonedomain'},$args->{'clonecourse'});
+ my @cloners = split(/,/,$clonehash{'cloners'});
if (grep(/^\*$/,@cloners)) {
$can_clone = 1;
} elsif (grep(/^\*\:\Q$args->{'ccdomain'}\E$/,@cloners)) {
$can_clone = 1;
} else {
- my %roleshash =
- &Apache::lonnet::get_my_roles($args->{'ccuname'},
- $args->{'ccdomain'},
- 'userroles',['active'],['cc'],
- [$args->{'clonedomain'}]);
- if (($roleshash{$args->{'clonecourse'}.':'.$args->{'clonedomain'}.':cc'}) || (grep(/^\Q$args->{'ccuname'}\E:\Q$args->{'ccdomain'}\E$/,@cloners))) {
- $can_clone = 1;
- } else {
- $clonemsg = &mt('No new course created.').$linefeed.&mt('The new course could not be cloned from the existing course because the new course owner ([_1]) does not have cloning rights in the existing course ([_2]).',$args->{'ccuname'}.':'.$args->{'ccdomain'},$clonedesc{'description'});
- }
- }
+ my $ccrole = 'cc';
+ if ($args->{'crstype'} eq 'Community') {
+ $ccrole = 'co';
+ }
+ my %roleshash =
+ &Apache::lonnet::get_my_roles($args->{'ccuname'},
+ $args->{'ccdomain'},
+ 'userroles',['active'],[$ccrole],
+ [$args->{'clonedomain'}]);
+ if (($roleshash{$args->{'clonecourse'}.':'.$args->{'clonedomain'}.':'.$ccrole}) || (grep(/^\Q$args->{'ccuname'}\E:\Q$args->{'ccdomain'}\E$/,@cloners))) {
+ $can_clone = 1;
+ } elsif (&Apache::lonnet::is_course_owner($args->{'clonedomain'},$args->{'clonecourse'},$args->{'ccuname'},$args->{'ccdomain'})) {
+ $can_clone = 1;
+ } else {
+ if ($args->{'crstype'} eq 'Community') {
+ $clonemsg = &mt('No new community created.').$linefeed.&mt('The new community could not be cloned from the existing community because the new community owner ([_1]) does not have cloning rights in the existing community ([_2]).',$args->{'ccuname'}.':'.$args->{'ccdomain'},$clonedesc{'description'});
+ } else {
+ $clonemsg = &mt('No new course created.').$linefeed.&mt('The new course could not be cloned from the existing course because the new course owner ([_1]) does not have cloning rights in the existing course ([_2]).',$args->{'ccuname'}.':'.$args->{'ccdomain'},$clonedesc{'description'});
+ }
+ }
+ }
}
}
return ($can_clone, $clonemsg, $cloneid, $clonehome);
}
sub construct_course {
- my ($args,$logmsg,$courseid,$crsudom,$crsunum,$udom,$uname,$context) = @_;
+ my ($args,$logmsg,$courseid,$crsudom,$crsunum,$udom,$uname,$context,$cnum,$category) = @_;
my $outcome;
my $linefeed = ' '."\n";
if ($context eq 'auto') {
@@ -8826,7 +9531,9 @@ sub construct_course {
$args->{'crscode'},
$args->{'ccuname'}.':'.
$args->{'ccdomain'},
- $args->{'crstype'});
+ $args->{'crstype'},
+ $cnum,$context,$category);
+
# Note: The testing routines depend on this being output; see
# Utils::Course. This needs to at least be output as a comment
@@ -8869,7 +9576,9 @@ sub construct_course {
'policy.email',
'comment.email',
'pch.users.denied',
- 'plc.users.denied'],
+ 'plc.users.denied',
+ 'hidefromcat',
+ 'categories'],
$$crsudom,$$crsunum);
}
@@ -9097,10 +9806,10 @@ sub construct_course {
$outcome .= ($fatal?$errtext:'read ok').' - ';
my $title; my $url;
if ($args->{'firstres'} eq 'syl') {
- $title='Syllabus';
+ $title=&mt('Syllabus');
$url='/public/'.$$crsudom.'/'.$$crsunum.'/syllabus';
} else {
- $title='Navigate Contents';
+ $title=&mt('Navigate Contents');
$url='/adm/navmaps';
}
@@ -9132,12 +9841,22 @@ sub course_type {
sub group_term {
my $crstype = &course_type();
my %names = (
- 'Course' => 'group',
- 'Group' => 'team',
+ 'Course' => 'group',
+ 'Community' => 'group',
);
return $names{$crstype};
}
+sub course_types {
+ my @types = ('official','unofficial','community');
+ my %typename = (
+ official => 'Official course',
+ unofficial => 'Unofficial course',
+ community => 'Community',
+ );
+ return (\@types,\%typename);
+}
+
sub icon {
my ($file)=@_;
my $curfext = lc((split(/\./,$file))[-1]);
@@ -9154,28 +9873,14 @@ sub icon {
return &lonhttpdurl($iconname);
}
-sub lonhttpd_port {
- my $lonhttpd_port=$Apache::lonnet::perlvar{'lonhttpdPort'};
- if (!defined($lonhttpd_port)) { $lonhttpd_port='8080'; }
- # IE doesn't like a secure page getting images from a non-secure
- # port (when logging we haven't parsed the browser type so default
- # back to secure
- if ((!exists($env{'browser.type'}) || $env{'browser.type'} eq 'explorer')
- && $ENV{'SERVER_PORT'} == 443) {
- return 443;
- }
- return $lonhttpd_port;
-
-}
-
sub lonhttpdurl {
+#
+# Had been used for "small fry" static images on separate port 8080.
+# Modify here if lightweight http functionality desired again.
+# Currently eliminated due to increasing firewall issues.
+#
my ($url)=@_;
-
- my $lonhttpd_port = &lonhttpd_port();
- if ($lonhttpd_port == 443) {
- return 'https://'.$ENV{'SERVER_NAME'}.$url;
- }
- return 'http://'.$ENV{'SERVER_NAME'}.':'.$lonhttpd_port.$url;
+ return $url;
}
sub connection_aborted {
@@ -9211,6 +9916,22 @@ sub escape_url {
return join('/',@urlslices).'/'.$lastitem;
}
+sub compare_arrays {
+ my ($arrayref1,$arrayref2) = @_;
+ my (@difference,%count);
+ @difference = ();
+ %count = ();
+ if ((ref($arrayref1) eq 'ARRAY') && (ref($arrayref2) eq 'ARRAY')) {
+ foreach my $element (@{$arrayref1}, @{$arrayref2}) { $count{$element}++; }
+ foreach my $element (keys(%count)) {
+ if ($count{$element} == 1) {
+ push(@difference,$element);
+ }
+ }
+ }
+ return @difference;
+}
+
# -------------------------------------------------------- Initliaze user login
sub init_user_environment {
my ($r, $username, $domain, $authhost, $form, $args) = @_;
@@ -9253,7 +9974,7 @@ sub init_user_environment {
}
# Give them a new cookie
my $id = ($args->{'robot'} ? 'robot'.$args->{'robot'}
- : $now);
+ : $now.$$.int(rand(10000)));
$cookie="$username\_$id\_$domain\_$authhost";
# Initialize roles
@@ -9341,6 +10062,17 @@ sub init_user_environment {
}
}
+ foreach my $tool ('aboutme','blog','portfolio') {
+ $userenv{'availabletools.'.$tool} =
+ &Apache::lonnet::usertools_access($username,$domain,$tool,'reload');
+ }
+
+ foreach my $crstype ('official','unofficial','community') {
+ $userenv{'canrequest.'.$crstype} =
+ &Apache::lonnet::usertools_access($username,$domain,$crstype,
+ 'reload','requestcourses');
+ }
+
$env{'user.environment'} = "$lonids/$cookie.id";
if (tie(my %disk_env,'GDBM_File',"$lonids/$cookie.id",
@@ -9368,12 +10100,54 @@ sub init_user_environment {
sub _add_to_env {
my ($idf,$env_data,$prefix) = @_;
- while (my ($key,$value) = each(%$env_data)) {
- $idf->{$prefix.$key} = $value;
- $env{$prefix.$key} = $value;
+ if (ref($env_data) eq 'HASH') {
+ while (my ($key,$value) = each(%$env_data)) {
+ $idf->{$prefix.$key} = $value;
+ $env{$prefix.$key} = $value;
+ }
}
}
+# --- Get the symbolic name of a problem and the url
+sub get_symb {
+ my ($request,$silent) = @_;
+ (my $url=$env{'form.url'}) =~ s-^https?\://($ENV{'SERVER_NAME'}|$ENV{'HTTP_HOST'})--;
+ my $symb=($env{'form.symb'} ne '' ? $env{'form.symb'} : (&Apache::lonnet::symbread($url)));
+ if ($symb eq '') {
+ if (!$silent) {
+ $request->print("Unable to handle ambiguous references:$url:.");
+ return ();
+ }
+ }
+ &Apache::lonenc::check_decrypt(\$symb);
+ return ($symb);
+}
+
+# --------------------------------------------------------------Get annotation
+
+sub get_annotation {
+ my ($symb,$enc) = @_;
+
+ my $key = $symb;
+ if (!$enc) {
+ $key =
+ &Apache::lonnet::clutter((&Apache::lonnet::decode_symb($symb))[2]);
+ }
+ my %annotation=&Apache::lonnet::get('nohist_annotations',[$key]);
+ return $annotation{$key};
+}
+
+sub clean_symb {
+ my ($symb,$delete_enc) = @_;
+
+ &Apache::lonenc::check_decrypt(\$symb);
+ my $enc = $env{'request.enc'};
+ if ($delete_enc) {
+ delete($env{'request.enc'});
+ }
+
+ return ($symb,$enc);
+}
=pod