--- loncom/interface/loncommon.pm 2014/04/23 10:33:52 1.1075.2.70 +++ loncom/interface/loncommon.pm 2014/01/21 14:38:51 1.1171 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # a pile of common routines # -# $Id: loncommon.pm,v 1.1075.2.70 2014/04/23 10:33:52 raeburn Exp $ +# $Id: loncommon.pm,v 1.1171 2014/01/21 14:38:51 kruse Exp $ # # Copyright Michigan State University Board of Trustees # @@ -69,14 +69,12 @@ use Apache::lontexconvert(); use Apache::lonclonecourse(); use Apache::lonuserutils(); use Apache::lonuserstate(); -use Apache::courseclassifier(); use LONCAPA qw(:DEFAULT :match); use DateTime::TimeZone; use DateTime::Locale::Catalog; +use Text::Aspell; use Authen::Captcha; use Captcha::reCAPTCHA; -use Crypt::DES; -use DynaLoader; # for Crypt::DES version # ---------------------------------------------- Designs use vars qw(%defaultdesign); @@ -161,6 +159,7 @@ sub ssi_with_retries { # ----------------------------------------------- Filetypes/Languages/Copyright my %language; my %supported_language; +my %supported_codes; my %latex_language; # For choosing hyphenation in my %latex_language_bykey; # for choosing hyphenation from metadata my %cprtag; @@ -195,14 +194,15 @@ BEGIN { while (my $line = <$fh>) { next if ($line=~/^\#/); chomp($line); - my ($key,$two,$country,$three,$enc,$val,$sup,$latex)=(split(/\t/,$line)); + my ($key,$code,$country,$three,$enc,$val,$sup,$latex)=(split(/\t/,$line)); $language{$key}=$val.' - '.$enc; if ($sup) { $supported_language{$key}=$sup; + $supported_codes{$key} = $code; } if ($latex) { $latex_language_bykey{$key} = $latex; - $latex_language{$two} = $latex; + $latex_language{$code} = $latex; } } close($fh); @@ -666,7 +666,7 @@ if (!Array.prototype.indexOf) { var n = 0; if (arguments.length > 0) { n = Number(arguments[1]); - if (n !== n) { // shortcut for verifying if it's NaN + if (n !== n) { // shortcut for verifying if it is NaN n = 0; } else if (n !== 0 && n !== (1 / 0) && n !== -(1 / 0)) { n = (n > 0 || -1) * Math.floor(Math.abs(n)); @@ -902,12 +902,12 @@ sub check_uncheck_jscript { function checkAll(field) { if (field.length > 0) { for (i = 0; i < field.length; i++) { - if (!field[i].disabled) { + if (!field[i].disabled) { field[i].checked = true; } } } else { - if (!field.disabled) { + if (!field.disabled) { field.checked = true; } } @@ -1017,6 +1017,33 @@ sub select_language { =pod + +=item * &list_languages() + +Returns an array reference that is suitable for use in language prompters. +Each array element is itself a two element array. The first element +is the language code. The second element a descsriptiuon of the +language itself. This is suitable for use in e.g. +&Apache::edit::select_arg (once dereferenced that is). + +=cut + +sub list_languages { + my @lang_choices; + + foreach my $id (&languageids()) { + my $code = &supportedlanguagecode($id); + if ($code) { + my $selector = $supported_codes{$id}; + my $description = &plainlanguagedescription($id); + push (@lang_choices, [$selector, $description]); + } + } + return \@lang_choices; +} + +=pod + =item * &linked_select_forms(...) linked_select_forms returns a string containing a block @@ -1237,11 +1264,7 @@ sub help_open_topic { $topic=~s/\W/\_/g; if (!$stayOnPage) { - if ($env{'browser.mobile'}) { - $link = "javascript:openMyModal('/adm/help/${filename}.hlp',$width,$height,'yes');"; - } else { - $link = "javascript:void(open('/adm/help/${filename}.hlp', 'Help_for_$topic', 'menubar=0,toolbar=1,scrollbars=1,width=$width,height=$height,resizable=yes'))"; - } + $link = "javascript:openMyModal('/adm/help/${filename}.hlp',$width,$height,'yes');"; } elsif ($stayOnPage eq 'popup') { $link = "javascript:void(open('/adm/help/${filename}.hlp', 'Help_for_$topic', 'menubar=0,toolbar=1,scrollbars=1,width=$width,height=$height,resizable=yes'))"; } else { @@ -1355,10 +1378,8 @@ sub help_open_menu { sub top_nav_help { my ($text) = @_; $text = &mt($text); - my $stay_on_page; - unless ($env{'environment.remote'} eq 'on') { - $stay_on_page = 1; - } + my $stay_on_page = 1; + my ($link,$banner_link); unless ($env{'request.noversionuri'} =~ m{^/adm/helpmenu}) { $link = ($stay_on_page) ? "javascript:helpMenu('display')" @@ -1388,9 +1409,9 @@ sub help_menu_js { &Apache::loncommon::start_page('Help Menu', undef, {'frameset' => 1, 'js_ready' => 1, - 'use_absolute' => $httphost, + 'use_absolute' => $httphost, 'add_entries' => { - 'border' => '0', + 'border' => '0', 'rows' => "110,*",},}); my $end_page = &Apache::loncommon::end_page({'frameset' => 1, @@ -2192,7 +2213,7 @@ The optional $onchange argument specifie The optional $incdoms is a reference to an array of domains which will be the only available options. -The optional $excdoms is a reference to an array of domains which will be excluded from the available options. +The optional $excdoms is a reference to an array of domains which will be excluded from the available options. =cut @@ -2210,7 +2231,7 @@ sub select_dom_form { } if ($includeempty) { @domains=('',@domains); } if (ref($excdoms) eq 'ARRAY') { - map { $exclude{$_} = 1; } @{$excdoms}; + map { $exclude{$_} = 1; } @{$excdoms}; } my $selectdomain = "'. - &Apache::lonnet::domain($codedom,'description'); - } else { - $domainselectform = &select_dom_form($filter->{$item}, - 'domainfilter', - $allow_blank,'',$onchange); - } - } else { - $list->{$item} = &HTML::Entities::encode($filter->{$item},'<>&"'); - } - } - - # last course activity filter and selection - $sincefilterform = &timebased_select_form('sincefilter',$filter); - - # course created filter and selection - if (exists($filter->{'createdfilter'})) { - $createdfilterform = &timebased_select_form('createdfilter',$filter); - } - - my %lt = &Apache::lonlocal::texthash( - 'cac' => "$crstype Activity", - 'ccr' => "$crstype Created", - 'cde' => "$crstype Title", - 'cdo' => "$crstype Domain", - 'ins' => 'Institutional Code', - 'inc' => 'Institutional Categorization', - 'cow' => "$crstype Owner/Co-owner", - 'cop' => "$crstype Personnel Includes", - 'cog' => 'Type', - ); - - if (($formname eq 'ccrs') || ($formname eq 'requestcrs')) { - my $typeval = 'Course'; - if ($crstype eq 'Community') { - $typeval = 'Community'; - } - $typeselectform = ''; - } else { - $typeselectform = '"; - } - - my ($cloneableonlyform,$cloneabletitle); - if (exists($filter->{'cloneableonly'})) { - my $cloneableon = ''; - my $cloneableoff = ' checked="checked"'; - if ($filter->{'cloneableonly'}) { - $cloneableon = $cloneableoff; - $cloneableoff = ''; - } - $cloneableonlyform = ''.(' 'x3).''; - if ($formname eq 'ccrs') { - $cloneabletitle = &mt('Cloneable for').' '.$cloneruname.':'.$clonerudom; - } else { - $cloneabletitle = &mt('Cloneable by you'); - } - } - my $officialjs; - if ($crstype eq 'Course') { - if (exists($filter->{'instcodefilter'})) { -# if (($fixeddom) || ($formname eq 'requestcrs') || -# ($formname eq 'modifycourse') || ($formname eq 'filterpicker')) { - if ($codedom) { - $officialjs = 1; - ($instcodeform,$jscript,$$numtitlesref) = - &Apache::courseclassifier::instcode_selectors($codedom,'filterpicker', - $officialjs,$codetitlesref); - if ($jscript) { - $jscript = ''."\n"; - } - } - if ($instcodeform eq '') { - $instcodeform = - ''; - $instcodetitle = $lt{'ins'}; - } else { - $instcodetitle = $lt{'inc'}; - } - if ($fixeddom) { - $instcodetitle .= '
('.$codedom.')'; - } - } - } - my $output = qq| -
- -|; - if ($formname eq 'modifycourse') { - $output .= ''."\n". - ''."\n"; - } elsif ($formname ne 'quotacheck') { - my $name_input; - if ($cnameelement ne '') { - $name_input = ''; - } - $output .= qq| - - -$name_input -$roleelement -$multelement -$typeelement -|; - if ($formname eq 'portform') { - $output .= ''."\n"; - } - } - if ($fixeddom) { - $output .= ''."\n"; - } - $output .= "
\n".&Apache::lonhtmlcommon::start_pick_box(); - if ($sincefilterform) { - $output .= &Apache::lonhtmlcommon::row_title($lt{'cac'}) - .$sincefilterform - .&Apache::lonhtmlcommon::row_closure(); - } - if ($createdfilterform) { - $output .= &Apache::lonhtmlcommon::row_title($lt{'ccr'}) - .$createdfilterform - .&Apache::lonhtmlcommon::row_closure(); - } - if ($domainselectform) { - $output .= &Apache::lonhtmlcommon::row_title($lt{'cdo'}) - .$domainselectform - .&Apache::lonhtmlcommon::row_closure(); - } - if ($typeselectform) { - if (($formname eq 'ccrs') || ($formname eq 'requestcrs')) { - $output .= $typeselectform; - } else { - $output .= &Apache::lonhtmlcommon::row_title($lt{'cog'}) - .$typeselectform - .&Apache::lonhtmlcommon::row_closure(); - } - } - if ($instcodeform) { - $output .= &Apache::lonhtmlcommon::row_title($instcodetitle) - .$instcodeform - .&Apache::lonhtmlcommon::row_closure(); - } - if (exists($filter->{'ownerfilter'})) { - $output .= &Apache::lonhtmlcommon::row_title($lt{'cow'}). - '
'.&mt('Username').'
'. - '
'.&mt('Domain').'
'. - $ownerdomselectform.'
'. - &Apache::lonhtmlcommon::row_closure(); - } - if (exists($filter->{'personfilter'})) { - $output .= &Apache::lonhtmlcommon::row_title($lt{'cop'}). - '
'.&mt('Username').'
'. - '
'.&mt('Domain').'
'. - $persondomselectform.'
'. - &Apache::lonhtmlcommon::row_closure(); - } - if (exists($filter->{'coursefilter'})) { - $output .= &Apache::lonhtmlcommon::row_title(&mt('LON-CAPA course ID')) - .'' - .&Apache::lonhtmlcommon::row_closure(); - } - if ($cloneableonlyform) { - $output .= &Apache::lonhtmlcommon::row_title($cloneabletitle). - $cloneableonlyform.&Apache::lonhtmlcommon::row_closure(); - } - if (exists($filter->{'descriptfilter'})) { - $output .= &Apache::lonhtmlcommon::row_title($lt{'cde'}) - .'' - .&Apache::lonhtmlcommon::row_closure(1); - } - $output .= &Apache::lonhtmlcommon::end_pick_box().'

