--- loncom/interface/loncourserespicker.pm 2013/11/13 01:40:07 1.8 +++ loncom/interface/loncourserespicker.pm 2024/11/22 22:42:27 1.17 @@ -1,6 +1,6 @@ # The LearningOnline Network # -# $Id: loncourserespicker.pm,v 1.8 2013/11/13 01:40:07 raeburn Exp $ +# $Id: loncourserespicker.pm,v 1.17 2024/11/22 22:42:27 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -37,8 +37,9 @@ loncourserespicker provides an interface resources are to be either: (a) exported to an IMS Content Package -(b) subject to access blocking for the duriation of an exam/quiz. +(b) subject to access blocking for the duration of an exam/quiz. (c) dumped to an Authoring Space +(d) receive shortened URLs to be used when deep-linking into a course =head1 DESCRIPTION @@ -62,9 +63,10 @@ a higher level to become unchecked. There is a submit button, which will be named differently according to the context in which resource/folder selection is being made. -The three contexts currently supported are: IMS export, selection of +The four contexts currently supported are: IMS export, selection of content to be subject to access restructions for the duration of an -exam, and selection of items for dumping to an Authoring Space. +exam, selection of items for dumping to an Authoring Space, and +display or creation of shortened URLs for deep-linking, =head1 INTERNAL SUBROUTINES @@ -75,12 +77,13 @@ select items. Checking a folder causes within the folder. Unchecking a resource causing unchecking of folders containing the item back up to the top level. -Inputs: 9. +Inputs: 11. - $navmap -- Reference to LON-CAPA navmap object (encapsulates information about resources in the course). - $context -- Context in which course resource selection is being made. - Currently imsexport and examblock are supported. + Currently imsexport, examblock, dumpdocs, and shorturls + are supported. - $formname -- Name of the form in the window from which the pop-up used to select course items was launched. @@ -107,6 +110,13 @@ Inputs: 9. - $uploadedfiles -- Reference to hash: keys are paths to files in /home/httpd/lonUsers/$cdom/$1/$2/$3/$cnum/userfiles. + - $tiny -- Reference to hash: keys are symbs of course items for which + shortened URLs have already been created. + + - $readonly -- if true, no "check all" or "uncheck all" buttons will + be displayed, and checkboxes will be disabled, if this + is for an exam block or for shortened URL creation. + Output: $output is the HTML mark-up for display/selection of content items in the pop-up window. @@ -123,7 +133,7 @@ Inputs: 7. - $numcount -- Total numer of folders and resources in course. - $context -- Context in which resources are being displayed - (imsexport, examblock or dumpdocs). + (imsexport, examblock, dumpdocs or shorturls). - $formname -- Name of form. @@ -144,14 +154,14 @@ no object instantiated. Inputs: 2. - $crstype -- Container type: Course or Community - - $context -- Context: imsexport, examblock or dumpdocs + - $context -- Context: imsexport, examblock, dumpdocs, or shorturls =item &clean() Takes incoming title and replaces non-alphanumeric characters with underscore, so title can be used as suggested file name (with appended extension) for file -copied from course to Authoring space. +copied from course to Authoring Space. =item &enumerate_course_contents() @@ -162,7 +172,8 @@ map url, or symb, for an iteration throu a Course Coordinator. Used to generate numerical IDs to facilitate (a) storage of lists of maps or resources to be blocked during an exam, (b) processing selected form element during dumping of selected course - content to Authoring space. + content to Authoring Space. +(c) Inputs: 7 @@ -176,7 +187,7 @@ Inputs: 7 $title_ref - reference to hash containing titles for items in course - $context - examblock or dumpdocs + $context - examblock, dumpdocs or shorturls $cdom - course's domain @@ -206,9 +217,15 @@ use Apache::lonlocal; use LONCAPA qw(:DEFAULT :match); sub create_picker { - my ($navmap,$context,$formname,$crstype,$blockedmaps,$blockedresources,$block,$preamble,$numhome,$uploadedfiles) = @_; + my ($navmap,$context,$formname,$crstype,$blockedmaps,$blockedresources,$block,$preamble, + $numhome,$uploadedfiles,$tiny,$readonly) = @_; return unless (ref($navmap)); - my ($it,$output,$numdisc,%maps,%resources,%discussiontime,%currmaps,%currresources,%files); + my ($it,$output,$numdisc,%discussiontime,%currmaps,%currresources,%files, + %shorturls,$chkname); + $chkname = 'archive'; + if ($context eq 'shorturls') { + $chkname = 'addtiny'; + } $it = $navmap->getIterator(undef,undef,undef,1,undef,undef); if (ref($blockedmaps) eq 'HASH') { %currmaps = %{$blockedmaps}; @@ -217,6 +234,8 @@ sub create_picker { %currresources = %{$blockedresources}; } elsif (ref($uploadedfiles) eq 'HASH') { %files = %{$uploadedfiles}; + } elsif (ref($tiny) eq 'HASH') { + %shorturls = %{$tiny}; } my @checked_maps; my $curRes; @@ -236,27 +255,38 @@ sub create_picker { my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'}; my $crsprefix = &propath($cdom,$cnum).'/userfiles/'; - my ($info,$display,$onsubmit,$togglebuttons); + my ($info,$display,$onsubmit,$togglebuttons,$disabled); if ($context eq 'examblock') { my $maps_elem = 'docs_maps_'.$block; my $res_elem = 'docs_resources_'.$block; $onsubmit = ' onsubmit="return writeToOpener('."'$maps_elem','$res_elem'".');"'; $info = &mt('Items in '.lc($crstype).' for which access will be blocked.'); + if ($readonly) { + $disabled = ' disabled="disabled"'; + } } if ($context eq 'dumpdocs') { $info = ''. - &mt('Choose the uploaded course items and templated pages/problems to be copied to Authoring space.'). + &mt('Choose the uploaded course items and templated pages/problems to be copied to Authoring Space.'). '

