--- loncom/interface/loncommon.pm 2012/08/07 10:52:17 1.1090 +++ loncom/interface/loncommon.pm 2012/11/16 16:54:45 1.1097 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # a pile of common routines # -# $Id: loncommon.pm,v 1.1090 2012/08/07 10:52:17 foxr Exp $ +# $Id: loncommon.pm,v 1.1097 2012/11/16 16:54:45 bisitz Exp $ # # Copyright Michigan State University Board of Trustees # @@ -70,6 +70,9 @@ use Apache::lonclonecourse(); use LONCAPA qw(:DEFAULT :match); use DateTime::TimeZone; use DateTime::Locale::Catalog; +use Text::Aspell; +use Authen::Captcha; +use Captcha::reCAPTCHA; # ---------------------------------------------- Designs use vars qw(%defaultdesign); @@ -887,10 +890,14 @@ sub check_uncheck_jscript { function checkAll(field) { if (field.length > 0) { for (i = 0; i < field.length; i++) { - field[i].checked = true ; + if (!field[i].disabled) { + field[i].checked = true; + } } } else { - field.checked = true + if (!field.disabled) { + field.checked = true; + } } } @@ -3063,41 +3070,27 @@ Note: This sub assumes that aspell is in sub check_spelling { my ($wordlist, $language) = @_; + my @misspellings; + + # Generate the speller and set the langauge. + # if explicitly selected: - # Format the command. If $language is null then - # don't request a language - Note that's dangerous - # because there's no assurance the server is running the intended default - # language. - - my $langswitch = ''; + my $speller = Text::Aspell->new; if ($language) { - $langswitch = "--lang=$language"; + $speller->set_option('lang', $language); } - my $aspell_command = "aspell -a $language"; - my $full_command = "echo $wordlist | $aspell_command"; - - my $ispell_result = `$full_command`; + # Turn the word list into an array of words by splittingon whitespace - # The result is several lines of text. - # the first line will start with @(#). Other wise - # There's an error. With an error our fallback is to declare - # all the words are correctly spelled (return empty string). + my @words = split(/\s+/, $wordlist); - my @misspellings; - my @lines = split(/\n/, $ispell_result); - my $heading = shift(@lines); # header - if ($heading =~ /^\@\(#\) /) { - foreach my $word (split(/\s+/, $wordlist)) { - my $spellok = pop(@lines); - if (!($spellok =~ /^\*/)) { - push(@misspellings, $word); - } + foreach my $word (@words) { + if(! $speller->check($word)) { + push(@misspellings, $word); } - return join(' ', (@misspellings)); # empty if all words ok. - } else { - return ""; } + return join(' ', @misspellings); + } # -------------------------------------------------------------- Plaintext name @@ -3333,7 +3326,7 @@ sub aboutmewrapper { if (!defined($username) && !defined($domain)) { return; } - return ''.$link.''; } @@ -5067,6 +5060,10 @@ Inputs: should it have jsmath forced on by the current page +=item * $advtoolsref, optional argument, ref to an array containing + inlineremote items to be added in "Functions" menu below + breadcrumbs. + =back Returns: A uniform header for LON-CAPA web pages. @@ -5078,7 +5075,7 @@ other decorations will be returned. sub bodytag { my ($title,$function,$addentries,$bodyonly,$domain,$forcereg, - $no_nav_bar,$bgcolor,$args)=@_; + $no_nav_bar,$bgcolor,$args,$advtoolsref)=@_; my $public; if ((($env{'user.name'} eq 'public') && ($env{'user.domain'} eq 'public')) @@ -5197,8 +5194,15 @@ sub bodytag { if ($env{'request.state'} eq 'construct') { $bodytag .= &Apache::lonmenu::innerregister($forcereg, $args->{'bread_crumbs'}); - } elsif ($forcereg) { - $bodytag .= &Apache::lonmenu::innerregister($forcereg); + } elsif ($forcereg) { + $bodytag .= &Apache::lonmenu::innerregister($forcereg,undef, + $args->{'group'}); + } else { + $bodytag .= + &Apache::lonmenu::prepare_functions($env{'request.noversionuri'}, + $forcereg,$args->{'group'}, + $args->{'bread_crumbs'}, + $advtoolsref); } }else{ # this is to seperate menu from content when there's no secondary @@ -5413,10 +5417,12 @@ form, .inline { .LC_error { color: red; - font-size: larger; } -.LC_warning, +.LC_warning { + color: darkorange; +} + .LC_diff_removed { color: red; } @@ -7383,6 +7389,8 @@ $args - additional optional args support current page bread_crumbs -> Array containing breadcrumbs bread_crumbs_component -> if exists show it as headline else show only the breadcrumbs + group -> includes the current group, if page is for a + specific group =back @@ -7395,7 +7403,7 @@ sub start_page { #&Apache::lonnet::logthis("start_page ".join(':',caller(0))); $env{'internal.start_page'}++; - my $result; + my ($result,@advtools); if (! exists($args->{'skip_phases'}{'head'}) ) { $result .= &xml_begin() . &headtag($title, $head_extra, $args); @@ -7412,7 +7420,8 @@ sub start_page { $args->{'function'}, $args->{'add_entries'}, $args->{'only_body'}, $args->{'domain'}, $args->{'force_register'}, $args->{'no_nav_bar'}, - $args->{'bgcolor'}, $args); + $args->{'bgcolor'}, $args, + \@advtools); } } @@ -7441,6 +7450,10 @@ sub start_page { &Apache::lonhtmlcommon::add_breadcrumb($crumb); } } + # if @advtools array contains items add then to the breadcrumbs + if (@advtools > 0) { + &Apache::lonmenu::advtools_crumbs(@advtools); + } #if bread_crumbs_component exists show it as headline else show only the breadcrumbs if(exists($args->{'bread_crumbs_component'})){ @@ -7836,7 +7849,7 @@ sub simple_error_page { my ($r,$title,$msg) = @_; my $page = &Apache::loncommon::start_page($title). - &mt($msg). + '
'.&mt($msg).'
'. &Apache::loncommon::end_page(); if (ref($r)) { $r->print($page); @@ -13885,6 +13898,20 @@ sub init_user_environment { \%userenv,\%domdef,\%is_adv); } + $userenv{'canrequest.author'} = + &Apache::lonnet::usertools_access($username,$domain,'requestauthor', + 'reload','requestauthor', + \%userenv,\%domdef,\%is_adv); + my %reqauthor = &Apache::lonnet::get('requestauthor',['author_status','author'], + $domain,$username); + my $reqstatus = $reqauthor{'author_status'}; + if ($reqstatus eq 'approval' || $reqstatus eq 'approved') { + if (ref($reqauthor{'author'}) eq 'HASH') { + $userenv{'requestauthorqueued'} = $reqstatus.':'. + $reqauthor{'author'}{'timestamp'}; + } + } + $env{'user.environment'} = "$lonids/$cookie.id"; if (tie(my %disk_env,'GDBM_File',"$lonids/$cookie.id", @@ -14059,6 +14086,164 @@ sub parse_supplemental_title { return $title; } +sub captcha_display { + my ($context,$lonhost) = @_; + my ($output,$error); + my ($captcha,$pubkey,$privkey) = &get_captcha_config($context,$lonhost); + if ($captcha eq 'original') { + $output = &create_captcha(); + unless ($output) { + $error = 'captcha'; + } + } elsif ($captcha eq 'recaptcha') { + $output = &create_recaptcha($pubkey); + unless ($output) { + $error = 'recaptcha'; + } + } + return ($output,$error); +} + +sub captcha_response { + my ($context,$lonhost) = @_; + my ($captcha_chk,$captcha_error); + my ($captcha,$pubkey,$privkey) = &get_captcha_config($context,$lonhost); + if ($captcha eq 'original') { + ($captcha_chk,$captcha_error) = &check_captcha(); + } elsif ($captcha eq 'recaptcha') { + $captcha_chk = &check_recaptcha($privkey); + } else { + $captcha_chk = 1; + } + return ($captcha_chk,$captcha_error); +} + +sub get_captcha_config { + my ($context,$lonhost) = @_; + my ($captcha,$pubkey,$privkey,$hashtocheck); + my $hostname = &Apache::lonnet::hostname($lonhost); + my $serverhomeID = &Apache::lonnet::get_server_homeID($hostname); + my $serverhomedom = &Apache::lonnet::host_domain($serverhomeID); + if ($context eq 'usercreation') { + my %domconfig = &Apache::lonnet::get_dom('configuration',[$context],$serverhomedom); + if (ref($domconfig{$context}) eq 'HASH') { + $hashtocheck = $domconfig{$context}{'cancreate'}; + if (ref($hashtocheck) eq 'HASH') { + if ($hashtocheck->{'captcha'} eq 'recaptcha') { + if (ref($hashtocheck->{'recaptchakeys'}) eq 'HASH') { + $pubkey = $hashtocheck->{'recaptchakeys'}{'public'}; + $privkey = $hashtocheck->{'recaptchakeys'}{'private'}; + } + if ($privkey && $pubkey) { + $captcha = 'recaptcha'; + } else { + $captcha = 'original'; + } + } elsif ($hashtocheck->{'captcha'} ne 'notused') { + $captcha = 'original'; + } + } + } else { + $captcha = 'captcha'; + } + } elsif ($context eq 'login') { + my %domconfhash = &Apache::loncommon::get_domainconf($serverhomedom); + if ($domconfhash{$serverhomedom.'.login.captcha'} eq 'recaptcha') { + $pubkey = $domconfhash{$serverhomedom.'.login.recaptchakeys_public'}; + $privkey = $domconfhash{$serverhomedom.'.login.recaptchakeys_private'}; + if ($privkey && $pubkey) { + $captcha = 'recaptcha'; + } else { + $captcha = 'original'; + } + } elsif ($domconfhash{$serverhomedom.'.login.captcha'} eq 'original') { + $captcha = 'original'; + } + } + return ($captcha,$pubkey,$privkey); +} + +sub create_captcha { + my %captcha_params = &captcha_settings(); + my ($output,$maxtries,$tries) = ('',10,0); + while ($tries < $maxtries) { + $tries ++; + my $captcha = Authen::Captcha->new ( + output_folder => $captcha_params{'output_dir'}, + data_folder => $captcha_params{'db_dir'}, + ); + my $md5sum = $captcha->generate_code($captcha_params{'numchars'}); + + if (-e $Apache::lonnet::perlvar{'lonCaptchaDir'}.'/'.$md5sum.'.png') { + $output = ''."\n". + &mt('Type in the letters/numbers shown below').' '. + '