--- loncom/interface/loncommon.pm 2009/08/05 13:40:10 1.878 +++ loncom/interface/loncommon.pm 2010/10/04 22:30:42 1.925.2.15 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # a pile of common routines # -# $Id: loncommon.pm,v 1.878 2009/08/05 13:40:10 bisitz Exp $ +# $Id: loncommon.pm,v 1.925.2.15 2010/10/04 22:30:42 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -482,8 +482,11 @@ ENDAUTHORBRW } sub coursebrowser_javascript { - my ($domainfilter,$sec_element,$formname)=@_; - my $crs_or_grp_alert = &mt('Please select the type of LON-CAPA entity - Course or Community - for which you wish to add/modify a user role'); + my ($domainfilter,$sec_element,$formname,$role_element,$crstype) = @_; + my $wintitle = &mt('Course Browser'); + if ($crstype ne '') { + $wintitle = &mt($crstype); + } my $id_functions = &javascript_index_functions(); my $output = ' END_MYBLOCK + + $output = Apache::lonhtmlcommon::scripttag($output); + my $popupUrl = "/adm/blockingstatus/$querystring"; + my $text = mt('Communication Blocked'); + $output .= <<"END_BLOCK";
- Communication Blocked + title='$text'> + $text Communication Blocked + title='$text'>$text
END_BLOCK @@ -4032,7 +4127,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'}; @@ -4283,18 +4378,30 @@ sub CSTR_pageheader { } else { $lastitem = $thisdisfn; } - return + + my $output = '
' .&Apache::loncommon::help_open_menu('','',3,'Authoring') #FIXME: Broken? Where is it? .''.&mt('Construction Space:').' ' .'
' #FIXME lonpubdir: target="_parent" - .&Apache::lonhtmlcommon::crumbs($uname.'/'.$parentpath,'_top','/priv','','+1',1)."$lastitem
" + .'" target="_top">' #FIXME lonpubdir: target="_parent" + .&Apache::lonhtmlcommon::crumbs($uname.'/'.$parentpath,'_top','/priv',undef,undef); + + if ($lastitem) { + $output .= + '' + .$lastitem + .''; + } + $output .= + '
' #FIXME lonpubdir: &Apache::lonhtmlcommon::crumbs($uname.$thisdisfn.'/','_top','/priv','','+1',1)."
" .&Apache::lonhtmlcommon::select_recent('construct','recent','this.form.action=this.form.recent.value;this.form.submit()') .'
' .&Apache::lonmenu::constspaceform() .'
'; + + return $output; } ############################################### @@ -4371,6 +4478,10 @@ sub bodytag { 'link' => &designparm($function.'.link',$domain),); @design{keys(%$addentries)} = @$addentries{keys(%$addentries)}; + my $custommenu; + if ($env{'environment.remote'} eq 'off') { + $custommenu = &needs_gci_custom(); + } # role and realm my ($role,$realm) = split(/\./,$env{'request.role'},2); if ($role eq 'ca') { @@ -4380,11 +4491,22 @@ sub bodytag { # realm if ($env{'request.course.id'}) { if ($env{'request.role'} !~ /^cr/) { - $role = &Apache::lonnet::plaintext($role,&course_type()); + if (($custommenu) && ($role eq 'cm')) { + undef($role); + } else { + $role = &Apache::lonnet::plaintext($role,&course_type()); + } } + if ($env{'request.course.sec'}) { + $role .= (' 'x2).'- '.&mt('section:').' '.$env{'request.course.sec'}; + } $realm = $env{'course.'.$env{'request.course.id'}.'.description'}; } else { - $role = &Apache::lonnet::plaintext($role); + if (($custommenu) && ($role eq 'cm')) { + undef($role); + } else { + $role = &Apache::lonnet::plaintext($role); + } } if (!$realm) { $realm=' '; } @@ -4416,40 +4538,147 @@ sub bodytag { $env{'course.'.$env{'request.course.id'}. '.domain'}.'/'})) { my $cid = $env{'request.course.id'}; - $dc_info.= $cid.' '.$env{'course.'.$cid.'.internal.coursecode'}; + $dc_info = $cid.' '.$env{'course.'.$cid.'.internal.coursecode'}; $dc_info =~ s/\s+$//; - $dc_info = '('.$dc_info.')'; } - $role = "($role)" if $role; + $role = '('.$role.')' if $role; &get_unprocessed_cgi($ENV{'QUERY_STRING'}, ['inhibitmenu']); if ($env{'environment.remote'} eq 'off') { # No Remote - if ($env{'request.state'} eq 'construct') { - $forcereg=1; - } + if ($no_nav_bar || $env{'form.inhibitmenu'} eq 'yes') { + return $bodytag; + } -# if ($env{'request.state'} eq 'construct') { -# $titleinfo = &CSTR_pageheader(); #FIXME: Will be removed once all scripts have their own calls -# } + if ($env{'request.state'} eq 'construct') { $forcereg=1; } - my $titletable = '' - ."" - .'
$titleinfo $dc_info
'; + # if ($env{'request.state'} eq 'construct') { + # $titleinfo = &CSTR_pageheader(); #FIXME: Will be removed once all scripts have their own calls + # } + + my $role_selector; + if (($custommenu) && ($env{'request.course.id'}) && + ($env{'course.'.$env{'request.course.id'}.'.domain'} eq 'gcitest')) { + $role_selector = &Apache::lonmenu::roles_selector( + $env{'course.' . $env{'request.course.id'} . '.domain'}, + $env{'course.' . $env{'request.course.id'} . '.num'} ); + if ($role_selector) { + $role_selector = '
'.$role_selector; + } + } + my $cid = $env{'request.course.id'}; + my %gcicourses = ( + gci_9615072b469884921gcil1 => 'review', + gci_1H96711d710194bfegcil1 => 'submit', + gci_5422913620b814c90gcil1 => 'tutorial', + ); + if (($custommenu && $cid && !$gcicourses{$cid}) || ($env{'user.domain'} eq 'gcitest')) { + my $role = 'st'; + if ($custommenu) { + $role = 'cc'; + } + my ($switcher_js,$switcher,$formname); + $formname = 'pickrole'; + my %courses = &existing_gcitest_courses($role); + my $numcourses = keys(%courses); + my $reqdcount = 0; + if ($cid) { + if ($courses{$cid}) { + $reqdcount = 1; + } + } + if ($numcourses > $reqdcount) { + $switcher = &gcitest_switcher($role,$formname,%courses); + my $current; + if ($cid) { + $current = $role.'./'.$env{'course.'.$cid.'.domain'}. + '/'.$env{'course.'.$cid.'.num'}; + } + $switcher_js = &Apache::loncommon::gcitest_switcher_js($current,$numcourses,$formname); + if ($switcher_js) { + $switcher_js= <<"ENDSCRIPT"; + +ENDSCRIPT + } + } + if ($switcher) { + $switcher = $switcher_js.$switcher; + if ($role_selector) { + $role_selector .= '   '.$switcher; + } else { + $role_selector .= '
'.$switcher; + } } } + + if ($env{'request.noversionuri'} =~ m{^/res/adm/pages/}) { + if ($dc_info) { + $dc_info = qq|$dc_info|; + } + $bodytag .= qq|
$name $role
+ $realm $dc_info
|; + return $bodytag; + } + + if ($cid && $gcicourses{$cid} eq 'tutorial') { + $bodytag .= '
'; + } + $bodytag .= qq|
$name $role $role_selector
|; + + $bodytag .= Apache::lonhtmlcommon::scripttag( + Apache::lonmenu::utilityfunctions('',$custommenu), 'start'); + + $bodytag .= Apache::lonmenu::primary_menu(); + + if ($dc_info) { + $dc_info = &dc_courseid_toggle($dc_info); + } + $bodytag .= qq|
$realm $dc_info
|; + if ($cid && $gcicourses{$cid} eq 'tutorial') { + $bodytag .= '
'; + } + + #don't show menus for public users + if($env{'user.name'} ne 'public' && $env{'user.domain'} ne 'public'){ + if (($custommenu) && + ($env{'request.role'} !~ m{^st\./gcitest/$match_courseid})) { + $bodytag .= &Apache::lonmenu::gci_secondary_menu(); + } else { + $bodytag .= Apache::lonmenu::secondary_menu(); + } + $bodytag .= Apache::lonmenu::serverform(); + $bodytag .= Apache::lonhtmlcommon::scripttag('', 'end'); + if ($env{'request.state'} eq 'construct') { + $bodytag .= &Apache::lonmenu::innerregister($forcereg,'', + $args->{'bread_crumbs'}); + } elsif ($forcereg) { + $bodytag .= &Apache::lonmenu::innerregister($forcereg); + } elsif ($custommenu && $env{'request.course.id'} && + &Apache::lonnet::allowed('mdc', $env{'request.course.id'})) { + if ($env{'request.noversionuri'} eq '/adm/navmaps') { + my @advtools = &concept_test_manager(); + &Apache::lonhtmlcommon::add_breadcrumb_tool( + 'advtools',@advtools); + my $advlinks; + my $legendtext = ''.&mt('Management').''; + &Apache::lonhtmlcommon::render_advtools(\$advlinks,$legendtext); + $bodytag .= $advlinks; + } + } + }else{ + # this is to seperate menu from content when there's no secondary + # menu. Especially needed for public accessible ressources. + $bodytag .= '
'; + $bodytag .= Apache::lonhtmlcommon::scripttag('', 'end'); + } + return $bodytag; } @@ -4465,13 +4694,16 @@ sub bodytag { # Explicit link to get inline menu my $menu= ($no_inline_link?'' - :''.&mt('Switch to Inline Menu Mode').''); - $bodytag .= qq|
$name $role - $realm $dc_info
-
    + :''.&mt('Switch to Inline Menu Mode').''); + + if ($dc_info) { + $dc_info = qq|($dc_info)|; + } + + $bodytag .= qq|
    $name $role
    +
    1. $menu
    2. -
    | unless $env{'form.inhibitmenu'}; - # +
$realm $dc_info
| unless $env{'form.inhibitmenu'}; return(< @@ -4484,6 +4716,60 @@ $bodytag ENDBODY } +sub concept_test_manager { + my @advtools; + my %items = ( + docs => { + desc => 'Edit Test', + action => "go('/adm/coursedocs')", + tooltip => 'Assemble or modify Concept Test' + }, + cprv => { + desc => 'Enrollment/Activity', + action => "go('/adm/createuser')", + tooltip => 'Enrollment and student activity', + }, + new => { + desc => "What's New?", + action => "go('/adm/whatsnew')", + tooltip => 'Recent events/action items in Concept Test' , + }, + prnt => { + desc => 'Print Test', + action => "go('/adm/printout');", + tooltip => 'Prepare printable Concept Test', + }, + chrt => { + desc => 'Test Statistics', + action => "go('/adm/statistics');", + tooltip => 'Concept Test Statistics', + }, + rcrs => { + desc => 'Create New Test', + action => "switchpage('createtest');", + tooltip => 'Create new Concept Test', + }, + ); + my @ordered = ('docs','cprv','new','prnt','chrt','rcrs'); + foreach my $item (@ordered) { + push(@advtools, + ''. + ''.$items{$item}{tooltip}.
+                  ''. + ''.$items{$item}{desc}.''); + } + return @advtools; +} + +sub dc_courseid_toggle { + my ($dc_info) = @_; + return ' '. + ''. + &mt('(More ...)').''. + '
'.$dc_info.'
'; +} + sub make_attr_string { my ($register,$attr_ref) = @_; @@ -4615,57 +4901,48 @@ sub standard_css { my $mail_other_hover = '#669999'; my $table_header = '#DDDDDD'; my $feedback_link_bg = '#BBBBBB'; - my $lg_border_color = '#C8C8C8'; + my $lg_border_color = '#C8C8C8'; my $border = ($env{'browser.type'} eq 'explorer' || - $env{'browser.type'} eq 'safari' ) ? '0 2px 0 2px' - : '0 3px 0 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_data_table tr.LC_odd_row > td { + background-color: $data_table_light; + padding: 2px; + vertical-align: top; +} + table.LC_pick_box tr > td.LC_odd_row { background-color: $data_table_light; + vertical-align: top; +} + +table.LC_data_table tr.LC_even_row > td { + background-color: $data_table_dark; padding: 2px; + vertical-align: top; } -table.LC_data_table tr.LC_even_row > td, table.LC_pick_box tr > td.LC_even_row { background-color: $data_table_dark; - padding: 2px; + vertical-align: top; } table.LC_data_table tr.LC_data_table_highlight td { @@ -4984,6 +5298,9 @@ table.LC_nested tr.LC_empty_row td { padding: 8px; } +table.LC_caption { +} + table.LC_nested tr.LC_empty_row td { padding: 4ex } @@ -5048,6 +5365,7 @@ table.LC_createuser tr.LC_info_row td { table.LC_calendar { border: 1px solid #000000; border-collapse: collapse; + width: 98%; } table.LC_calendar_pickdate { @@ -5057,6 +5375,7 @@ table.LC_calendar_pickdate { table.LC_calendar tr td { border: 1px solid #000000; vertical-align: top; + width: 14%; } table.LC_calendar tr td.LC_calendar_day_empty { @@ -5075,12 +5394,6 @@ table.LC_mail_list tr.LC_mail_new:hover background-color: $mail_new_hover; } -table.LC_mail_list tr.LC_mail_even { -} - -table.LC_mail_list tr.LC_mail_odd { -} - table.LC_mail_list tr.LC_mail_read { background-color: $mail_read; } @@ -5107,7 +5420,7 @@ table.LC_mail_list tr.LC_mail_other:hove table.LC_data_table tr > td.LC_browser_file, table.LC_data_table tr > td.LC_browser_file_published { - background: #CCFF88; + background: #AAEE77; } table.LC_data_table tr > td.LC_browser_file_locked, @@ -5116,20 +5429,20 @@ table.LC_data_table tr > td.LC_browser_f } table.LC_data_table tr > td.LC_browser_file_obsolete { - background: #AAAAAA; + background: #888888; } table.LC_data_table tr > td.LC_browser_file_modified, table.LC_data_table tr > td.LC_browser_file_metamodified { - background: #FFFF77; + background: #F8F866; } table.LC_data_table tr.LC_browser_folder > td { - background: #CCCCFF; + background: #E0E8FF; } table.LC_data_table tr > td.LC_roles_is { -/* background: #77FF77; */ + /* background: #77FF77; */ } table.LC_data_table tr > td.LC_roles_future { @@ -5177,7 +5490,8 @@ span.LC_parm_part { color: blue; } -span.LC_parm_folder, span.LC_parm_symb { +span.LC_parm_folder, +span.LC_parm_symb { font-size: x-small; font-family: $mono; color: #AAAAAA; @@ -5267,7 +5581,7 @@ table.LC_pick_box { table.LC_pick_box td.LC_pick_box_title { background: $sidebg; font-weight: bold; - text-align: right; + text-align: left; vertical-align: top; width: 184px; padding: 8px; @@ -5305,40 +5619,6 @@ table.LC_pick_box td.LC_oddrow_value { background-color: $data_table_light; } -table.LC_helpform_receipt { - width: 620px; - border-collapse: separate; - background: white; - border: 1px solid black; - border-spacing: 1px; -} - -table.LC_helpform_receipt td.LC_pick_box_title { - background: $tabbg; - font-weight: bold; - text-align: right; - width: 184px; - padding: 8px; -} - -table.LC_helpform_receipt td.LC_evenrow_value { - text-align: left; - padding: 8px; - background-color: $data_table_light; -} - -table.LC_helpform_receipt td.LC_oddrow_value { - text-align: left; - padding: 8px; - background-color: $data_table_light; -} - -table.LC_helpform_receipt td.LC_pick_box_separator { - padding: 0; - height: 1px; - background: black; -} - span.LC_helpform_receipt_cat { font-weight: bold; } @@ -5393,15 +5673,17 @@ table.LC_notify_front_page td { .LC_topic_bar { font-weight: bold; - width: 100%; background: $tabbg; - vertical-align: middle; - margin: 2ex 0ex 2ex 0ex; + margin: 1em 0em 1em 2em; padding: 3px; + font-size: 1.2em; } .LC_topic_bar span { + left: 0.5em; + position: absolute; vertical-align: middle; + font-size: 1.2em; } .LC_topic_bar img { @@ -5434,12 +5716,12 @@ div.LC_feedback_link img { vertical-align:middle; } -div.LC_feedback_link a{ +div.LC_feedback_link a { text-decoration: none; } div.LC_comblock { - display:inline; + display:inline; color:$font; font-size:90%; } @@ -5517,12 +5799,12 @@ span.LC_prior_string, span.LC_prior_custom, span.LC_prior_reaction, span.LC_prior_math { - font-family: monospace; + font-family: $mono; white-space: pre; } span.LC_prior_string { - font-family: monospace; + font-family: $mono; white-space: pre; } @@ -5531,7 +5813,7 @@ table.LC_prior_option { border-collapse: collapse; } -table.LC_prior_rank, +table.LC_prior_rank, table.LC_prior_match { border-collapse: collapse; } @@ -5555,17 +5837,6 @@ span.LC_cusr_subheading { font-size: 85%; } -table.LC_docs_documents { - background: #BBBBBB; - border-width: 0; - border-collapse: collapse; -} - -table.LC_docs_documents td.LC_docs_document { - border: 2px solid black; - padding: 4px; -} - div.LC_docs_entry_move { border: 1px solid #BBBBBB; background: #DDDDDD; @@ -5761,30 +6032,24 @@ div.LC_edit_problem_saves { padding-bottom: 5px; } -img.stift{ +img.stift { border-width: 0; vertical-align: middle; } -table#LC_mainmenu{ - margin-top:10px; - width:80%; -} - -table#LC_mainmenu td.LC_mainmenu_col_fieldset{ +table td.LC_mainmenu_col_fieldset { vertical-align: top; - width: 45%; } -.LC_mainmenu_fieldset_category { - color: $font; - background: $pgbg; - font-size: small; - font-weight: bold; +div.LC_createcourse { + margin: 10px 10px 10px 10px; } -div.LC_createcourse { - margin: 10px 10px 10px 10px; +.LC_dccid { + margin: 0.2em 0 0 0; + padding: 0; + font-size: 90%; + display:none; } /* ---- Remove when done ---- @@ -5795,226 +6060,246 @@ div.LC_createcourse { # --------------------------*/ a:hover, -ol.LC_smallMenu a:hover, +ol.LC_primary_menu a:hover, ol#LC_MenuBreadcrumbs a:hover, ol#LC_PathBreadcrumbs a:hover, -ul#LC_TabMainMenuContent a:hover, +ul#LC_secondary_menu a:hover, .LC_FormSectionClearButton input:hover ul.LC_TabContent li:hover a { - color:#BF2317; - text-decoration:none; + color:#BF2317; + text-decoration:none; } h1 { - padding: 0; - line-height:130%; + padding: 0; + line-height:130%; } -h2,h3,h4,h5,h6 { - margin: 5px 0 5px 0; - padding: 0; - line-height:130%; +h2, +h3, +h4, +h5, +h6 { + margin: 5px 0 5px 0; + padding: 0; + line-height:130%; } .LC_hcell { - padding:3px 15px 3px 15px; - margin: 0; - background-color:$tabbg; - color:$fontmenu; - border-bottom:solid 1px $lg_border_color; + padding:3px 15px 3px 15px; + margin: 0; + background-color:$tabbg; + color:$fontmenu; + border-bottom:solid 1px $lg_border_color; } .LC_Box > .LC_hcell { - margin: 0 -10px 10px -10px; + margin: 0 -10px 10px -10px; } .LC_noBorder { - border: 0; -} - -.LC_Right { - float: right; - margin: 0; - padding: 0; + border: 0; } .LC_FormSectionClearButton input { - background-color:transparent; - border: none; - cursor:pointer; - text-decoration:underline; + background-color:transparent; + border: none; + cursor:pointer; + text-decoration:underline; } .LC_help_open_topic { - color: #FFFFFF; - background-color: #EEEEFF; - margin: 1px; - padding: 4px; - border: 1px solid #000033; - white-space: nowrap; -/* vertical-align: middle; */ + color: #FFFFFF; + background-color: #EEEEFF; + margin: 1px; + padding: 4px; + border: 1px solid #000033; + white-space: nowrap; + /* vertical-align: middle; */ } -dl,ul,div,fieldset { - margin: 10px 10px 10px 0; -/* overflow: hidden; */ +dl, +ul, +div, +fieldset { + margin: 10px 10px 10px 0; + /* overflow: hidden; */ } fieldset > legend { - font-weight: bold; - padding: 0 5px 0 5px; + font-weight: bold; + padding: 0 5px 0 5px; +} + +div.LC_page_header { + background-color: $pgbg_or_bgcolor; + margin: 0 0 1.0em 0; } #LC_nav_bar { - float: left; - margin: 0.2em 0 0 0; + float: left; + margin: 0.2em 0 0 0; } -#LC_nav_bar em{ - font-weight: bold; - font-style: normal; +#LC_realm { + margin: 0.2em 0 0 0; + padding: 0; + font-weight: bold; + text-align: center; } -ol.LC_smallMenu { - float: right; - margin: 0.2em 0 0 0; +#LC_nav_bar em { + font-weight: bold; + font-style: normal; +} + +ol.LC_primary_menu { + float: right; + margin: 0.2em 0 0 0; +} + +span.LC_new_message{ + font-weight:bold; + color: darkred; } ol#LC_PathBreadcrumbs { - margin: 0; + margin: 0; } -ol.LC_smallMenu li { - display: inline; - padding: 5px 5px 0 10px; - vertical-align: top; +ol.LC_primary_menu li { + display: inline; + padding: 5px 5px 0 10px; + vertical-align: top; } -ol.LC_smallMenu li img { - vertical-align: bottom; +ol.LC_primary_menu li img { + vertical-align: bottom; } -ol.LC_smallMenu a { - font-size: 90%; - color: RGB(80, 80, 80); - text-decoration: none; +ol.LC_primary_menu a { + font-size: 90%; + color: RGB(80, 80, 80); + text-decoration: none; } -ul#LC_TabMainMenuContent { - clear: both; - color: $fontmenu; - background: $tabbg; - list-style: none; - padding: 0; - margin: 0; - width: 100%; +ul#LC_secondary_menu { + clear: both; + color: $fontmenu; + background: $tabbg; + list-style: none; + padding: 0; + margin: 0; + width: 100%; } -ul#LC_TabMainMenuContent li { - font-weight: bold; - line-height: 1.8em; - padding: 0 0.8em; - border-right: 1px solid black; - display: inline; - vertical-align: middle; +ul#LC_secondary_menu li { + font-weight: bold; + line-height: 1.8em; + padding: 0 0.8em; + border-right: 1px solid black; + display: inline; + vertical-align: middle; } ul.LC_TabContent { - display:block; - background: $sidebg; - border-bottom: solid 1px $lg_border_color; - list-style:none; - margin: 0 -10px; - padding: 0; + display:block; + background: $sidebg; + border-bottom: solid 1px $lg_border_color; + list-style:none; + margin: 0 -10px; + padding: 0; } ul.LC_TabContent li, ul.LC_TabContentBigger li { - float:left; + float:left; } -ul#LC_TabMainMenuContent li a { - color: $fontmenu; - text-decoration: none; +ul#LC_secondary_menu li a { + color: $fontmenu; + text-decoration: none; } ul.LC_TabContent { - min-height:1.5em; + min-height:1.5em; } ul.LC_TabContent li { - vertical-align:middle; - padding: 0 10px 0 10px; - background-color:$tabbg; - border-bottom:solid 1px $lg_border_color; + vertical-align:middle; + padding: 0 10px 0 10px; + background-color:$tabbg; + border-bottom:solid 1px $lg_border_color; } ul.LC_TabContent .right { - float:right; + float:right; } -ul.LC_TabContent li a, ul.LC_TabContent li { - color:rgb(47,47,47); - text-decoration:none; - font-size:95%; - font-weight:bold; - padding-right: 16px; +ul.LC_TabContent li a, +ul.LC_TabContent li { + color:rgb(47,47,47); + text-decoration:none; + font-size:95%; + font-weight:bold; + padding-right: 16px; } -ul.LC_TabContent li:hover, ul.LC_TabContent li.active { - background:#FFFFFF url(/adm/lonIcons/open.gif) no-repeat scroll right center; - border-bottom:solid 2px #FFFFFF; - padding-right: 16px; +ul.LC_TabContent li:hover, +ul.LC_TabContent li.active { + background:#FFFFFF url(/adm/lonIcons/open.gif) no-repeat scroll right center; + border-bottom:solid 2px #FFFFFF; + padding-right: 16px; } #maincoursedoc { - clear:both; + clear:both; } ul.LC_TabContentBigger { - display:block; - list-style:none; - padding: 0; + display:block; + list-style:none; + padding: 0; } ul.LC_TabContentBigger li { - vertical-align:bottom; - height: 30px; - font-size:110%; - font-weight:bold; - color: #737373; + vertical-align:bottom; + height: 30px; + font-size:110%; + font-weight:bold; + color: #737373; } ul.LC_TabContentBigger li a { - background:url('/adm/lonIcons/tabbgleft.gif') left bottom no-repeat; - height: 30px; - line-height: 30px; - text-align: center; - display: block; - text-decoration: none; + background:url('/adm/lonIcons/tabbgleft.gif') left bottom no-repeat; + height: 30px; + line-height: 30px; + text-align: center; + display: block; + text-decoration: none; } -ul.LC_TabContentBigger li:hover a, +ul.LC_TabContentBigger li:hover a, ul.LC_TabContentBigger li.active a { - background:url('/adm/lonIcons/tabbgleft.gif') left top no-repeat; - color:$font; - text-decoration: underline; + background:url('/adm/lonIcons/tabbgleft.gif') left top no-repeat; + color:$font; + text-decoration: underline; } ul.LC_TabContentBigger li b { - background: url('/adm/lonIcons/tabbgright.gif') no-repeat right bottom; - display: block; - float: left; - padding: 0 30px; + background: url('/adm/lonIcons/tabbgright.gif') no-repeat right bottom; + display: block; + float: left; + padding: 0 30px; } ul.LC_TabContentBigger li:hover b, ul.LC_TabContentBigger li.active b { - background:url('/adm/lonIcons/tabbgright.gif') right top no-repeat; - color:$font; - border-bottom: 1px solid #FFFFFF; + background:url('/adm/lonIcons/tabbgright.gif') right top no-repeat; + color:$font; + border-bottom: 1px solid #FFFFFF; } @@ -6027,65 +6312,73 @@ ul.LC_CourseBreadcrumbs { } -ol#LC_MenuBreadcrumbs, +ol#LC_MenuBreadcrumbs, ol#LC_PathBreadcrumbs { - padding-left: 10px; - margin: 0; - list-style-position: inside; + padding-left: 10px; + margin: 0; + margin: 0; + height: 2.5em; /* equal to #LC_breadcrumbs line-height */ } -ol#LC_MenuBreadcrumbs li, -ol#LC_PathBreadcrumbs li, +ol#LC_MenuBreadcrumbs li, +ol#LC_PathBreadcrumbs li, ul.LC_CourseBreadcrumbs li { - display: inline; - white-space: nowrap; + display: inline; + white-space: normal; } ol#LC_MenuBreadcrumbs li a, ul.LC_CourseBreadcrumbs li a { - text-decoration: none; - font-size:90%; + text-decoration: none; + font-size:90%; +} + +ol#LC_MenuBreadcrumbs h1 { + display: inline; + font-size: 90%; + line-height: 2.5em; + margin: 0; + padding: 0; } ol#LC_PathBreadcrumbs li a { - text-decoration:none; - font-size:100%; - font-weight:bold; + text-decoration:none; + font-size:100%; + font-weight:bold; } .LC_Box { - border: solid 1px $lg_border_color; - padding: 0 10px 10px 10px; + border: solid 1px $lg_border_color; + padding: 0 10px 10px 10px; } .LC_AboutMe_Image { - float:left; - margin-right:10px; + float:left; + margin-right:10px; } .LC_Clear_AboutMe_Image { - clear:left; + clear:left; } dl.LC_ListStyleClean dt { - padding-right: 5px; - display: table-header-group; + padding-right: 5px; + display: table-header-group; } dl.LC_ListStyleClean dd { - display: table-row; + display: table-row; } .LC_ListStyleClean, .LC_ListStyleSimple, .LC_ListStyleNormal, -.LC_ListStyle_Border, .LC_ListStyleSpecial { - /*display:block; */ - list-style-position: inside; - list-style-type: none; - overflow: hidden; - padding: 0; + /* display:block; */ + list-style-position: inside; + list-style-type: none; + overflow: hidden; + padding: 0; } .LC_ListStyleSimple li, @@ -6094,211 +6387,260 @@ dl.LC_ListStyleClean dd { .LC_ListStyleNormal dd, .LC_ListStyleSpecial li, .LC_ListStyleSpecial dd { - margin: 0; - padding: 5px 5px 5px 10px; - clear: both; + margin: 0; + padding: 5px 5px 5px 10px; + clear: both; } .LC_ListStyleClean li, .LC_ListStyleClean dd { - padding-top: 0; - padding-bottom: 0; + padding-top: 0; + padding-bottom: 0; } .LC_ListStyleSimple dd, .LC_ListStyleSimple li { - border-bottom: solid 1px $lg_border_color; + border-bottom: solid 1px $lg_border_color; } .LC_ListStyleSpecial li, .LC_ListStyleSpecial dd { - list-style-type: none; - background-color: RGB(220, 220, 220); - margin-bottom: 4px; + list-style-type: none; + background-color: RGB(220, 220, 220); + margin-bottom: 4px; } table.LC_SimpleTable { - margin:5px; - border:solid 1px $lg_border_color; + margin:5px; + border:solid 1px $lg_border_color; } table.LC_SimpleTable tr { - padding: 0; - border:solid 1px $lg_border_color; + padding: 0; + border:solid 1px $lg_border_color; } table.LC_SimpleTable thead { - background:rgb(220,220,220); + background:rgb(220,220,220); } div.LC_columnSection { - display: block; - clear: both; - overflow: hidden; - margin: 0; + display: block; + clear: both; + overflow: hidden; + margin: 0; } div.LC_columnSection>* { - float: left; - margin: 10px 20px 10px 0; - overflow:hidden; + float: left; + margin: 10px 20px 10px 0; + overflow:hidden; } .LC_loginpage_container { - text-align:left; - margin : 0 auto; - width:90%; - padding: 10px; - height: auto; - background-color:#FFFFFF; - border:1px solid #CCCCCC; + text-align:left; + margin : 0 auto; + width:90%; + padding: 10px; + height: auto; + background-color:#FFFFFF; + border:1px solid #CCCCCC; } .LC_loginpage_loginContainer { - float:left; - width: 182px; - padding: 2px; - border:1px solid #CCCCCC; - background-color:$loginbg; + float:left; + width: 182px; + padding: 2px; + border:1px solid #CCCCCC; + background-color:$loginbg; } .LC_loginpage_loginContainer h2 { - margin-top: 0; - display:block; - background:$bgcol; - color:$textcol; - padding-left:5px; + margin-top: 0; + display:block; + background:$bgcol; + color:$textcol; + padding-left:5px; } .LC_loginpage_loginInfo { - float:left; - width:182px; - border:1px solid #CCCCCC; - padding:2px; + float:left; + width:182px; + border:1px solid #CCCCCC; + padding:2px; } .LC_loginpage_space { - clear: both; - margin-bottom: 20px; - border-bottom: 1px solid #CCCCCC; + clear: both; + margin-bottom: 20px; + border-bottom: 1px solid #CCCCCC; } .LC_loginpage_floatLeft { - float: left; - width: 200px; - margin: 0; + float: left; + width: 200px; + margin: 0; } table em { - font-weight: bold; - font-style: normal; + font-weight: bold; + font-style: normal; } table.LC_tableBrowseRes, table.LC_tableOfContent { - border:none; - border-spacing: 1px; - padding: 3px; - background-color: #FFFFFF; - font-size: 90%; + border:none; + border-spacing: 1px; + padding: 3px; + background-color: #FFFFFF; + font-size: 90%; } -table.LC_tableOfContent{ - border-collapse: collapse; +table.LC_tableOfContent { + border-collapse: collapse; } table.LC_tableBrowseRes a, table.LC_tableOfContent a { - background-color: transparent; - text-decoration: none; -} - -table.LC_tableBrowseRes tr.LC_trOdd, -table.LC_tableOfContent tr.LC_trOdd{ - background-color: #EEEEEE; + background-color: transparent; + text-decoration: none; } table.LC_tableOfContent img { - border: none; - height: 1.3em; - vertical-align: text-bottom; - margin-right: 0.3em; + border: none; + height: 1.3em; + vertical-align: text-bottom; + margin-right: 0.3em; } a#LC_content_toolbar_firsthomework { - background-image:url(/res/adm/pages/open-first-problem.gif); + background-image:url(/res/adm/pages/open-first-problem.gif); } a#LC_content_toolbar_launchnav { - background-image:url(/res/adm/pages/start-navigation.gif); + background-image:url(/res/adm/pages/start-navigation.gif); } a#LC_content_toolbar_closenav { - background-image:url(/res/adm/pages/close-navigation.gif); + background-image:url(/res/adm/pages/close-navigation.gif); } a#LC_content_toolbar_everything { - background-image:url(/res/adm/pages/show-all.gif); + background-image:url(/res/adm/pages/show-all.gif); } a#LC_content_toolbar_uncompleted { - background-image:url(/res/adm/pages/show-incomplete-problems.gif); + background-image:url(/res/adm/pages/show-incomplete-problems.gif); } #LC_content_toolbar_clearbubbles { - background-image:url(/res/adm/pages/mark-discussionentries-read.gif); + background-image:url(/res/adm/pages/mark-discussionentries-read.gif); } a#LC_content_toolbar_changefolder { - background : url(/res/adm/pages/close-all-folders.gif) top center ; + background : url(/res/adm/pages/close-all-folders.gif) top center ; } a#LC_content_toolbar_changefolder_toggled { - background-image:url(/res/adm/pages/open-all-folders.gif); + background-image:url(/res/adm/pages/open-all-folders.gif); } ul#LC_toolbar li a:hover { - background-position: bottom center; + background-position: bottom center; } ul#LC_toolbar { - padding: 0; - margin: 2px; - list-style:none; - position:relative; - background-color:white; + padding: 0; + margin: 2px; + list-style:none; + position:relative; + background-color:white; } ul#LC_toolbar li { - border:1px solid white; - padding: 0; - margin: 0; - float: left; - display:inline; - vertical-align:middle; -} + border:1px solid white; + padding: 0; + margin: 0; + float: left; + display:inline; + vertical-align:middle; +} a.LC_toolbarItem { - display:block; - padding: 0; - margin: 0; - height: 32px; - width: 32px; - color:white; - border: none; - background-repeat:no-repeat; - background-color:transparent; + display:block; + padding: 0; + margin: 0; + height: 32px; + width: 32px; + color:white; + border: none; + background-repeat:no-repeat; + background-color:transparent; +} + +ul.LC_funclist { + margin: 0; + padding: 0.5em 1em 0.5em 0; +} + +ul.LC_funclist > li:first-child { + font-weight:bold; + margin-left:0.8em; +} + +ul.LC_funclist + ul.LC_funclist { + /* + left border as a seperator if we have more than + one list + */ + border-left: 1px solid $sidebg; + /* + this hides the left border behind the border of the + outer box if element is wrapped to the next 'line' + */ + margin-left: -1px; } ul.LC_funclist li { - float: left; + display: inline; white-space: nowrap; - height: 35px; /* at least as high as heighest list item */ - margin: 0 15px 15px 10px; + margin: 0 0 0 25px; + line-height: 150%; } +#gciheader { + float:left; + width:100%; + background:#DAE0D2 url("/gcimenu_bg.gif") repeat-x bottom; + font-size:93%; + line-height:normal; + margin: 0.5em 0 0.5em 0; +} +#gciheader ul { + margin:0; + padding:10px 5px 0; + list-style:none; +} +#gciheader li { + float:left; + background:url("/gcimenu_left.gif") no-repeat left top; + margin:0; + padding:0 0 0 9px; +} +#gciheader a { + display:block; + background:url("/gcimenu_right.gif") no-repeat right top; + padding:5px 15px 4px 6px; +} +#gciheader #current { + background-image:url("/gcimenu_left_on.gif"); +} +#gciheader #current a { + background-image:url("/gcimenu_right_on.gif"); + padding-bottom:5px; +} END } @@ -6575,6 +6917,11 @@ sub start_page { # Don't add anything more if only_body wanted return $result if $args->{'only_body'}; + #Breadcrumbs for Construction Space provided by &bodytag. + if (($env{'environment.remote'} eq 'off') && ($env{'request.state'} eq 'construct')) { + return $result; + } + #Breadcrumbs if (exists($args->{'bread_crumbs'}) or exists($args->{'bread_crumbs_component'})) { &Apache::lonhtmlcommon::clear_breadcrumbs(); @@ -6588,8 +6935,8 @@ sub start_page { #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(); + } else { + $result .= &Apache::lonhtmlcommon::breadcrumbs(); } } return $result; @@ -6722,14 +7069,14 @@ sub simple_error_page { my ($add_class) = @_; $row_count[0]++; my $css_class = ($row_count[0] % 2)?'LC_odd_row':'LC_even_row'; - $css_class = (join(' ',$css_class,$add_class)); + $css_class = (join(' ',$css_class,$add_class)) unless ($add_class eq ''); return ''."\n";; } sub continue_data_table_row { my ($add_class) = @_; my $css_class = ($row_count[0] % 2)?'LC_odd_row':'LC_even_row'; - $css_class = (join(' ',$css_class,$add_class)); + $css_class = (join(' ',$css_class,$add_class)) unless ($add_class eq '');; return ''."\n";; } @@ -6753,6 +7100,11 @@ sub simple_error_page { sub end_data_table_header_row { return ''."\n";; } + + sub data_table_caption { + my $caption = shift; + return "$caption"; + } } =pod @@ -6823,7 +7175,7 @@ sub get_users_function { if ($env{'request.role'}=~/^(st)/) { $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)/) { @@ -6894,7 +7246,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; @@ -7515,9 +7867,9 @@ sub user_picker { 'whse' => "When searching by last,first you must include at least one character in the first name.", 'thfo' => "The following need to be corrected before the search can be run:", ); - my $domform = &select_dom_form($currdom,'srchdomain',1,1); + my $domform = &select_dom_form($currdom,'srchdomain',undef,1); my $srchinsel = ' \n"; @@ -7575,9 +7929,9 @@ sub user_picker { ); $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.' - ,'','') + .'
' + .&mt('Enter a valid e-mail address as the username for the new user.').' '.&mt('Please contact the [_1]helpdesk[_2] for assistance.' + ,'','') .'


'; } } @@ -9273,10 +9627,11 @@ sub restore_settings { =item * &build_recipient_list() -Build recipient lists for four types of e-mail: +Build recipient lists for five types of e-mail: (a) Error Reports, (b) Package Updates, (c) lonstatus warnings/errors -(d) Help requests, generated by -lonerrorhandler.pm, CHECKRPMS, loncron, and lonsupportreq.pm respectively. +(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), @@ -9446,6 +9801,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; } @@ -9558,12 +9915,14 @@ cathash - reference to hash of categorie 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); @@ -9572,15 +9931,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) { @@ -9588,18 +9952,26 @@ sub assign_categories_table { $checked = ' checked="checked"'; } } - $output .= ''. - ''.$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(); + } } } } @@ -9844,12 +10216,26 @@ 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'}) { + 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'], @@ -9860,15 +10246,23 @@ sub check_clone { } elsif (grep(/^\*\:\Q$args->{'ccdomain'}\E$/,@cloners)) { $can_clone = 1; } else { + my $ccrole = 'cc'; + if ($args->{'crstype'} eq 'Community') { + $ccrole = 'co'; + } my %roleshash = &Apache::lonnet::get_my_roles($args->{'ccuname'}, $args->{'ccdomain'}, - 'userroles',['active'],['cc'], + 'userroles',['active'],[$ccrole], [$args->{'clonedomain'}]); - if (($roleshash{$args->{'clonecourse'}.':'.$args->{'clonedomain'}.':cc'}) || (grep(/^\Q$args->{'ccuname'}\E:\Q$args->{'ccdomain'}\E$/,@cloners))) { + if (($roleshash{$args->{'clonecourse'}.':'.$args->{'clonedomain'}.':'.$ccrole}) || (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'}); + 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'}); + } } } } @@ -9877,7 +10271,7 @@ sub check_clone { } 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') { @@ -9915,7 +10309,8 @@ 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 @@ -10202,6 +10597,21 @@ sub construct_course { $outcome .= ($fatal?$errtext:'write ok').$linefeed; } + if ($args->{'cloneroster'}) { + my ($numadded,$clisterror) = &Apache::lonclonecourse::copyroster($cloneid,$$courseid,$args->{'startaccess'},$args->{'endaccess'}); + if ($clisterror) { + $outcome .= "\0".&mt('An error occurred when copying the student roster from the old course to the new course; the error was: [_1].',$clisterror).$linefeed; + if ($numadded) { + $outcome .= &mt('Although [quant,_1,student] have received roles in the new course the roster does not report this. It is ').$linefeed; + } + } else { + if ($numadded) { + $outcome .= "\0".&mt('[quant,_1,student] copied from roster for old course to roster for new course.',$numadded).$linefeed; + } else { + $outcome .= "\0".&mt('No students have been enrolled in the new Concept Test.').' '.&mt('This is because either (a) an error occurred, or (b) there were no students with either current access or access which ended on/after the current default end date set for access to the old course.').$linefeed; + } + } + } return (1,$outcome); } @@ -10229,6 +10639,16 @@ sub group_term { 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]); @@ -10458,6 +10878,60 @@ sub _add_to_env { } } +sub new_roles_update { + my $rolecount = 0; + foreach my $envkey (keys(%env)) { + next unless ($envkey =~ /^user\.role\./); + $rolecount ++; + } + my $newrolecount = 0; + if (!$rolecount) { + my %userenv; + foreach my $crstype ('official','unofficial','community') { + $userenv{'canrequest.'.$crstype} = + &Apache::lonnet::usertools_access($env{'user.name'}, + $env{'user.domain'},$crstype,'reload','requestcourses'); + } + my $then=$env{'user.login.time'}; + my $refresh=time; + my (%userroles,%allroles,%allgroups,@newroles); + my %roleshash = + &Apache::lonnet::get_my_roles($env{'user.name'},$env{'user.domain'},'userroles',['active','future','previous'],undef,undef,1); + foreach my $item (keys(%roleshash)) { + my ($uname,$udom,$role,$section) = split(':',$item); + my $where = '/'.$udom.'/'.$uname; + my ($tstart,$tend) = split(':',$roleshash{$item}); + if ($section ne '') { + $where .= '/'.$section; + } + my $spec = $role.'.'.$where; + &Apache::lonnet::set_arearole($role,$where,$tstart,$tend, + $env{'user.domain'},$env{'user.name'}); + $userroles{'user.role.'.$spec} = $tstart.'.'.$tend; + $newrolecount ++; + unless (grep(/^\Q$role\E$/,@newroles)) { + push(@newroles,$role); + } + my $status = + &Apache::lonnet::curr_role_status($tstart,$tend,$refresh,$then); + if ($status eq 'active') { + &Apache::lonnet::gather_roleprivs(\%allroles,\%allgroups,\%userroles, + $where,$role,$tstart,$tend); + } + } + if (@newroles) { + my ($author,$adv) = &Apache::lonnet::set_userprivs(\%userroles,\%allroles, + \%allgroups); + &Apache::lonnet::appenv(\%userroles,[@newroles,'cm']); + $userenv{'user.adv'} = $adv; + $userenv{'user.author'} = $author; + $userenv{'user.refresh.time'} = $refresh; + } + &Apache::lonnet::appenv(\%userenv); + } + return $newrolecount; +} + # --- Get the symbolic name of a problem and the url sub get_symb { my ($request,$silent) = @_; @@ -10499,6 +10973,151 @@ sub clean_symb { return ($symb,$enc); } +sub needs_gci_custom { + my $custommenu; + my $numdc = &check_for_gci_dc(); + unless ($numdc) { + my $then=$env{'user.login.time'}; + my $now = time; + my %cnums = ( + review => '9615072b469884921gcil1', + submit => '1H96711d710194bfegcil1', + ); + if ($env{'user.role.st./gci/'.$cnums{'review'}}) { + my ($start,$end) = + split('.',$env{'user.role.st./gci/'.$cnums{'review'}}); + if (((!$start) || ($start && $start <= $now)) && + ((!$end) || ($end > $now))) { + $custommenu = 1; + if ($env{'user.role.cc./gci/'.$cnums{'review'}}) { + my ($ccstart,$ccend) = + split('.',$env{'user.role.cc./gci/'.$cnums{'review'}}); + if (((!$start) || ($start && $start <= $now)) && + ((!$end) || ($end > $now))) { + $custommenu = ''; + } + } + } + } + } + return $custommenu; +} + +sub check_for_gci_dc { + my $then=$env{'user.login.time'}; + my $numdc = 0; + foreach my $dom ('gci','gcitest') { + if ($env{'user.role.dc./'.$dom.'/'}) { + my $livedc = 1; + my ($tstart,$tend)=split(/\./,$env{'user.role.dc./'.$dom.'/'}); + if ($tstart && $tstart>$then) { $livedc = 0; } + if ($tend && $tend <$then) { $livedc = 0; } + if ($livedc) { + $numdc++; + } + } + } + return $numdc; +} + +sub existing_gcitest_courses { + my ($role) = @_; + my %courses; + my $cdom = 'gcitest'; + my $now = time; + foreach my $envkey (keys(%env)) { + my $cnum; + if ($envkey =~ m{^user\.role\.\Q$role\E\./\Q$cdom\E/($match_courseid)$}) { + $cnum = $1; + } else { + next; + } + my ($tstart,$tend) = split('.',$env{$envkey}); + if (((!$tstart) || ($tstart < $now)) && ((!$tend) || ($tend > $now))) { + my $descr = $env{'course.'.$cdom.'_'.$cnum.'.description'}; + if ($descr ne '') { + $courses{$cdom.'_'.$cnum}{'description'} = $descr; + } + } + } + return %courses; +} + +sub gcitest_switcher { + my ($role,$formname,%courses) = @_; + my $output; + my %Sortby; + foreach my $course (sort(keys(%courses))) { + next unless (ref($courses{$course}) eq 'HASH'); + my $clean_title = $courses{$course}{'description'}; + $clean_title =~ s/\W+//g; + if ($clean_title eq '') { + $clean_title = $courses{$course}{'description'}; + } + push(@{$Sortby{$clean_title}},$course); + } + my @sorted_courses = sort { lc($a) cmp lc($b) } (keys(%Sortby)); + my $default; + if (@sorted_courses > 1) { + if (($env{'request.course.id'}) && ($courses{$env{'request.course.id'}})) { + $default = &mt('Switch concept test ...'); + } else { + $default = &mt('Select a concept test ...'); + } + } else { + unless (($env{'request.course.id'}) && ($courses{$env{'request.course.id'}})) { + $default = &mt('Select concept test ...'); + } + } + if ($default) { + $output = '
'. + '
'; + } + return $output; +} + +sub gcitest_switcher_js { + my ($current,$numcourses,$formname) = @_; + my $output = <<"ENDJS"; + +function courseswitcher(caller) { + var numcourses = $numcourses; + var current = '$current'; + var choice = document.$formname.newrole.options[document.$formname.newrole.selectedIndex].value; + if (choice == '') { + if (caller == 'icon') { + alert('No Concept Test selected'); + } + document.$formname.selectrole.value = ''; + return; + } + if (choice == current) { + if ((caller != 'icon') && (numcourses > 1)) { + alert('You have selected the current course.\\nPlease select a different Concept Test course'); + } + document.$formname.newrole.selectedIndex = 0; + document.$formname.selectrole.value = ''; + return; + } + document.$formname.selectrole.value = '1'; + document.$formname.submit(); + return; +} + +ENDJS + return $output; +} + + + =pod =back