';
+ $text .= '';
for (my $j=0; $j<$numchildren; $j++) {
$name = $cats->[$depth]{$parent}[$j];
$item = &escape($name).':'.&escape($parent).':'.$depth;
@@ -13737,7 +13912,7 @@ sub check_clone {
}
sub construct_course {
- my ($args,$logmsg,$courseid,$crsudom,$crsunum,$udom,$uname,$context,$cnum,$category) = @_;
+ my ($args,$logmsg,$courseid,$crsudom,$crsunum,$udom,$uname,$context,$cnum,$category,$coderef) = @_;
my $outcome;
my $linefeed = ' '."\n";
if ($context eq 'auto') {
@@ -13834,8 +14009,12 @@ sub construct_course {
'plc.users.denied',
'hidefromcat',
'checkforpriv',
- 'categories'],
+ 'categories',
+ 'internal.uniquecode'],
$$crsudom,$$crsunum);
+ if ($args->{'textbook'}) {
+ $cenv{'internal.textbook'} = $args->{'textbook'};
+ }
}
#
@@ -14019,6 +14198,25 @@ sub construct_course {
}
}
+#
+# generate and store uniquecode (available to course requester), if course should have one.
+#
+ if ($args->{'uniquecode'}) {
+ my ($code,$error) = &make_unique_code($$crsudom,$$crsunum);
+ if ($code) {
+ $cenv{'internal.uniquecode'} = $code;
+ my %crsinfo =
+ &Apache::lonnet::courseiddump($$crsudom,'.',1,'.','.',$$crsunum,undef,undef,'.');
+ if (ref($crsinfo{$$crsudom.'_'.$$crsunum}) eq 'HASH') {
+ $crsinfo{$$crsudom.'_'.$$crsunum}{'uniquecode'} = $code;
+ my $putres = &Apache::lonnet::courseidput($$crsudom,\%crsinfo,$crsuhome,'notime');
+ }
+ if (ref($coderef)) {
+ $$coderef = $code;
+ }
+ }
+ }
+
if ($args->{'disresdis'}) {
$cenv{'pch.roles.denied'}='st';
}
@@ -14087,6 +14285,60 @@ sub construct_course {
return (1,$outcome);
}
+sub make_unique_code {
+ my ($cdom,$cnum) = @_;
+ # get lock on uniquecodes db
+ my $lockhash = {
+ $cnum."\0".'uniquecodes' => $env{'user.name'}.
+ ':'.$env{'user.domain'},
+ };
+ my $tries = 0;
+ my $gotlock = &Apache::lonnet::newput_dom('uniquecodes',$lockhash,$cdom);
+ my ($code,$error);
+
+ while (($gotlock ne 'ok') && ($tries<3)) {
+ $tries ++;
+ sleep 1;
+ $gotlock = &Apache::lonnet::newput_dom('uniquecodes',$lockhash,$cdom);
+ }
+ if ($gotlock eq 'ok') {
+ my %currcodes = &Apache::lonnet::dump_dom('uniquecodes',$cdom);
+ my $gotcode;
+ my $attempts = 0;
+ while ((!$gotcode) && ($attempts < 100)) {
+ $code = &generate_code();
+ if (!exists($currcodes{$code})) {
+ $gotcode = 1;
+ unless (&Apache::lonnet::newput_dom('uniquecodes',{ $code => $cnum },$cdom) eq 'ok') {
+ $error = 'nostore';
+ }
+ }
+ $attempts ++;
+ }
+ my @del_lock = ($cnum."\0".'uniquecodes');
+ my $dellockoutcome = &Apache::lonnet::del_dom('uniquecodes',\@del_lock,$cdom);
+ } else {
+ $error = 'nolock';
+ }
+ return ($code,$error);
+}
+
+sub generate_code {
+ my $code;
+ my @letts = qw(B C D G H J K M N P Q R S T V W X Z);
+ for (my $i=0; $i<6; $i++) {
+ my $lettnum = int (rand 2);
+ my $item = '';
+ if ($lettnum) {
+ $item = $letts[int( rand(18) )];
+ } else {
+ $item = 1+int( rand(8) );
+ }
+ $code .= $item;
+ }
+ return $code;
+}
+
############################################################
############################################################
@@ -14114,11 +14366,12 @@ sub group_term {
}
sub course_types {
- my @types = ('official','unofficial','community');
+ my @types = ('official','unofficial','community','textbook');
my %typename = (
official => 'Official course',
unofficial => 'Unofficial course',
community => 'Community',
+ textbook => 'Textbook course',
);
return (\@types,\%typename);
}
@@ -14251,7 +14504,7 @@ sub init_user_environment {
# ------------------------------------ Check browser type and MathML capability
my ($httpbrowser,$clientbrowser,$clientversion,$clientmathml,
- $clientunicode,$clientos,$clientmobile) = &decode_user_agent($r);
+ $clientunicode,$clientos,$clientmobile,$clientinfo) = &decode_user_agent($r);
# ------------------------------------------------------------- Get environment
@@ -14283,6 +14536,7 @@ sub init_user_environment {
"browser.unicode" => $clientunicode,
"browser.os" => $clientos,
"browser.mobile" => $clientmobile,
+ "browser.info" => $clientinfo,
"server.domain" => $Apache::lonnet::perlvar{'lonDefDomain'},
"request.course.fn" => '',
"request.course.uri" => '',
@@ -14302,6 +14556,12 @@ sub init_user_environment {
$env{'browser.interface'}=$form->{'interface'};
}
+ if ($form->{'iptoken'}) {
+ my $lonhost = $r->dir_config('lonHostID');
+ $initial_env{"user.noloadbalance"} = $lonhost;
+ $env{'user.noloadbalance'} = $lonhost;
+ }
+
my %is_adv = ( is_adv => $env{'user.adv'} );
my %domdef;
unless ($domain eq 'public') {
@@ -14314,7 +14574,7 @@ sub init_user_environment {
undef,\%userenv,\%domdef,\%is_adv);
}
- foreach my $crstype ('official','unofficial','community') {
+ foreach my $crstype ('official','unofficial','community','textbook') {
$userenv{'canrequest.'.$crstype} =
&Apache::lonnet::usertools_access($username,$domain,$crstype,
'reload','requestcourses',
@@ -14535,6 +14795,30 @@ sub parse_supplemental_title {
return $title;
}
+sub recurse_supplemental {
+ my ($cnum,$cdom,$suppmap,$numfiles,$errors) = @_;
+ if ($suppmap) {
+ my ($errtext,$fatal) = &LONCAPA::map::mapread('/uploaded/'.$cdom.'/'.$cnum.'/'.$suppmap);
+ if ($fatal) {
+ $errors ++;
+ } else {
+ if ($#LONCAPA::map::resources > 0) {
+ foreach my $res (@LONCAPA::map::resources) {
+ my ($title,$src,$ext,$type,$status)=split(/\:/,$res);
+ if (($src ne '') && ($status eq 'res')) {
+ if ($src =~ m{^\Q/uploaded/$cdom/$cnum/\E(supplemental_\d+\.sequence)$}) {
+ ($numfiles,$errors) = &recurse_supplemental($cnum,$cdom,$1,$numfiles,$errors);
+ } else {
+ $numfiles ++;
+ }
+ }
+ }
+ }
+ }
+ }
+ return ($numfiles,$errors);
+}
+
sub symb_to_docspath {
my ($symb) = @_;
return unless ($symb);
@@ -14564,7 +14848,7 @@ sub symb_to_docspath {
my $thistitle = $res->title();
$path .= '&'.
&Apache::lonhtmlcommon::entity_encode($thisurl).'&'.
- &Apache::lonhtmlcommon::entity_encode($thistitle).
+ &escape($thistitle).
':'.$res->randompick().
':'.$res->randomout().
':'.$res->encrypted().
@@ -14580,7 +14864,7 @@ sub symb_to_docspath {
}
$path .= (($path ne '')? '&' : '').
&Apache::lonhtmlcommon::entity_encode($mapurl).'&'.
- &Apache::lonhtmlcommon::entity_encode($maptitle).
+ &escape($maptitle).
':'.$mapresobj->randompick().
':'.$mapresobj->randomout().
':'.$mapresobj->encrypted().
@@ -14593,11 +14877,11 @@ sub symb_to_docspath {
$maptitle = 'Main Content';
}
$path = &Apache::lonhtmlcommon::entity_encode($mapurl).'&'.
- &Apache::lonhtmlcommon::entity_encode($maptitle).':::::'.$ispage;
+ &escape($maptitle).':::::'.$ispage;
}
unless ($mapurl eq 'default') {
$path = 'default&'.
- &Apache::lonhtmlcommon::entity_encode('Main Content').
+ &escape('Main Content').
':::::&'.$path;
}
return $path;
@@ -14610,15 +14894,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);
+ return ($output,$error,$captcha);
}
sub captcha_response {
@@ -14694,8 +14978,9 @@ sub create_captcha {
if (-e $Apache::lonnet::perlvar{'lonCaptchaDir'}.'/'.$md5sum.'.png') {
$output = ''."\n".
&mt('Type in the letters/numbers shown below').' '.
- ' '.
- ' ';
+ ''.
+ ' '.
+ ' ';
last;
}
}
@@ -14736,9 +15021,13 @@ sub check_captcha {
sub create_recaptcha {
my ($pubkey) = @_;
+ my $use_ssl;
+ if ($ENV{'SERVER_PORT'} == 443) {
+ $use_ssl = 1;
+ }
my $captcha = Captcha::reCAPTCHA->new;
return $captcha->get_options_setter({theme => 'white'})."\n".
- $captcha->get_html($pubkey).
+ $captcha->get_html($pubkey,undef,$use_ssl).
&mt('If either word is hard to read, [_1] will replace them.',
' ').
'
';
@@ -14761,6 +15050,83 @@ sub check_recaptcha {
return $captcha_chk;
}
+sub emailusername_info {
+ my @fields = ('lastname','firstname','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;
+ if ($incoming ne '') {
+ $outgoing = $incoming;
+ $outgoing =~ s/;/;/g;
+ $outgoing =~ s/\#/#/g;
+ $outgoing =~ s/\&/&/g;
+ $outgoing =~ s/</g;
+ $outgoing =~ s/>/>/g;
+ $outgoing =~ s/\(/(/g;
+ $outgoing =~ s/\)/)/g;
+ $outgoing =~ s/"/"/g;
+ $outgoing =~ s/'/'/g;
+ $outgoing =~ s/\$/$/g;
+ $outgoing =~ s{/}{/}g;
+ $outgoing =~ s/=/=/g;
+ $outgoing =~ s/\\/\/g
+ }
+ 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
|