'; $startcount = 3 + $numhome; - $onsubmit = ' onsubmit="return checkUnique(document.'.$formname.',document.'.$formname.'.archive);"'; + $onsubmit = ' onsubmit="return checkUnique(document.'.$formname.',document.'.$formname.'.'.$chkname.');"'; + } elsif ($context eq 'shorturls') { + $info = ''. + &mt('Choose the resource(s) and/or folder(s) from Main Content for which shortened URL(s) are needed.'). + '

'; } elsif ($context eq 'imsexport') { $info = &mt('Choose which items you wish to export from your '.$crstype.'.'); $startcount = 5; } - $togglebuttons = ''. - '  '; + if ($disabled) { + $togglebuttons = '
'; + } else { + $togglebuttons = ''. + '  '; + } $display = '
'."\n"; if ($context eq 'imsexport') { $display .= $info. @@ -278,7 +308,7 @@ sub create_picker { ''; } $display .= ''; - } elsif ($context eq 'examblock') { + } elsif (($context eq 'examblock') || ($context eq 'shorturls')) { $display .= $info.$togglebuttons; } elsif ($context eq 'dumpdocs') { $display .= $preamble. @@ -299,9 +329,12 @@ sub create_picker { $display .= ''.&mt('Access blocked?').''; } elsif ($context eq 'dumpdocs') { $display .= ''.&mt('Copy?').''. - ''.&mt("Title in $crstype"). + ''.&mt("Title in $crstype").''. ''.&mt('Internal Identifier').''. ''.&mt('Save as ...').''; + } elsif ($context eq 'shorturls') { + $display .= ''.&mt('Tiny URL').''. + ''.&mt("Title in $crstype").''; } $display .= &Apache::loncommon::end_data_table_header_row(); while ($curRes = $it->next()) { @@ -327,35 +360,49 @@ sub create_picker { } } $count ++; - my $currelem; + my ($currelem,$mapurl,$is_map); if ($context eq 'imsexport') { $currelem = $count+$boards+$startcount; } else { $currelem = $count+$startcount; } - $display .= &Apache::loncommon::start_data_table_row(). - ''."\n". - 'is_sequence()) || ($curRes->is_page())) { $lastcontainer = $currelem; - $display .= 'onclick="javascript:checkFolder(document.'.$formname.','."'$currelem'".')" '; - my $mapurl = (&Apache::lonnet::decode_symb($symb))[2]; - if ($currmaps{$mapurl}) { - $display .= 'checked="checked"'; - push(@checked_maps,$currelem); + $mapurl = (&Apache::lonnet::decode_symb($symb))[2]; + $is_map = 1; + } + if ($context eq 'shorturls') { + if ($shorturls{$symb}) { + $display .= ' '."/tiny/$cdom/$shorturls{$symb}".''."\n"; + } else { + $display .= ''. + ' '."\n"; } } else { - if ($curRes->is_problem()) { - $numprobs ++; - } - $display .= 'onclick="javascript:checkResource(document.'.$formname.','."'$currelem'".')" '; - if ($currresources{$symb}) { - $display .= 'checked="checked"'; + $display .= 'is_problem()) { + $numprobs ++; + } + $display .= 'onclick="javascript:checkResource(document.'.$formname.','."'$currelem'".')" '; + if ($currresources{$symb}) { + $display .= 'checked="checked"'; + } } + $display .= $disabled.' />'."\n"; } - $display .= ' />'."\n"; if ($context eq 'dumpdocs') { $display .= ''; + } elsif ($context eq 'shorturls') { + $display .= ''; } for (my $i=0; $i<$depth; $i++) { $display .= "$whitespace\n"; @@ -450,10 +497,12 @@ sub create_picker { &mt('Export').'" />

'; $numcount = $count + $boards + $startcount; } elsif ($context eq 'examblock') { - $display .= - '

'. - '

'; + unless ($readonly) { + $display .= + '

'. + '

'; + } $numcount = $count + $startcount; } elsif ($context eq 'dumpdocs') { $display .= ''. @@ -462,12 +511,19 @@ sub create_picker { ''. ''; $numcount = $count + $startcount; + } elsif ($context eq 'shorturls') { + unless ($readonly) { + $display .= + '

'. + '

'; + } } $display .= '
'; - my $scripttag = + my $scripttag = &respicker_javascript($startcount,$numcount,$context,$formname,\%children, - \%hierarchy,\@checked_maps); - if ($context eq 'dumpdocs') { + \%hierarchy,\@checked_maps,$numhome,$chkname); + if (($context eq 'dumpdocs') || ($context eq 'shorturls')) { return $scripttag.$display; } my ($title,$crumbs,$args); @@ -484,8 +540,8 @@ sub create_picker { $output .= &Apache::lonhtmlcommon::breadcrumbs('IMS Export'). &Apache::londocs::startContentScreen('tools'); } elsif ($context eq 'dumpdocs') { - $output .= &Apache::lonhtmlcommon::breadcrumbs('Copying to Authoring Space'). - &Apache::londocs::startContentScreen('tools'); + $output .= &Apache::lonhtmlcommon::breadcrumbs('Copying to Authoring Space'). + &Apache::londocs::startContentScreen('tools'); } $output .= $display; if ($context eq 'examblock') { @@ -498,21 +554,8 @@ sub create_picker { sub respicker_javascript { my ($startcount,$numitems,$context,$formname,$children,$hierarchy, - $checked_maps) = @_; - return unless ((ref($children) eq 'HASH') && (ref($hierarchy) eq 'HASH') - && (ref($checked_maps) eq 'ARRAY')); - my ($elem,$nested,$nameforelem); - if ($context eq 'dumpdocs') { - $elem='((parseInt(item)-'.$startcount.')*2)+'.$startcount; - $nested='((parseInt(nesting[item][i])-'.$startcount.')*2)+'.$startcount; - $nameforelem=$elem+1; - } else { - $elem='parseInt(item)'; - $nested='parseInt(nesting[item][i])'; - } - my $scripttag = <<"START"; - +END + } + return unless ((ref($children) eq 'HASH') && (ref($hierarchy) eq 'HASH') + && (ref($checked_maps) eq 'ARRAY')); + my ($elem,$nested,$nameforelem); + if ($context eq 'dumpdocs') { + $elem='((parseInt(item)-'.$startcount.')*2)+'.$startcount; + $nested='((parseInt(nesting[item][i])-'.$startcount.')*2)+'.$startcount; + $nameforelem=$elem+1; + } else { + $elem='parseInt(item)'; + $nested='parseInt(nesting[item][i])'; + } + my $scripttag = <<"START"; +