'.
+ &mt('There was a problem removing a lockfile.').' ';
+ if ($type eq 'paste') {
+ if ($freedlock eq 'nolock') {
+ $locknotfreed =
+ '
'.
+ &mt('A lockfile was not released when you added content to the clipboard earlier in this session.').' '.
+
+ &mt('As a result addition of items to the clipboard will be unavailable until your next log-in.');
+ } else {
+ $locknotfreed .=
+ &mt('This will prevent addition of items to the clipboard until your next log-in.');
+ }
+ } elsif ($type eq 'map') {
+ $locknotfreed .=
+ &mt('This will prevent creation of additional folders or composite pages in this course.');
+ } elsif ($type eq 'smppg') {
+ $locknotfreed .=
+ &mt('This will prevent creation of additional simple pages in this course.');
+ } elsif ($type eq 'exttool') {
+ $locknotfreed .=
+ &mt('This will prevent creation of additional external tools in this course.');
+ } else {
+ $locknotfreed .=
+ &mt('This will prevent creation of additional discussion boards in this course.');
+ }
+ unless ($type eq 'paste') {
+ $locknotfreed .=
+ ' '.&mt('Please contact the [_1]helpdesk[_2] for assistance.',
+ '
','');
+ }
+ $locknotfreed .= '
';
+ }
+ return ($suffix,$errtext,$locknotfreed);
+}
+
+=pod
+
+=item tiehash()
+
+tie the hash
+
+=cut
+
+sub tiehash {
+ my ($mode)=@_;
+ $hashtied=0;
+ if ($env{'request.course.fn'}) {
+ if ($mode eq 'write') {
+ if (tie(%hash,'GDBM_File',$env{'request.course.fn'}.".db",
+ &GDBM_WRCREAT(),0640)) {
+ $hashtied=2;
+ }
+ } else {
+ if (tie(%hash,'GDBM_File',$env{'request.course.fn'}.".db",
+ &GDBM_READER(),0640)) {
+ $hashtied=1;
+ }
+ }
+ }
+}
+
+sub untiehash {
+ if ($hashtied) { untie %hash; }
+ $hashtied=0;
return OK;
+}
+
+
+
+
+sub checkonthis {
+ my ($r,$url,$level,$title,$checkstale)=@_;
+ $url=&unescape($url);
+ $alreadyseen{$url}=1;
+ $r->rflush();
+ if (($url) && ($url!~/^\/uploaded\//) && ($url!~/\*$/)) {
+ $r->print("\n
");
+ if ($level==0) {
+ $r->print("
");
+ }
+ for (my $i=0;$i<=$level*5;$i++) {
+ $r->print(' ');
+ }
+ $r->print('
'.
+ ($title?$title:$url).' ');
+ if ($url=~/^\/res\//) {
+ my $updated;
+ if (($checkstale) && ($url !~ m{^/res/lib/templates/}) &&
+ ($url !~ /\.\d+\.\w+$/)) {
+ $updated = &Apache::lonnet::remove_stale_resfile($url);
+ }
+ my $result=&Apache::lonnet::repcopy(
+ &Apache::lonnet::filelocation('',$url));
+ if ($result eq 'ok') {
+ $r->print('
'.&mt('ok').'');
+ if ($updated) {
+ $r->print('
');
+ for (my $i=0;$i<=$level*5;$i++) {
+ $r->print(' ');
+ }
+ $r->print('- '.&mt('Outdated copy removed'));
+ }
+ $r->rflush();
+ &Apache::lonnet::countacc($url);
+ $url=~/\.(\w+)$/;
+ if (&Apache::loncommon::fileembstyle($1) eq 'ssi') {
+ $r->print('
');
+ $r->rflush();
+ for (my $i=0;$i<=$level*5;$i++) {
+ $r->print(' ');
+ }
+ $r->print('- '.&mt('Rendering:').' ');
+ my ($errorcount,$warningcount)=split(/:/,
+ &Apache::lonnet::ssi_body($url,
+ ('grade_target'=>'web',
+ 'return_only_error_and_warning_counts' => 1)));
+ if (($errorcount) ||
+ ($warningcount)) {
+ if ($errorcount) {
+ $r->print('
'.
+ &mt('[quant,_1,error]',$errorcount).'');
+ }
+ if ($warningcount) {
+ $r->print('
'.
+ &mt('[quant,_1,warning]',$warningcount).'');
+ }
+ } else {
+ $r->print('
'.&mt('ok').'');
+ }
+ $r->rflush();
+ }
+ my $dependencies=
+ &Apache::lonnet::metadata($url,'dependencies');
+ foreach my $dep (split(/\,/,$dependencies)) {
+ if (($dep=~/^\/res\//) && (!$alreadyseen{$dep})) {
+ &checkonthis($r,$dep,$level+1,'',$checkstale);
+ }
+ }
+ } elsif ($result eq 'unavailable') {
+ $r->print('
'.&mt('connection down').'');
+ } elsif ($result eq 'not_found') {
+ unless ($url=~/\$/) {
+ $r->print('
'.&mt('not found').'');
+ } else {
+ $r->print('
'.&mt('unable to verify variable URL').'');
+ }
+ } else {
+ $r->print('
'.&mt('access denied').'');
+ }
+ if (($updated) && ($result ne 'ok')) {
+ $r->print('
'.&mt('Outdated copy removed'));
+ }
+ }
+ }
+}
+
+
+
+=pod
+
+=item list_symbs()
+
+List Content Identifiers
+
+=cut
+
+sub list_symbs {
+ my ($r) = @_;
+
+ my $crstype = &Apache::loncommon::course_type();
+ $r->print(&Apache::loncommon::start_page('List of Content Identifiers'));
+ $r->print(&Apache::lonhtmlcommon::breadcrumbs('Content Identifiers'));
+ $r->print(&startContentScreen('tools'));
+ my $navmap = Apache::lonnavmaps::navmap->new();
+ if (!defined($navmap)) {
+ $r->print('
'.&mt('Retrieval of List Failed').'
'.
+ '
'.
+ &mt('Unable to retrieve information about course contents').
+ '
');
+ &Apache::lonnet::logthis('Symb list failed - could not create navmap object in '.lc($crstype).':'.$env{'request.course.id'});
+ } else {
+ $r->print('
'.&mt("$crstype Content Identifiers").'
'.
+ &Apache::loncommon::start_data_table().
+ &Apache::loncommon::start_data_table_header_row().
+ '
'.&mt('Title').' | '.&mt('Identifier').' | '.
+ &Apache::loncommon::end_data_table_header_row()."\n");
+ my $count;
+ foreach my $res ($navmap->retrieveResources()) {
+ $r->print(&Apache::loncommon::start_data_table_row().
+ '
'.$res->compTitle().' | '.
+ '
'.$res->symb().' | '.
+ &Apache::loncommon::end_data_table_row());
+ $count ++;
+ }
+ if (!$count) {
+ $r->print(&Apache::loncommon::start_data_table_row().
+ '
'.&mt("$crstype is empty").' | '.
+ &Apache::loncommon::end_data_table_row());
+ }
+ $r->print(&Apache::loncommon::end_data_table());
+ }
+ $r->print(&endContentScreen());
+}
+
+sub short_urls {
+ my ($r,$canedit) = @_;
+ my $crstype = &Apache::loncommon::course_type();
+ my $formname = 'shortenurl';
+ $r->print(&Apache::loncommon::start_page('Display/Set Shortened URLs'));
+ $r->print(&Apache::lonhtmlcommon::breadcrumbs('Shortened URLs'));
+ $r->print(&startContentScreen('tools'));
+ my ($navmap,$errormsg) =
+ &Apache::loncourserespicker::get_navmap_object($crstype,'shorturls');
+ my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
+ my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
+ my (%maps,%resources,%titles);
+ if (!ref($navmap)) {
+ $r->print($errormsg.
+ &endContentScreen());
+ return '';
+ } else {
+ $r->print('
'.&mt('Tiny URLs for deep-linking into course').'
'."\n");
+ $r->rflush();
+ my $readonly;
+ if ($canedit) {
+ my ($numnew,$errors) = &Apache::loncommon::get_requested_shorturls($cdom,$cnum,$navmap);
+ if ($numnew) {
+ $r->print('
'.&mt('Created [quant,_1,URL]',$numnew).'
');
+ }
+ if ((ref($errors) eq 'ARRAY') && (@{$errors} > 0)) {
+ $r->print(&mt('The following errors occurred when processing your request to create shortened URLs:').'
');
+ foreach my $error (@{$errors}) {
+ $r->print('- '.$error.'
');
+ }
+ $r->print('
');
+ }
+ } else {
+ $readonly = 1;
+ }
+ my %currtiny = &Apache::lonnet::dump('tiny',$cdom,$cnum);
+ $r->print(&Apache::loncourserespicker::create_picker($navmap,'shorturls',$formname,$crstype,undef,
+ undef,undef,undef,undef,undef,\%currtiny,undef,$readonly));
+ }
+ $r->print(&endContentScreen());
+}
+
+sub contentverifyform {
+ my ($r) = @_;
+ my $crstype = &Apache::loncommon::course_type();
+ $r->print(&Apache::loncommon::start_page('Verify '.$crstype.' Content'));
+ $r->print(&Apache::lonhtmlcommon::breadcrumbs('Verify '.$crstype.' Content'));
+ $r->print(&startContentScreen('tools'));
+ $r->print('
'.&mt($crstype.' content verification').'
');
+ $r->print('
');
+ $r->print(&endContentScreen());
+ return;
+}
+
+sub verifycontent {
+ my ($r,$checkstale) = @_;
+ my $crstype = &Apache::loncommon::course_type();
+ $r->print(&Apache::loncommon::start_page('Verify '.$crstype.' Content'));
+ $r->print(&Apache::lonhtmlcommon::breadcrumbs('Verify '.$crstype.' Content'));
+ $r->print(&startContentScreen('tools'));
+ $r->print('
'.&mt($crstype.' content verification').'
');
+ $hashtied=0;
+ undef %alreadyseen;
+ %alreadyseen=();
+ &tiehash();
+
+ foreach my $key (keys(%hash)) {
+ if ($hash{$key}=~/\.(page|sequence)$/) {
+ if (($key=~/^src_/) && ($alreadyseen{&unescape($hash{$key})})) {
+ $r->print('
'.
+ &mt('The following sequence or page is included more than once in your '.$crstype.':').' '.
+ &unescape($hash{$key}).''.
+ &mt('Note that grading records for problems included in this sequence or folder will overlap.').'
');
+ }
+ }
+ if (($key=~/^src\_(.+)$/) && (!$alreadyseen{&unescape($hash{$key})})) {
+ &checkonthis($r,$hash{$key},0,$hash{'title_'.$1},$checkstale);
+ }
+ }
+ &untiehash();
+ $r->print('
'.&mt('Done').'
');
+ $r->print(&endContentScreen());
+}
+
+sub devalidateversioncache {
+ my $src=shift;
+ &Apache::lonnet::devalidate_cache_new('courseresversion',$env{'request.course.id'}.'_'.
+ &Apache::lonnet::clutter($src));
+}
+
+sub checkversions {
+ my ($r,$canedit) = @_;
+ my $crstype = &Apache::loncommon::course_type();
+ $r->print(&Apache::loncommon::start_page("Check $crstype Resource Versions"));
+ $r->print(&Apache::lonhtmlcommon::breadcrumbs("Check $crstype Resource Versions"));
+ $r->print(&startContentScreen('tools'));
+
+ my $header='';
+ my $startsel='';
+ my $monthsel='';
+ my $weeksel='';
+ my $daysel='';
+ my $allsel='';
+ my %changes=();
+ my $starttime=0;
+ my $haschanged=0;
+ my %setversions=&Apache::lonnet::dump('resourceversions',
+ $env{'course.'.$env{'request.course.id'}.'.domain'},
+ $env{'course.'.$env{'request.course.id'}.'.num'});
+
+ $hashtied=0;
+ &tiehash();
+ if ($canedit) {
+ my %newsetversions=();
+ if ($env{'form.setmostrecent'}) {
+ $haschanged=1;
+ foreach my $key (keys(%hash)) {
+ if ($key=~/^ids\_(\/res\/.+)$/) {
+ $newsetversions{$1}='mostrecent';
+ &devalidateversioncache($1);
+ }
+ }
+ } elsif ($env{'form.setcurrent'}) {
+ $haschanged=1;
+ foreach my $key (keys(%hash)) {
+ if ($key=~/^ids\_(\/res\/.+)$/) {
+ my $getvers=&Apache::lonnet::getversion($1);
+ if ($getvers>0) {
+ $newsetversions{$1}=$getvers;
+ &devalidateversioncache($1);
+ }
+ }
+ }
+ } elsif ($env{'form.setversions'}) {
+ $haschanged=1;
+ foreach my $key (keys(%env)) {
+ if ($key=~/^form\.set_version_(.+)$/) {
+ my $src=$1;
+ if (($env{$key}) && ($env{$key} ne $setversions{$src})) {
+ $newsetversions{$src}=$env{$key};
+ &devalidateversioncache($src);
+ }
+ }
+ }
+ }
+ if ($haschanged) {
+ if (&Apache::lonnet::put('resourceversions',\%newsetversions,
+ $env{'course.'.$env{'request.course.id'}.'.domain'},
+ $env{'course.'.$env{'request.course.id'}.'.num'}) eq 'ok') {
+ $r->print(&Apache::loncommon::confirmwrapper(
+ &Apache::lonhtmlcommon::confirm_success(&mt('Your Version Settings have been Saved'))));
+ } else {
+ $r->print(&Apache::loncommon::confirmwrapper(
+ &Apache::lonhtmlcommon::confirm_success(&mt('An Error Occured while Attempting to Save your Version Settings'),1)));
+ }
+ &mark_hash_old();
+ }
+ &changewarning($r,'');
+ }
+ if ($env{'form.timerange'} eq 'all') {
+# show all documents
+ $header=&mt('All content in '.$crstype);
+ $allsel=' selected="selected"';
+ foreach my $key (keys(%hash)) {
+ if ($key=~/^ids\_(\/res\/.+)$/) {
+ my $src=$1;
+ $changes{$src}=1;
+ }
+ }
+ } else {
+# show documents which changed
+ %changes=&Apache::lonnet::dump
+ ('versionupdate',$env{'course.'.$env{'request.course.id'}.'.domain'},
+ $env{'course.'.$env{'request.course.id'}.'.num'});
+ my $firstkey=(keys(%changes))[0];
+ unless ($firstkey=~/^error\:/) {
+ unless ($env{'form.timerange'}) {
+ $env{'form.timerange'}=604800;
+ }
+ my $seltext=&mt('during the last').' '.$env{'form.timerange'}.' '
+ .&mt('seconds');
+ if ($env{'form.timerange'}==-1) {
+ $seltext='since start of course';
+ $startsel=' selected="selected"';
+ $env{'form.timerange'}=time;
+ }
+ $starttime=time-$env{'form.timerange'};
+ if ($env{'form.timerange'}==2592000) {
+ $seltext=&mt('during the last month').' ('.&Apache::lonlocal::locallocaltime($starttime).')';
+ $monthsel=' selected="selected"';
+ } elsif ($env{'form.timerange'}==604800) {
+ $seltext=&mt('during the last week').' ('.&Apache::lonlocal::locallocaltime($starttime).')';
+ $weeksel=' selected="selected"';
+ } elsif ($env{'form.timerange'}==86400) {
+ $seltext=&mt('since yesterday').' ('.&Apache::lonlocal::locallocaltime($starttime).')';
+ $daysel=' selected="selected"';
+ }
+ $header=&mt('Content changed').' '.$seltext;
+ } else {
+ $header=&mt('No content modifications yet.');
+ }
+ }
+ %setversions=&Apache::lonnet::dump('resourceversions',
+ $env{'course.'.$env{'request.course.id'}.'.domain'},
+ $env{'course.'.$env{'request.course.id'}.'.num'});
+ my %lt=&Apache::lonlocal::texthash
+ ('st' => 'Version changes since start of '.$crstype,
+ 'lm' => 'Version changes since last Month',
+ 'lw' => 'Version changes since last Week',
+ 'sy' => 'Version changes since Yesterday',
+ 'al' => 'All Resources (possibly large output)',
+ 'cd' => 'Change display',
+ 'sd' => 'Display',
+ 'fi' => 'File',
+ 'md' => 'Modification Date',
+ 'mr' => 'Most recently published Version',
+ 've' => 'Version used in '.$crstype,
+ 'vu' => 'Set Version to be used in '.$crstype,
+'sv' => 'Set Versions to be used in '.$crstype.' according to Selections below',
+'sm' => 'Keep all Resources up-to-date with most recent Versions (default)',
+'sc' => 'Set all Resource Versions to current Version (Fix Versions)',
+ 'di' => 'Differences',
+ 'save' => 'Save changes',
+ 'vers' => 'Version choice(s) for specific resources',
+ 'act' => 'Actions');
+ my ($disabled,$readonly);
+ unless ($canedit) {
+ $disabled = 'disabled="disabled"';
+ $readonly = 1;
+ }
+ $r->print(<
$header
+'
+ );
+
+ &untiehash();
+ $r->print(&endContentScreen());
+ return;
+}
+
+sub mark_hash_old {
+ my $retie_hash=0;
+ if ($hashtied) {
+ $retie_hash=1;
+ &untiehash();
+ }
+ &tiehash('write');
+ $hash{'old'}=1;
+ &untiehash();
+ if ($retie_hash) { &tiehash(); }
+}
+
+sub is_hash_old {
+ my $untie_hash=0;
+ if (!$hashtied) {
+ $untie_hash=1;
+ &tiehash();
+ }
+ my $return=$hash{'old'};
+ if ($untie_hash) { &untiehash(); }
+ return $return;
+}
+
+sub changewarning {
+ my ($r,$postexec,$message,$url)=@_;
+ if (!&is_hash_old()) { return; }
+ my $pathvar='folderpath';
+ my $path=&escape($env{'form.folderpath'});
+ if (!defined($url)) {
+ $url='/adm/coursedocs?'.$pathvar.'='.$path;
+ }
+ my $course_type = &Apache::loncommon::course_type();
+ if (!defined($message)) {
+ $message='Changes will become active for your current session after [_1], or the next time you log in.';
+ }
+ my $windowname = 'loncapaclient';
+ if ($env{'request.lti.login'}) {
+ $windowname .= 'lti';
+ }
+ $r->print("\n\n".
+''."\n".
+''."\n\n");
+}
+
+
+sub init_breadcrumbs {
+ my ($form,$text,$help)=@_;
+ &Apache::lonhtmlcommon::clear_breadcrumbs();
+ &Apache::lonhtmlcommon::add_breadcrumb({href=>"/adm/coursedocs?tools=1",
+ text=>&Apache::loncommon::course_type().' Editor',
+ faq=>273,
+ bug=>'Instructor Interface',
+ help => $help});
+ &Apache::lonhtmlcommon::add_breadcrumb({href=>"/adm/coursedocs?".$form.'=1',
+ text=>$text,
+ faq=>273,
+ bug=>'Instructor Interface'});
+}
+
+# subroutine to list form elements
+sub create_list_elements {
+ my @formarr = @_;
+ my $list = '';
+ foreach my $button (@formarr){
+ foreach my $picture (keys(%{$button})) {
+ $list .= &Apache::lonhtmlcommon::htmltag('li', $picture.' '.$button->{$picture}, {class => 'LC_menubuttons_inline_text', id => ''});
+ }
+ }
+ return $list;
+}
+
+# subroutine to create ul from list elements
+sub create_form_ul {
+ my $list = shift;
+ my $ul = &Apache::lonhtmlcommon::htmltag('ul',$list, {class => 'LC_ListStyleNormal'});
+ return $ul;
+}
+
+#
+# Start tabs
+#
+
+sub startContentScreen {
+ my ($mode) = @_;
+ my $output = '';
+ if (($mode eq 'navmaps') || ($mode eq 'supplemental')) {
+ $output .= '- '.&mt('Content Overview').'
'."\n";
+ $output .= '- '.&mt('Content Search').'
'."\n";
+ $output .= '- '.&mt('Content Index').'
'."\n";
+ $output .= '- '.&mt('Supplemental Content').'
';
+ } else {
+ $output .= '- '.&mt('Main Content Editor').'
'."\n";
+ $output .= '- '.&mt('Supplemental Content Editor').'
'."\n";
+ $output .= '- '.&mt('Content Utilities').'
'."\n";
+ '> '.&mt('Content Utilities').' ';
+ }
+ $output .= "\n".'
'."\n";
+ $output .= ''.
+ '
'.
+ '
';
+ return $output;
+}
+
+#
+# End tabs
+#
+
+sub endContentScreen {
+ return '
';
+}
+
+sub supplemental_base {
+ return 'supplemental&'.&escape(&mt('Supplemental Content'));
+}
+
+sub handler {
+ my $r = shift;
+ &Apache::loncommon::content_type($r,'text/html');
+ $r->send_http_header;
+ return OK if $r->header_only;
+
+# get course data
+ my $crstype = &Apache::loncommon::course_type();
+ my $coursenum=$env{'course.'.$env{'request.course.id'}.'.num'};
+ my $coursedom=$env{'course.'.$env{'request.course.id'}.'.domain'};
+ my $coursehome=$env{'course.'.$env{'request.course.id'}.'.home'};
+
+# get docroot
+ my $londocroot = $r->dir_config('lonDocRoot');
+
+# graphics settings
+ $iconpath = &Apache::loncommon::lonhttpdurl($r->dir_config('lonIconsURL').'/');
+
+#
+# --------------------------------------------- Initialize help topics for this
+ foreach my $topic ('Adding_Course_Doc','Main_Course_Documents',
+ 'Adding_External_Resource','Adding_External_Tool',
+ 'Navigate_Content','Adding_Folders','Docs_Overview',
+ 'Load_Map','Supplemental','Score_Upload_Form',
+ 'Adding_Pages','Importing_LON-CAPA_Resource',
+ 'Importing_IMS_Course','Uploading_From_Harddrive',
+ 'Course_Roster','Web_Page','Dropbox','Simple_Problem',
+ 'Standard_Problem','Course_Resources',
+ 'Search_LON-CAPA_Resource','Import_Stored_Links') {
+ $help{$topic}=&Apache::loncommon::help_open_topic('Docs_'.$topic);
+ }
+ # Composite help files
+ $help{'Syllabus'} = &Apache::loncommon::help_open_topic(
+ 'Docs_About_Syllabus,Docs_Editing_Templated_Pages');
+ $help{'Simple Page'} = &Apache::loncommon::help_open_topic(
+ 'Docs_About_Simple_Page,Docs_Editing_Templated_Pages');
+ $help{'Bulletin Board'} = &Apache::loncommon::help_open_topic(
+ 'Docs_About_Bulletin_Board,Docs_Editing_Templated_Pages');
+ $help{'My Personal Information Page'} = &Apache::loncommon::help_open_topic(
+ 'Docs_About_My_Personal_Info,Docs_Editing_Templated_Pages');
+ $help{'Group Portfolio'} = &Apache::loncommon::help_open_topic('Docs_About_Group_Files');
+ $help{'Caching'} = &Apache::loncommon::help_open_topic('Caching');
+
+ my ($allowed,$canedit,$canview,$noendpage,$disabled);
+# does this user have privileges to modify content.
+ if (&Apache::lonnet::allowed('mdc',$env{'request.course.id'})) {
+# URI is /adm/supplemental when viewing supplemental docs in non-edit mode.
+ unless ($r->uri eq '/adm/supplemental') {
+ $allowed = 1;
+ }
+ $canedit = 1;
+ $canview = 1;
+ } elsif (&Apache::lonnet::allowed('cev',$env{'request.course.id'})) {
+# URI is /adm/supplemental when viewing supplemental docs in non-edit mode.
+ unless ($r->uri eq '/adm/supplemental') {
+ $allowed = 1;
+ }
+ $canview = 1;
+ }
+ unless ($canedit) {
+ $disabled = ' disabled="disabled"';
+ }
+ &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},['inhibitmenu']);
+ if ($env{'form.inhibitmenu'}) {
+ unless ($env{'form.inhibitmenu'} eq 'yes') {
+ delete($env{'form.inhibitmenu'});
+ }
+ }
+
+ if ($allowed && $env{'form.verify'}) {
+ &init_breadcrumbs('verify','Verify Content','Docs_Verify_Content');
+ if (!$canedit) {
+ &verifycontent($r);
+ } elsif (($env{'form.checkstale'} ne '') && ($env{'form.checkstale'} =~ /^\d$/)) {
+ &Apache::lonhtmlcommon::add_breadcrumb({href=>"/adm/coursedocs?tools=1&verify=1&checkstale=$env{'form.checkstale'}",
+ text=>'Results',
+ faq=>273,
+ bug=>'Instructor Interface'});
+ &verifycontent($r,$env{'form.checkstale'});
+ } else {
+ &contentverifyform($r);
+ }
+ } elsif ($allowed && $env{'form.listsymbs'}) {
+ &init_breadcrumbs('listsymbs','List Content IDs');
+ &list_symbs($r);
+ } elsif ($allowed && $env{'form.shorturls'}) {
+ &init_breadcrumbs('shorturls','Set/Display Shortened URLs','Docs_Short_URLs');
+ &short_urls($r,$canedit);
+ } elsif ($allowed && $env{'form.docslog'}) {
+ &init_breadcrumbs('docslog','Show Log');
+ my $folder = $env{'form.folder'};
+ if ($folder eq '') {
+ $folder='default';
+ }
+ &docs_change_log($r,$coursenum,$coursedom,$folder,$allowed,$crstype,$iconpath,$canedit);
+ } elsif ($allowed && $env{'form.versions'}) {
+ &init_breadcrumbs('versions','Check/Set Resource Versions','Docs_Check_Resource_Versions');
+ &checkversions($r,$canedit);
+ } elsif ($canedit && $env{'form.dumpcourse'}) {
+ &init_breadcrumbs('dumpcourse','Copy uploaded content to Authoring Space');
+ &dumpcourse($r);
+ } elsif (($canedit || $canview) && ($env{'form.copyauthored'})) {
+ &init_breadcrumbs('copyauthored','Copy from Course Authoring to User Authoring');
+ my $readonly;
+ if (!$canedit) {
+ $readonly = 1;
+ }
+ ©crsauthored($r,$coursenum,$coursedom,$coursehome,$readonly);
+ } elsif ($canedit && $env{'form.exportcourse'}) {
+ &init_breadcrumbs('exportcourse','IMS Export');
+ &Apache::imsexport::exportcourse($r);
+ } else {
+ if ($canedit && $env{'form.authorrole'}) {
+ $noendpage = 1;
+ my ($redirect,$error) = &makenewproblem($r,$coursedom,$coursenum);
+ if ($redirect) {
+ if (($env{'form.newresourceadd'}) && ($env{'form.folderpath'})) {
+ my $container = 'sequence';
+ my ($breadcrumbtrail,$randompick,$ishidden,$isencrypted,$plain,
+ $is_random_order,$container) =
+ &Apache::lonhtmlcommon::docs_breadcrumbs($allowed,$crstype,1);
+ my (@folders)=split('&',$env{'form.folderpath'});
+ $env{'form.foldername'}=&unescape(pop(@folders));
+ my $folder=pop(@folders);
+ my ($errtext,$fatal) = &mapread($coursenum,$coursedom,
+ $folder.'.'.$container);
+ my $warning;
+ if ($fatal) {
+ if ($container eq 'page') {
+ $warning = &mt('An error occurred retrieving the contents of the current page.');
+ } else {
+ $warning = &mt('An error occurred retrieving the contents of the current folder.');
+ }
+ } else {
+ my $url = $redirect;
+ my $srcfile = $londocroot.$url;
+ $url =~ s{^/priv/}{/res/};
+ my $targetfile = $londocroot.$url;
+ my $nokeyref = &Apache::lonpublisher::getnokey($r->dir_config('lonIncludes'));
+ my $output = &Apache::lonpublisher::batchpublish($r,$srcfile,$targetfile,$nokeyref,1);
+ $env{'form.folder'} = $folder;
+ &snapshotbefore();
+ my $title = &LONCAPA::map::qtunescape($env{'form.newresourcetitle'});
+ my $ext = 'false';
+ my $newidx = &LONCAPA::map::getresidx(&LONCAPA::map::qtunescape($url));
+ $LONCAPA::map::resources[$newidx]=$title.':'.&LONCAPA::map::qtunescape($url).
+ ':'.$ext.':normal:res';
+ push(@LONCAPA::map::order,$newidx);
+ &LONCAPA::map::storeparameter($newidx,'parameter_hiddenresource','yes',
+ 'string_yesno');
+ &remember_parms($newidx,'hiddenresource','set','yes');
+ ($errtext,$fatal) =
+ &storemap($coursenum, $coursedom, $folder.'.'.$container,1);
+ &log_differences($plain);
+ &mark_hash_old();
+ $r->internal_redirect($redirect);
+ return OK;
+ }
+ } else {
+ $r->internal_redirect($redirect);
+ }
+ }
+ }
+#
+# Done catching special calls
+# The whole rest is for course and supplemental documents and utilities menu
+# Get the parameters that may be needed
+#
+ &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
+ ['folderpath','title',
+ 'forcesupplement','forcestandard',
+ 'tools','symb','command','supppath']);
+
+ foreach my $item ('forcesupplement','forcestandard','tools') {
+ next if ($env{'form.'.$item} eq '');
+ unless ($env{'form.'.$item} eq '1') {
+ delete($env{'form.'.$item});
+ }
+ }
+
+ if ($env{'form.command'}) {
+ unless ($env{'form.command'} =~ /^(direct|directnav|editdocs|editsupp|contents|home)$/) {
+ delete($env{'form.command'});
+ }
+ }
+
+ if ($env{'form.symb'}) {
+ my ($mapurl,$id,$resurl) = &Apache::lonnet::decode_symb($env{'form.symb'});
+ unless (($id =~ /^\d+$/) && (&Apache::lonnet::is_on_map($resurl))) {
+ delete($env{'form.symb'});
+ }
+ }
+
+# standard=1: this is a "new-style" course with an uploaded map as top level
+# standard=2: this is a "old-style" course, and there is nothing we can do
+
+ my $standard=($env{'request.course.uri'}=~/^\/uploaded\//);
+
+# Decide whether this should display supplemental or main content or utilities
+# supplementalflag=1: show supplemental documents
+# supplementalflag=0: show standard documents
+# toolsflag=1: show utilities
+
+ my $unesc_folderpath = &unescape($env{'form.folderpath'});
+ my $supplementalflag=($unesc_folderpath=~/^supplemental/);
+ if (($unesc_folderpath=~/^default/) || ($unesc_folderpath eq "")) {
+ $supplementalflag=0;
+ }
+ if ($env{'form.forcesupplement'}) { $supplementalflag=1; }
+ if ($env{'form.forcestandard'}) { $supplementalflag=0; }
+ unless (($supplementalflag) ||
+ ($r->uri =~ m{^/adm/coursedocs/showdoc/uploaded/\Q$coursedom\E/\Q$coursenum\E/docs/})) {
+ unless ($allowed) { $supplementalflag=1; }
+ unless ($standard) { $supplementalflag=1; }
+ }
+ my $toolsflag=0;
+ if ($env{'form.tools'}) { $toolsflag=1; }
+
+ if ($env{'form.folderpath'} ne '') {
+ &Apache::loncommon::validate_folderpath($supplementalflag,$allowed,$coursenum,$coursedom);
+ }
+
+ my $backto_supppath;
+ if ($env{'form.supppath'} ne '') {
+ if ($supplementalflag && $allowed) {
+ $backto_supppath = &validate_supppath($coursenum,$coursedom);
+ }
+ }
+
+ my $script='';
+ my $showdoc=0;
+ my $addentries = {};
+ my $container;
+ my $containertag;
+ my $pathitem;
+ my %ltitools;
+ my $posslti;
+ my $hiddentop;
+ my $navmap;
+ my $filterFunc = sub { my $res = shift; return (!$res->randomout() && !$res->is_map()) };
+
+# Do we directly jump somewhere?
+ if (($env{'form.command'} eq 'direct') || ($env{'form.command'} eq 'directnav')) {
+ if ($env{'form.symb'} ne '') {
+ $env{'form.folderpath'}=
+ &Apache::loncommon::symb_to_docspath($env{'form.symb'},\$navmap);
+ &Apache::lonnet::appenv({'docs.exit.'.$env{'request.course.id'} =>
+ $env{'form.command'}.'_'.$env{'form.symb'}});
+ } elsif (($env{'form.supppath'} ne '') && $supplementalflag && $allowed) {
+ $env{'form.folderpath'}=$env{'form.supppath'};
+ &Apache::lonnet::appenv({'docs.exit.'.$env{'request.course.id'} =>
+ $env{'form.command'}.'_'.$backto_supppath});
+ }
+ } elsif ($env{'form.command'} eq 'editdocs') {
+ $env{'form.folderpath'} = &default_folderpath($coursenum,$coursedom,\$navmap);
+ &Apache::lonnet::appenv({'docs.exit.'.$env{'request.course.id'} => $env{'form.command'}});
+ } elsif ($env{'form.command'} eq 'editsupp') {
+ $env{'form.folderpath'} = &supplemental_base();
+ &Apache::lonnet::appenv({'docs.exit.'.$env{'request.course.id'} => '/adm/supplemental'});
+ } elsif ($env{'form.command'} eq 'contents') {
+ &Apache::lonnet::appenv({'docs.exit.'.$env{'request.course.id'} => '/adm/navmaps'});
+ } elsif ($env{'form.command'} eq 'home') {
+ &Apache::lonnet::appenv({'docs.exit.'.$env{'request.course.id'} => '/adm/menu'});
+ }
+
+
+# Where do we store these for when we come back?
+ my $stored_folderpath='docs_folderpath';
+ if ($supplementalflag) {
+ $stored_folderpath='docs_sup_folderpath';
+ }
+
+# No folderpath, and in edit mode, see if we have something stored
+ if ((!$env{'form.folderpath'}) && $allowed) {
+ &Apache::loncommon::restore_course_settings($stored_folderpath,
+ {'folderpath' => 'scalar'});
+
+ if (&unescape($env{'form.folderpath'}) =~ m{^(default|supplemental)&}) {
+ if ($supplementalflag) {
+ undef($env{'form.folderpath'}) if ($1 eq 'default');
+ } else {
+ undef($env{'form.folderpath'}) if ($1 eq 'supplemental');
+ }
+ } else {
+ undef($env{'form.folderpath'});
+ }
+ if ($env{'form.folderpath'} ne '') {
+ &Apache::loncommon::validate_folderpath($supplementalflag,$allowed,$coursenum,$coursedom);
+ }
+ }
+
+# Set folderpath if we are not allowed to make changes and this is supplemental content
+ if ((!$allowed) && ($supplementalflag)) {
+ unless ($env{'form.folderpath'} =~ /^supplemental/) {
+ $env{'form.folderpath'} = &supplemental_base();
+ }
+ }
+# Make the zeroth entry in supplemental docs page paths, so we can get to top level
+ if ($env{'form.folderpath'} =~ /^supplemental_\d+/) {
+ $env{'form.folderpath'} = &supplemental_base()
+ .'&'.
+ $env{'form.folderpath'};
+ }
+# If allowed and user's role is not advanced check folderpath is not hidden
+ my $hidden_and_empty;
+ if (($allowed) && (!$env{'request.role.adv'}) && ($env{'form.folderpath'} ne '')) {
+ my ($folderurl,$foldername,$hiddenfolder);
+ my @pathitems = split(/\&/,$env{'form.folderpath'});
+ my $folder = $pathitems[-2];
+ if ($folder eq '') {
+ undef($env{'form.folderpath'});
+ } else {
+ $folderurl = "uploaded/$coursedom/$coursenum/$folder";
+ if ((split(/\:/,$pathitems[-1]))[5]) {
+ $folderurl .= '.page';
+ } else {
+ $folderurl .= '.sequence';
+ }
+ if ($supplementalflag) {
+ ($foldername,$hiddenfolder) = ($pathitems[-1] =~ /^([^:]*)::(|1):::$/);
+ $foldername = &HTML::Entities::decode(&unescape($foldername));
+ my ($supplemental) = &Apache::loncommon::get_supplemental($coursenum,$coursedom);
+ if (ref($supplemental) eq 'HASH') {
+ my ($suppmap,$suppmapnum);
+ if ($folder eq 'supplemental') {
+ $suppmap = 'default';
+ $suppmapnum = 0;
+ } elsif ($folder =~ /^supplemental_(\d+)$/) {
+ $suppmap = $1;
+ $suppmapnum = $suppmap;
+ }
+ if ($hiddenfolder) {
+ my $hascontent;
+ foreach my $key (reverse(sort(keys(%{$supplemental->{'ids'}})))) {
+ if ($key =~ m{^\Q/uploaded/$coursedom/$coursenum/supplemental/$suppmap/\E}) {
+ $hascontent = 1;
+ } elsif (ref($supplemental->{'ids'}->{$key}) eq 'ARRAY') {
+ foreach my $id (@{$supplemental->{'ids'}->{$key}}) {
+ if ($id =~ /^$suppmapnum\:/) {
+ $hascontent = 1;
+ last;
+ }
+ }
+ }
+ last if ($hascontent);
+ }
+ unless ($hascontent) {
+ if ($foldername ne '') {
+ $hidden_and_empty = $foldername;
+ } else {
+ $hidden_and_empty = $folder;
+ }
+ }
+ }
+ }
+ } else {
+ unless (ref($navmap)) {
+ $navmap = Apache::lonnavmaps::navmap->new();
+ }
+ ($foldername,$hiddenfolder) = ($pathitems[-1] =~ /^([^:]*):|\d+:|1:(|1):|1:|1$/);
+ $foldername = &HTML::Entities::decode(&unescape($foldername));
+ if (ref($navmap)) {
+ if ($hiddenfolder ||
+ (lc($navmap->get_mapparam(undef,$folderurl,"0.hiddenresource")) eq 'yes')) {
+ my @resources = $navmap->retrieveResources($folderurl,$filterFunc,1,1);
+ unless (@resources) {
+ if ($foldername ne '') {
+ $hidden_and_empty = $foldername;
+ } else {
+ $hidden_and_empty = $folder;
+ }
+ }
+ }
+ }
+ }
+ if ($hidden_and_empty ne '') {
+ splice(@pathitems,-2);
+ if (@pathitems) {
+ $env{'form.folderpath'} = join('&',@pathitems);
+ } else {
+ undef($env{'form.folderpath'});
+ }
+ }
+ }
+ }
+
+# If after all of this, we still don't have any paths, make them
+ unless ($env{'form.folderpath'}) {
+ if ($supplementalflag) {
+ $env{'form.folderpath'}=&supplemental_base();
+ } elsif ($allowed) {
+ ($env{'form.folderpath'},$hiddentop) = &default_folderpath($coursenum,$coursedom,\$navmap);
+ }
+ }
+
+# Store this
+ unless ($toolsflag) {
+ if (($allowed) && ($env{'form.folderpath'} ne '')) {
+ &Apache::loncommon::store_course_settings($stored_folderpath,
+ {'folderpath' => 'scalar'});
+ }
+ my $folderpath;
+ if ($env{'form.folderpath'}) {
+ $folderpath = $env{'form.folderpath'};
+ my (@folders)=split('&',$env{'form.folderpath'});
+ $env{'form.foldername'}=&unescape(pop(@folders));
+ if ($env{'form.foldername'} =~ /\:1$/) {
+ $container = 'page';
+ } else {
+ $container = 'sequence';
+ }
+ $env{'form.folder'}=pop(@folders);
+ } else {
+ if ($env{'form.folder'} eq '' ||
+ $env{'form.folder'} eq 'supplemental') {
+ if ($env{'form.folder'} eq 'supplemental') {
+ $folderpath=&supplemental_base();
+ } elsif (!$hiddentop) {
+ $folderpath='default&'.
+ &escape(&mt('Main Content').':::::');
+ }
+ }
+ }
+ $containertag = '';
+ $pathitem = '';
+ if ($r->uri=~/^\/adm\/coursedocs\/showdoc\/(.*)$/) {
+ $showdoc='/'.$1;
+ }
+ if ($showdoc) { # got called in sequence from course
+ $allowed=0;
+ } else {
+ if ($canedit) {
+ &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},['cmd']);
+ $script=&Apache::lonratedt::editscript('simple');
+ }
+ }
+ }
+
+# get personal data
+ my $uname=$env{'user.name'};
+ my $udom=$env{'user.domain'};
+ my $plainname=&escape(&Apache::loncommon::plainname($uname,$udom));
+
+ if ($allowed) {
+ if ($toolsflag) {
+ $script .= &inject_data_js();
+ my ($home,$other,%outhash)=&authorhosts();
+ if (!$home && $other) {
+ my @hosts;
+ foreach my $aurole (keys(%outhash)) {
+ unless(grep(/^\Q$outhash{$aurole}\E/,@hosts)) {
+ push(@hosts,$outhash{$aurole});
+ }
+ }
+ $script .= &dump_switchserver_js(@hosts);
+ }
+ } else {
+ my $tid = 1;
+ my @tabids;
+ if ($supplementalflag) {
+ @tabids = ('002','dd2','ee2','ff2');
+ $tid = 2;
+ } else {
+ @tabids = ('aa1','bb1','cc1','ff1');
+ unless ($env{'form.folderpath'} =~ /\:1$/) {
+ unshift(@tabids,'001');
+ push(@tabids,('dd1','ee1'));
+ }
+ }
+ my $tabidstr = join("','",@tabids);
+ my (%domtools,%crstools);
+ my %tooltypes = &Apache::loncommon::usable_exttools();
+ if ($tooltypes{'dom'}) {
+ %domtools = &Apache::lonnet::get_domain_lti($coursedom,'consumer');
+ }
+ if ($tooltypes{'crs'}) {
+ %crstools = &Apache::lonnet::get_course_lti($coursenum,$coursedom,'consumer');
+ }
+ %ltitools = (
+ dom => \%domtools,
+ crs => \%crstools,
+ );
+ $posslti = scalar(keys(%domtools)) + scalar(keys(%crstools));
+ my $hostname = $r->hostname();
+ $script .= &editing_js($udom,$uname,$supplementalflag,$coursedom,$coursenum,$posslti,
+ $londocroot,$canedit,$hostname,\$navmap).
+ &history_tab_js().
+ &inject_data_js().
+ &Apache::lonhtmlcommon::resize_scrollbox_js('docs',$tabidstr,$tid).
+ &Apache::lonextresedit::extedit_javascript(\%ltitools);
+ my $onload = "javascript:resize_scrollbox('contentscroll','1','1');";
+ if ($hidden_and_empty ne '') {
+ my $alert = &mt("Additional privileges required to edit empty and hidden folder: '[_1]'",
+ $hidden_and_empty);
+ $onload .= "javascript:alert('".&js_escape($alert)."');";
+ }
+ $addentries = {
+ onload => $onload,
+ };
+ }
+ $script .= &paste_popup_js();
+ my $confirm_switch = &mt("Editing requires switching to the resource's home server.").'\n'.
+ &mt('Switch server?');
+
+
+ }
+# -------------------------------------------------------------------- Body tag
+ $script = ''."\n"
+ .''."\n";
+
+ # Breadcrumbs
+ &Apache::lonhtmlcommon::clear_breadcrumbs();
+
+ if ($showdoc) {
+ my $args;
+ if ($supplementalflag) {
+ my $title = &HTML::Entities::encode($env{'form.title'},'\'"<>&');
+ my $brcrum = &Apache::lonhtmlcommon::docs_breadcrumbs(undef,$crstype,undef,$title,1);
+ $args = {'bread_crumbs' => $brcrum,
+ 'bread_crumbs_nomenu' => 1};
+ } else {
+ $args = {'force_register' => $showdoc};
+ }
+ $r->print(&Apache::loncommon::start_page("$crstype documents",undef,$args));
+ } elsif ($toolsflag) {
+ my ($breadtext,$breadtitle);
+ $breadtext = "$crstype Editor";
+ if ($canedit) {
+ $breadtitle = 'Editing '.$crstype.' Contents';
+ } else {
+ $breadtext .= ' (View-only mode)';
+ $breadtitle = 'Viewing '.$crstype.' Contents';
+ }
+ &Apache::lonhtmlcommon::add_breadcrumb({
+ href=>"/adm/coursedocs",text=>$breadtext});
+ $r->print(&Apache::loncommon::start_page("$crstype Contents", $script)
+ .&Apache::loncommon::help_open_menu('','',273,'RAT')
+ .&Apache::lonhtmlcommon::breadcrumbs(
+ $breadtitle)
+ );
+ } elsif ($r->uri eq '/adm/supplemental') {
+ unless ($env{'request.role.adv'}) {
+ unless (&Apache::lonnet::has_unhidden_suppfiles($coursenum,$coursedom)) {
+ $r->internal_redirect('/adm/navmaps');
+ return OK;
+ }
+ }
+ my $brcrum = &Apache::lonhtmlcommon::docs_breadcrumbs(undef,$crstype);
+ my $args = {'bread_crumbs' => $brcrum};
+ unless (($env{'form.folderpath'} eq '') ||
+ ($env{'form.folder'} eq 'supplemental')) {
+ $args->{'bread_crumbs_nomenu'} = 1;
+ }
+ $r->print(&Apache::loncommon::start_page("Supplemental $crstype Content",undef,
+ $args));
+ } else {
+ my ($breadtext,$breadtitle,$helpitem);
+ $breadtext = "$crstype Editor";
+ if ($canedit) {
+ $breadtitle = 'Editing '.$crstype.' Contents';
+ $helpitem = 'Docs_Adding_Course_Doc';
+ } else {
+ $breadtext .= ' (View-only mode)';
+ $breadtitle = 'Viewing '.$crstype.' Contents';
+ $helpitem = 'Docs_Viewing_Course_Doc';
+ }
+ &Apache::lonhtmlcommon::add_breadcrumb({
+ href=>"/adm/coursedocs",text=>$breadtext});
+ $r->print(&Apache::loncommon::start_page("$crstype Contents", $script,
+ {'add_entries' => $addentries}
+ )
+ .&Apache::loncommon::help_open_menu('','',273,'RAT')
+ .&Apache::lonhtmlcommon::breadcrumbs(
+ $breadtitle,
+ $helpitem)
+ );
+ }
+
+ my %allfiles = ();
+ my %codebase = ();
+ my ($upload_result,$upload_output,$uploadphase);
+ if ($canedit) {
+ undef($suppchanges);
+ if (($env{'form.uploaddoc.filename'}) &&
+ ($env{'form.cmd'}=~/^upload_(\w+)/)) {
+ my $context = $1;
+ # Process file upload - phase one - upload and parse primary file.
+ undef($hadchanges);
+ $uploadphase = &process_file_upload(\$upload_output,$coursenum,$coursedom,
+ \%allfiles,\%codebase,$context,$crstype);
+ undef($navmap);
+ if ($hadchanges) {
+ &mark_hash_old();
+ }
+ if ($suppchanges) {
+ &Apache::lonnet::update_supp_caches($coursedom,$coursenum);
+ undef($suppchanges);
+ }
+ $r->print($upload_output);
+ } elsif ($env{'form.phase'} eq 'upload_embedded') {
+ # Process file upload - phase two - upload embedded objects
+ $uploadphase = 'check_embedded';
+ my $primaryurl = &HTML::Entities::encode($env{'form.primaryurl'},'<>&"');
+ my $state = &embedded_form_elems($uploadphase,$primaryurl,
+ $env{'form.newidx'});
+ my $docuname=$env{'course.'.$env{'request.course.id'}.'.num'};
+ my $docudom=$env{'course.'.$env{'request.course.id'}.'.domain'};
+ my ($destination,$dir_root) = &embedded_destination();
+ my $url_root = '/uploaded/'.$docudom.'/'.$docuname;
+ my $actionurl = '/adm/coursedocs';
+ my ($result,$flag) =
+ &Apache::loncommon::upload_embedded('coursedoc',$destination,
+ $docuname,$docudom,$dir_root,$url_root,undef,undef,undef,$state,
+ $actionurl);
+ $r->print($result.&return_to_editor());
+ } elsif ($env{'form.phase'} eq 'check_embedded') {
+ # Process file upload - phase three - modify references in HTML file
+ $uploadphase = 'modified_orightml';
+ my $docuname=$env{'course.'.$env{'request.course.id'}.'.num'};
+ my $docudom=$env{'course.'.$env{'request.course.id'}.'.domain'};
+ my ($destination,$dir_root) = &embedded_destination();
+ my $result =
+ &Apache::loncommon::modify_html_refs('coursedoc',$destination,
+ $docuname,$docudom,undef,
+ $dir_root);
+ $r->print($result.&return_to_editor());
+ } elsif ($env{'form.phase'} eq 'decompress_uploaded') {
+ $uploadphase = 'decompress_phase_one';
+ $r->print(&decompression_phase_one().
+ &return_to_editor());
+ } elsif ($env{'form.phase'} eq 'decompress_cleanup') {
+ $uploadphase = 'decompress_phase_two';
+ $r->print(&decompression_phase_two().
+ &return_to_editor());
+ }
+ }
+
+ if ($allowed && $toolsflag) {
+ $r->print(&startContentScreen('tools'));
+ $r->print(&generate_admin_menu($crstype,$canedit,$coursenum,$coursedom));
+ $r->print(&endContentScreen());
+ } elsif ((!$showdoc) && (!$uploadphase)) {
+# -----------------------------------------------------------------------------
+ my %lt=&Apache::lonlocal::texthash(
+ 'copm' => 'All documents out of a published map into this folder',
+ 'upfi' => 'Upload File',
+ 'upld' => 'Upload Content',
+ 'srch' => 'Search Repository',
+ 'impo' => 'Import from Repository',
+ 'lnks' => 'Import from Stored Links',
+ 'impm' => 'Import from Assembled Map',
+ 'imcr' => 'Import from Course Resources',
+ 'extr' => 'External Resource',
+ 'extt' => 'External Tool',
+ 'selm' => 'Select Map',
+ 'load' => 'Load Map',
+ 'newf' => 'New Folder',
+ 'newp' => 'New Composite Page',
+ 'syll' => 'Syllabus',
+ 'navc' => 'Table of Contents',
+ 'sipa' => 'Simple Course Page',
+ 'sipr' => 'Simple Problem',
+ 'webp' => 'Blank Web Page (editable)',
+ 'stpr' => 'Standard Problem',
+ 'news' => 'New sub-directory',
+ 'crpr' => 'Create Problem',
+ 'swit' => 'Switch Server',
+ 'drbx' => 'Drop Box',
+ 'scuf' => 'External Scores (handgrade, upload, clicker)',
+ 'bull' => 'Discussion Board',
+ 'mypi' => 'My Personal Information Page',
+ 'grpo' => 'Group Portfolio',
+ 'rost' => 'Course Roster',
+ 'abou' => 'Personal Information Page for a User',
+ 'imsf' => 'IMS Upload',
+ 'imsl' => 'Upload IMS package',
+ 'cms' => 'Origin of IMS package',
+ 'se' => 'Select',
+ 'file' => 'File',
+ 'title' => 'Title',
+ 'addp' => 'Add Placeholder to course?',
+ 'uste' => 'Use Template?',
+ 'fnam' => 'File Name:',
+ 'loca' => 'Location:',
+ 'dire' => 'Directory:',
+ 'cate' => 'Category:',
+ 'tmpl' => 'Template:',
+ 'empd' => 'No resources found',
+ 'comment' => 'Comment',
+ 'parse' => 'Upload embedded images/multimedia files if HTML file',
+ 'bb5' => 'Blackboard 5',
+ 'bb6' => 'Blackboard 6',
+ 'angel5' => 'ANGEL 5.5',
+ 'webctce4' => 'WebCT 4 Campus Edition',
+ 'yes' => 'Yes',
+ 'no' => 'No',
+ 'er' => 'Editing rights unavailable for your current role.',
+ );
+# -----------------------------------------------------------------------------
+
+ # Calculate free quota space for a user or course. A javascript function checks
+ # file size to determine if upload should be allowed.
+ my $quotatype = 'unofficial';
+ if ($crstype eq 'Community') {
+ $quotatype = 'community';
+ } elsif ($crstype eq 'Placement') {
+ $quotatype = 'placement';
+ } elsif ($env{'course.'.$coursedom.'_'.$coursenum.'.internal.coursecode'}) {
+ $quotatype = 'official';
+ } elsif ($env{'course.'.$coursedom.'_'.$coursenum.'.internal.textbook'}) {
+ $quotatype = 'textbook';
+ }
+ my $disk_quota = &Apache::loncommon::get_user_quota($coursenum,$coursedom,
+ 'course',$quotatype); # expressed in MB
+ my $current_disk_usage = 0;
+ foreach my $subdir ('docs','supplemental') {
+ $current_disk_usage += &Apache::lonnet::diskusage($coursedom,$coursenum,
+ "userfiles/$subdir",1); # expressed in kB
+ }
+ my $free_space = 1024 * ((1024 * $disk_quota) - $current_disk_usage);
+ my $usage = $current_disk_usage/1024; # in MB
+ my $quota = $disk_quota;
+ my $percent;
+ if ($disk_quota == 0) {
+ $percent = 100.0;
+ } else {
+ $percent = 100*($usage/$disk_quota);
+ }
+ $usage = sprintf("%.2f",$usage);
+ $quota = sprintf("%.2f",$quota);
+ $percent = sprintf("%.0f",$percent);
+ my $quotainfo = ''.&mt('Currently using [_1] of the [_2] available.',
+ $percent.'%',$quota.' MB').'
';
+
+ my $fileupload=(<
+FIUP
+ my $checkbox=(<$lt{'parse'}?
+
+ -->
+
+CHBO
+ my $imsfolder = $env{'form.folder'};
+ if ($imsfolder eq '') {
+ $imsfolder = 'default';
+ }
+ my $imspform=(<