'.$clonetext."\n". - ''."\n". - '

'."\n".'
'."\n".'
'."\n"; - return $jscript.$clonewarning.$output; -} - -=pod - -=item * &timebased_select_form() - -Create markup for a dropdown list used to select a time-based -filter e.g., Course Activity, Course Created, when searching for courses -or communities - -Inputs: - -item - name of form element (sincefilter or createdfilter) - -filter - anonymous hash of criteria and their values - -Returns: HTML for a select box contained a blank, then six time selections, - with value set in incoming form variables currently selected. - -Side Effects: None - -=cut - -sub timebased_select_form { - my ($item,$filter) = @_; - if (ref($filter) eq 'HASH') { - $filter->{$item} =~ s/[^\d-]//g; - if (!$filter->{$item}) { $filter->{$item}=-1; } - return &select_form( - $filter->{$item}, - $item, - { '-1' => '', - '86400' => &mt('today'), - '604800' => &mt('last week'), - '2592000' => &mt('last month'), - '7776000' => &mt('last three months'), - '15552000' => &mt('last six months'), - '31104000' => &mt('last year'), - 'select_form_order' => - ['-1','86400','604800','2592000','7776000', - '15552000','31104000']}); - } -} - -=pod - -=item * &js_changer() - -Create script tag containing Javascript used to submit course search form -when course type or domain is changed, and also to hide 'Searching ...' on -page load completion for page showing search result. - -Inputs: None - -Returns: markup containing updateFilters() and hideSearching() javascript functions. - -Side Effects: None - -=cut - -sub js_changer { - return < -// - - -ENDJS -} - -=pod - -=item * &search_courses() - -Process selected filters form course search form and pass to lonnet::courseiddump -to retrieve a hash for which keys are courseIDs which match the selected filters. - -Inputs: - -dom - domain being searched - -type - course type ('Course' or 'Community' or '.' if any). - -filter - anonymous hash of criteria and their values - -numtitles - for institutional codes - number of categories - -cloneruname - optional username of new course owner - -clonerudom - optional domain of new course owner - -domcloner - Optional "domcloner" flag; has value=1 if user has ccc priv in domain being filtered by, - (used when DC is using course creation form) - -codetitles - reference to array of titles of components in institutional codes (official courses). - - -Returns: %courses - hash of courses satisfying search criteria, keys = course IDs, values are corresponding colon-separated escaped description, institutional code, owner and type. - - -Side Effects: None - -=cut - - -sub search_courses { - my ($dom,$type,$filter,$numtitles,$cloneruname,$clonerudom,$domcloner,$codetitles) = @_; - my (%courses,%showcourses,$cloner); - if (($filter->{'ownerfilter'} ne '') || - ($filter->{'ownerdomfilter'} ne '')) { - $filter->{'combownerfilter'} = $filter->{'ownerfilter'}.':'. - $filter->{'ownerdomfilter'}; - } - foreach my $item ('descriptfilter','coursefilter','combownerfilter') { - if (!$filter->{$item}) { - $filter->{$item}='.'; - } - } - my $now = time; - my $timefilter = - ($filter->{'sincefilter'}==-1?1:$now-$filter->{'sincefilter'}); - my ($createdbefore,$createdafter); - if (($filter->{'createdfilter'} ne '') && ($filter->{'createdfilter'} !=-1)) { - $createdbefore = $now; - $createdafter = $now-$filter->{'createdfilter'}; - } - my ($instcodefilter,$regexpok); - if ($numtitles) { - if ($env{'form.official'} eq 'on') { - $instcodefilter = - &Apache::courseclassifier::instcode_search_str($dom,$numtitles,$codetitles); - $regexpok = 1; - } elsif ($env{'form.official'} eq 'off') { - $instcodefilter = &Apache::courseclassifier::instcode_search_str($dom,$numtitles,$codetitles); - unless ($instcodefilter eq '') { - $regexpok = -1; - } - } - } else { - $instcodefilter = $filter->{'instcodefilter'}; - } - if ($instcodefilter eq '') { $instcodefilter = '.'; } - if ($type eq '') { $type = '.'; } - - if (($clonerudom ne '') && ($cloneruname ne '')) { - $cloner = $cloneruname.':'.$clonerudom; - } - %courses = &Apache::lonnet::courseiddump($dom, - $filter->{'descriptfilter'}, - $timefilter, - $instcodefilter, - $filter->{'combownerfilter'}, - $filter->{'coursefilter'}, - undef,undef,$type,$regexpok,undef,undef, - undef,undef,$cloner,$env{'form.cc_clone'}, - $filter->{'cloneableonly'}, - $createdbefore,$createdafter,undef, - $domcloner); - if (($filter->{'personfilter'} ne '') && ($filter->{'persondomfilter'} ne '')) { - my $ccrole; - if ($type eq 'Community') { - $ccrole = 'co'; - } else { - $ccrole = 'cc'; - } - my %rolehash = &Apache::lonnet::get_my_roles($filter->{'personfilter'}, - $filter->{'persondomfilter'}, - 'userroles',undef, - [$ccrole,'in','ad','ep','ta','cr'], - $dom); - foreach my $role (keys(%rolehash)) { - my ($cnum,$cdom,$courserole) = split(':',$role); - my $cid = $cdom.'_'.$cnum; - if (exists($courses{$cid})) { - if (ref($courses{$cid}) eq 'HASH') { - if (ref($courses{$cid}{roles}) eq 'ARRAY') { - if (!grep(/^\Q$courserole\E$/,@{$courses{$cid}{roles}})) { - push (@{$courses{$cid}{roles}},$courserole); - } - } else { - $courses{$cid}{roles} = [$courserole]; - } - $showcourses{$cid} = $courses{$cid}; - } - } - } - %courses = %showcourses; - } - return %courses; -} - - -=pod - -=back - -=cut - - sub build_release_hashes { my ($checkparms,$checkresponsetypes,$checkcrstypes,$anonsurvey,$randomizetry) = @_; return unless((ref($checkparms) eq 'HASH') && (ref($checkresponsetypes) eq 'HASH') && @@ -15436,15 +14888,15 @@ sub captcha_display { if ($captcha eq 'original') { $output = &create_captcha(); unless ($output) { - $error = 'captcha'; + $error = 'captcha'; } } elsif ($captcha eq 'recaptcha') { $output = &create_recaptcha($pubkey); unless ($output) { - $error = 'recaptcha'; + $error = 'recaptcha'; } } - return ($output,$error,$captcha); + return ($output,$error); } sub captcha_response { @@ -15520,9 +14972,8 @@ sub create_captcha { if (-e $Apache::lonnet::perlvar{'lonCaptchaDir'}.'/'.$md5sum.'.png') { $output = ''."\n". &mt('Type in the letters/numbers shown below').' '. - ''. - '
'. - 'captcha'; + '
'. + ''; last; } } @@ -15592,19 +15043,6 @@ sub check_recaptcha { return $captcha_chk; } -sub emailusername_info { - my @fields = ('firstname','lastname','institution','web','location','officialemail'); - my %titles = &Apache::lonlocal::texthash ( - lastname => 'Last Name', - firstname => 'First Name', - institution => 'School/college/university', - location => "School's city, state/province, country", - web => "School's web address", - officialemail => 'E-mail address at institution (if different)', - ); - return (\@fields,\%titles); -} - sub cleanup_html { my ($incoming) = @_; my $outgoing; @@ -15627,47 +15065,11 @@ sub cleanup_html { return $outgoing; } -# Use: -# my $answer=reply("encrypt:passwd:$udom:$uname:$upass",$tryserver); -# -################################################## -# password associated functions # -################################################## -sub des_keys { - # Make a new key for DES encryption. - # Each key has two parts which are returned separately. - # Please note: Each key must be passed through the &hex function - # before it is output to the web browser. The hex versions cannot - # be used to decrypt. - my @hexstr=('0','1','2','3','4','5','6','7', - '8','9','a','b','c','d','e','f'); - my $lkey=''; - for (0..7) { - $lkey.=$hexstr[rand(15)]; - } - my $ukey=''; - for (0..7) { - $ukey.=$hexstr[rand(15)]; - } - return ($lkey,$ukey); -} - -sub des_decrypt { - my ($key,$cyphertext) = @_; - my $keybin=pack("H16",$key); - my $cypher; - if ($Crypt::DES::VERSION>=2.03) { - $cypher=new Crypt::DES $keybin; - } else { - $cypher=new DES $keybin; - } - my $plaintext= - $cypher->decrypt(unpack("a8",pack("H16",substr($cyphertext,0,16)))); - $plaintext.= - $cypher->decrypt(unpack("a8",pack("H16",substr($cyphertext,16,16)))); - $plaintext=substr($plaintext,1,ord(substr($plaintext,0,1)) ); - return $plaintext; -} +=pod + +=back + +=cut 1; __END__;