Diff for /loncom/publisher/lonpublisher.pm between versions 1.273 and 1.295.2.1.2.2

version 1.273, 2011/10/26 15:05:25 version 1.295.2.1.2.2, 2024/06/01 22:41:28
Line 66  invocation by F<loncapa_apache.conf>: Line 66  invocation by F<loncapa_apache.conf>:
   
 =head1 OVERVIEW  =head1 OVERVIEW
   
 Authors can only write-access the C</~authorname/> space. They can  Authors can only write-access the C</priv/domain/authorname/> space. 
 copy resources into the resource area through the publication step,  They can copy resources into the resource area through the 
 and move them back through a recover step. Authors do not have direct  publication step, and move them back through a recover step. 
 write-access to their resource space.  Authors do not have direct write-access to their resource space.
   
 During the publication step, several events will be  During the publication step, several events will be
 triggered. Metadata is gathered, where a wizard manages default  triggered. Metadata is gathered, where a wizard manages default
Line 102  to publication space. Line 102  to publication space.
 Many of the undocumented subroutines implement various magical  Many of the undocumented subroutines implement various magical
 parsing shortcuts.  parsing shortcuts.
   
 =over 4  
   
 =cut  =cut
   
 ######################################################################  ######################################################################
Line 121  use HTML::LCParser; Line 119  use HTML::LCParser;
 use HTML::Entities;  use HTML::Entities;
 use Encode::Encoder;  use Encode::Encoder;
 use Apache::lonxml;  use Apache::lonxml;
 use Apache::loncacc;  
 use DBI;  use DBI;
 use Apache::lonnet;  use Apache::lonnet;
 use Apache::loncommon();  use Apache::loncommon();
Line 150  my $lock; Line 147  my $lock;
   
 =pod  =pod
   
   =over 4
   
 =item B<metaeval>  =item B<metaeval>
   
 Evaluates a string that contains metadata.  This subroutine  Evaluates a string that contains metadata.  This subroutine
Line 201  sub metaeval { Line 200  sub metaeval {
     if (defined($token->[2]->{'name'})) {       if (defined($token->[2]->{'name'})) { 
  $unikey.="\0".$token->[2]->{'name'};    $unikey.="\0".$token->[2]->{'name'}; 
     }      }
     foreach (@{$token->[3]}) {      foreach my $item (@{$token->[3]}) {
  $metadatafields{$unikey.'.'.$_}=$token->[2]->{$_};   $metadatafields{$unikey.'.'.$item}=$token->[2]->{$item};
  if ($metadatakeys{$unikey}) {   if ($metadatakeys{$unikey}) {
     $metadatakeys{$unikey}.=','.$_;      $metadatakeys{$unikey}.=','.$item;
  } else {   } else {
     $metadatakeys{$unikey}=$_;      $metadatakeys{$unikey}=$item;
  }   }
     }      }
     my $newentry=$parser->get_text('/'.$entry);      my $newentry=$parser->get_text('/'.$entry);
Line 294  sub coursedependencies { Line 293  sub coursedependencies {
     my %evaldata=&Apache::lonnet::dump('nohist_resevaldata',$adomain,      my %evaldata=&Apache::lonnet::dump('nohist_resevaldata',$adomain,
        $aauthor,$regexp);         $aauthor,$regexp);
     my %courses=();      my %courses=();
     foreach (keys %evaldata) {      foreach my $item (keys(%evaldata)) {
  if ($_=~/^([a-zA-Z0-9]+_[a-zA-Z0-9]+)___.+___course$/) {   if ($item=~/^([a-zA-Z0-9]+_[a-zA-Z0-9]+)___.+___course$/) {
     $courses{$1}=1;      $courses{$1}=1;
         }          }
     }      }
Line 319  string which presents the form field (fo Line 318  string which presents the form field (fo
   
 =item B<textfield>  =item B<textfield>
   
   =item B<text_with_browse_field>
   
 =item B<hiddenfield>  =item B<hiddenfield>
   
   =item B<checkbox>
   
 =item B<selectbox>  =item B<selectbox>
   
 =back  =back
Line 368  sub hiddenfield { Line 371  sub hiddenfield {
   
 sub checkbox {  sub checkbox {
     my ($name,$text)=@_;      my ($name,$text)=@_;
     return "\n<br /><label><input type='checkbox' name='$name' /> ".      return "\n<label><input type='checkbox' name='$name' /> ".
  &mt($text)."</label>";   &mt($text)."</label>";
 }  }
   
Line 383  sub selectbox { Line 386  sub selectbox {
     }      }
     my $selout="\n".&Apache::lonhtmlcommon::row_title($title)      my $selout="\n".&Apache::lonhtmlcommon::row_title($title)
               .'<select name="'.$name.'">';                .'<select name="'.$name.'">';
     foreach (@idlist) {      foreach my $id (@idlist) {
         $selout.='<option value="'.$_.'"';          $selout.='<option value="'.$id.'"';
         if ($_ eq $value) {          if ($id eq $value) {
     $selout.=' selected="selected"';      $selout.=' selected="selected"';
         }          }
         $selout.='>'.&{$functionref}($_).'</option>';          $selout.='>'.&{$functionref}($id).'</option>';
     }      }
     $selout.='</select>'.&Apache::lonhtmlcommon::row_closure();      $selout.='</select>'.&Apache::lonhtmlcommon::row_closure();
     return $selout;      return $selout;
Line 400  sub select_level_form { Line 403  sub select_level_form {
     if (!defined($value)) { $env{'form.'.$name}=0; }      if (!defined($value)) { $env{'form.'.$name}=0; }
     return  &Apache::loncommon::select_level_form($value,$name);      return  &Apache::loncommon::select_level_form($value,$name);
 }  }
   
   sub common_access {
       my ($name,$text,$options)=@_;
       return unless (ref($options) eq 'ARRAY');
       my $formname = 'pubdirpref';
       my $chkname = 'common'.$name;
       my $chkid = 'LC_'.$chkname;
       my $divid = $chkid.'div';
       my $customdivid = 'LC_customfile'; 
       my $selname = $chkname.'select';
       my $selid = $chkid.'select';
       my $selonchange;
       if ($name eq 'dist') {
           $selonchange = ' onchange="showHideCustom(this,'."'$customdivid'".');"';
       }
       my %lt = &Apache::lonlocal::texthash(
                                               'default' => 'System wide - can be used for any courses system wide',
                                               'domain'  => 'Domain only - use limited to courses in the domai',
                                               'custom'  => 'Customized right of use ...',
                                               'public'  => 'Public - no authentication or authorization required for use',
                                               'closed'  => 'Closed - XML source is closed to everyone',
                                               'open'    => 'Open - XML source is open to people who want to use it',
                                               'sel'     => 'Select',
                                           );
       my $output = <<"END";
   <span class="LC_nobreak">
   <label>
   <input type="checkbox" name="commonaccess" value="$name" id="$chkid"  
   onclick="showHideAccess(this,'$divid');" />
   $text</label></span>
   <div id="$divid" style="padding:0;clear:both;margin:0;border:0;display:none">
   <select name="$selname" id="$selid" $selonchange>
   <option value="" selected="selected">$lt{'sel'}</option>
   END
       foreach my $val (@{$options}) {
           $output .= '<option value="'.$val.'">'.$lt{$val}.'</option>'."\n";
       }
       $output .= '
   </select>';
       if ($name eq 'dist') {
           $output .= <<"END";
   <div id="$customdivid" style="padding:0;clear:both;margin:0;border:0;display:none">
   <input type="text" name="commoncustomrights" size="60" value="" />
   <a href="javascript:openbrowser('$formname','commoncustomrights','rights');">
   $lt{'sel'}</a></div>
   END
       }
       $output .= '
   </div>
   ';
   }
   
 #########################################  #########################################
 #########################################  #########################################
   
Line 469  Currently undocumented Line 524  Currently undocumented
 #########################################  #########################################
 #########################################  #########################################
 sub set_allow {  sub set_allow {
     my ($allow,$logfile,$target,$tag,$oldurl)=@_;      my ($allow,$logfile,$target,$tag,$oldurl,$type)=@_;
     my $newurl=&urlfixup($oldurl,$target);      my $newurl=&urlfixup($oldurl,$target);
     my $return_url=$oldurl;      my $return_url=$oldurl;
     print $logfile 'GUYURL: '.$tag.':'.$oldurl.' - '.$newurl."\n";      print $logfile 'GUYURL: '.$tag.':'.$oldurl.' - '.$newurl."\n";
Line 481  sub set_allow { Line 536  sub set_allow {
  ($newurl !~ /^mailto:/i) &&   ($newurl !~ /^mailto:/i) &&
  ($newurl !~ /^(?:http|https|ftp):/i) &&   ($newurl !~ /^(?:http|https|ftp):/i) &&
  ($newurl !~ /^\#/)) {   ($newurl !~ /^\#/)) {
           if (($type eq 'src') || ($type eq 'href')) {
               if ($newurl =~ /^([^?]+)\?[^?]*$/) {
                   $newurl = $1;
               }
           }
  $$allow{&absoluteurl($newurl,$target)}=1;   $$allow{&absoluteurl($newurl,$target)}=1;
     }      }
     return $return_url;      return $return_url;
Line 722  sub fix_ids_and_indices { Line 782  sub fix_ids_and_indices {
     foreach my $type ('src','href','background','bgimg') {      foreach my $type ('src','href','background','bgimg') {
  foreach my $key (keys(%parms)) {   foreach my $key (keys(%parms)) {
     if ($key =~ /^$type$/i) {      if ($key =~ /^$type$/i) {
                                   next if (($lctag eq 'img') && ($type eq 'src') && 
                                            ($parms{$key} =~ m{^data\:image/gif;base64,}));
  $parms{$key}=&set_allow(\%allow,$logfile,   $parms{$key}=&set_allow(\%allow,$logfile,
  $target,$tag,   $target,$tag,
  $parms{$key});   $parms{$key},$type);
     }      }
  }   }
     }      }
Line 781  sub fix_ids_and_indices { Line 843  sub fix_ids_and_indices {
  }   }
  my $newparmstring='';   my $newparmstring='';
  my $endtag='';   my $endtag='';
  foreach (keys %parms) {   foreach my $parkey (keys(%parms)) {
     if ($_ eq '/') {      if ($parkey eq '/') {
  $endtag=' /';   $endtag=' /';
     } else {       } else { 
  my $quote=($parms{$_}=~/\"/?"'":'"');   my $quote=($parms{$parkey}=~/\"/?"'":'"');
  $newparmstring.=' '.$_.'='.$quote.$parms{$_}.$quote;   $newparmstring.=' '.$parkey.'='.$quote.$parms{$parkey}.$quote;
     }      }
  }   }
  if (!$endtag) { if ($token->[4]=~m:/>$:) { $endtag=' /'; }; }   if (!$endtag) { if ($token->[4]=~m:/>$:) { $endtag=' /'; }; }
  $outstring.='<'.$tag.$newparmstring.$endtag.'>';   $outstring.='<'.$tag.$newparmstring.$endtag.'>';
  if ($lctag eq 'm' || $lctag eq 'script' || $lctag eq 'answer'    if ($lctag eq 'm' || $lctag eq 'answer' || $lctag eq 'display' ||
                     || $lctag eq 'display' || $lctag eq 'tex') {                      $lctag eq 'tex') {
     $outstring.=&get_all_text_unbalanced('/'.$lctag,\@parser);      $outstring.=&get_all_text_unbalanced('/'.$lctag,\@parser);
  }                  } elsif ($lctag eq 'script') {
                       if ($parms{'type'} eq 'loncapa/perl') {
                           $outstring.=&get_all_text_unbalanced('/'.$lctag,\@parser);
                       } else {
                           my $script = &get_all_text_unbalanced('/'.$lctag,\@parser);
                           if ($script =~ m{\.set\w+(Src|Swf)\(["']}i) {
                               my @srcs = split(/\.set/i,$script);
                               if (scalar(@srcs) > 1) {
                                   foreach my $item (@srcs) {
                                       if ($item =~ m{^(FlashPlayerSwf|MediaSrc|XMPSrc|ConfigurationSrc|PosterImageSrc)\((['"])(?:(?!\2).)+\2\)}is) {
                                           my $srctype = $1;
                                           my $quote = $2;
                                           my ($url) = ($item =~ m{^\Q$srctype($quote\E([^$quote]+)\Q$quote)\E});
                                           $url = &urlfixup($url);
                                           unless ($url=~m{^(?:http|https|ftp)://}) {
                                               $allow{&absoluteurl($url,$target)}=1;
                                               if ($srctype eq 'ConfigurationSrc') {
                                                   if ($url =~ m{^(.+/)configuration_express\.xml$}) {
   #
   # Camtasia 8.1: express_show/spritesheet.png needed, and included in zip archive.
   # Not referenced directly in <main>.html or <main>_player.html files,
   # so add this file to %allow (where <main> is name user gave to file/archive).
   #
                                                       my $spritesheet = $1.'express_show/spritesheet.png';
                                                       $allow{&absoluteurl($spritesheet,$target)}=1;
   
   #
   # Camtasia 8.4: skins/express_show/spritesheet.min.css needed, and included in zip archive.
   # Not referenced directly in <main>.html or <main>_player.html files,
   # so add this file to %allow (where <main> is name user gave to file/archive).
   #
                                                       my $spritecss = $1.'express_show/spritesheet.min.css';
                                                       $allow{&absoluteurl($spritecss,$target)}=1;
                                                   }
                                               } elsif ($srctype eq 'PosterImageSrc') {
                                                   if ($url =~ m{^(.+)_First_Frame\.png$}) {
                                                       my $prefix = $1;
   #
   # Camtasia 8.1: <main>_Thumbnails.png needed, and included in zip archive.
   # Not referenced directly in <main>.html or <main>_player.html files,
   # so add this file to %allow (where <main> is name user gave to file/archive).
   #
                                                       my $thumbnail = $prefix.'_Thumbnails.png';
                                                       $allow{&absoluteurl($thumbnail,$target)}=1;
                                                   }
                                               }
                                           }
                                       }
                                   }
                               }
                           }
                           if ($script =~ m{\.addMediaSrc\((["'])((?!\1).+)\1\);}) {
                               my $src = $2;
                               if ($src) {
                                   my $url = &urlfixup($src);
                                   unless ($url=~m{^(?:http|https|ftp)://}) {
                                       $allow{&absoluteurl($url,$target)}=1;
                                   }
                               }
                           }
                           if ($script =~ /\(document,\s*(['"])script\1,\s*\[([^\]]+)\]\);/s) {
                               my $scriptslist = $2;
                               my @srcs = split(/\s*,\s*/,$scriptslist);
                               foreach my $src (@srcs) {
                                   if ($src =~ /(["'])(?:(?!\1).)+\.js\1/) {
                                       my $quote = $1;
                                       my ($url) = ($src =~ m/\Q$quote\E([^$quote]+)\Q$quote\E/);
                                       $url = &urlfixup($url);
                                       unless ($url=~m{^(?:http|https|ftp)://}) {
                                           $allow{&absoluteurl($url,$target)}=1;
                                       }
                                   }
                               }
                           }
                           if ($script =~ m{loadScript\(\s*(['"])((?:(?!\1).)+\.js)\1,\s*function}is) {
                               my $src = $2;
                               if ($src) {
                                   my $url = &urlfixup($src);
                                   unless ($url=~m{^(?:http|https|ftp)://}) {
                                       $allow{&absoluteurl($url,$target)}=1;
                                   }
                               }
                           }
                           $outstring .= $script;
                       }
                   }
     } elsif ($token->[0] eq 'E') {      } elsif ($token->[0] eq 'E') {
  if ($token->[2]) {   if ($token->[2]) {
     unless ($token->[1] eq 'allow') {      unless ($token->[1] eq 'allow') {
Line 1017  sub publish { Line 1164  sub publish {
    $outdep.= ' - <span class="LC_error">'.&mt('Currently not available').     $outdep.= ' - <span class="LC_error">'.&mt('Currently not available').
        '</span>';         '</span>';
                } else {                 } else {
   #
   # Store the fact that the dependency has been used by the target file
   # Unfortunately, usage is erroneously named sequsage in lonmeta.pm
   # The translation happens in lonmetadata.pm
   #
                    my %temphash=(&Apache::lonnet::declutter($target).'___'.                     my %temphash=(&Apache::lonnet::declutter($target).'___'.
                              &Apache::lonnet::declutter($thisdep).'___usage'                               &Apache::lonnet::declutter($thisdep).'___usage'
                                  => time);                                   => time);
Line 1101  sub publish { Line 1253  sub publish {
   
 # ------------------- Clear out parameters and stores (there should not be any)  # ------------------- Clear out parameters and stores (there should not be any)
   
         foreach (keys %metadatafields) {          foreach my $field (keys(%metadatafields)) {
     if (($_=~/^parameter/) || ($_=~/^stores/)) {      if (($field=~/^parameter/) || ($field=~/^stores/)) {
  delete $metadatafields{$_};   delete $metadatafields{$field};
             }              }
         }          }
   
Line 1112  sub publish { Line 1264  sub publish {
   
         $scrout.=&metaread($logfile,$source.'.meta');          $scrout.=&metaread($logfile,$source.'.meta');
   
         foreach (keys %metadatafields) {          foreach my $field (keys(%metadatafields)) {
     if (($_=~/^parameter/) || ($_=~/^stores/)) {      if (($field=~/^parameter/) || ($field=~/^stores/)) {
                 $oldparmstores{$_}=1;                  $oldparmstores{$field}=1;
  delete $metadatafields{$_};   delete $metadatafields{$field};
             }              }
         }          }
 # ------------------------------------------------------------- Save some stuff  # ------------------------------------------------------------- Save some stuff
         my %savemeta=();          my %savemeta=();
         foreach ('title') {          if ($metadatafields{'title'}) { $savemeta{'title'}=$metadatafields{'title'}; }
             if ($metadatafields{$_}) { $savemeta{$_}=$metadatafields{$_}; }  
  }  
 # ------------------------------------------ See if anything new in file itself  # ------------------------------------------ See if anything new in file itself
     
  $allmeta=&parseformeta($source,$style);   $allmeta=&parseformeta($source,$style);
 # ----------------------------------------------------------- Restore the stuff  # ----------------------------------------------------------- Restore the stuff
         foreach (keys %savemeta) {          foreach my $item (keys(%savemeta)) {
     $metadatafields{$_}=$savemeta{$_};      $metadatafields{$item}=$savemeta{$item};
  }   }
    }     }
   
Line 1136  sub publish { Line 1286  sub publish {
 # ---------------- Find and document discrepancies in the parameters and stores  # ---------------- Find and document discrepancies in the parameters and stores
   
     my $chparms='';      my $chparms='';
     foreach (sort keys %metadatafields) {      foreach my $field (sort(keys(%metadatafields))) {
  if (($_=~/^parameter/) || ($_=~/^stores/)) {   if (($field=~/^parameter/) || ($field=~/^stores/)) {
     unless ($_=~/\.\w+$/) {       unless ($field=~/\.\w+$/) {
  unless ($oldparmstores{$_}) {   unless ($oldparmstores{$field}) {
     my $disp_key = $_;      my $disp_key = $field;
     $disp_key =~ tr/\0/_/;      $disp_key =~ tr/\0/_/;
     print $logfile ('New: '.$disp_key."\n");      print $logfile ('New: '.$disp_key."\n");
     $chparms .= $disp_key.' ';      $chparms .= $disp_key.' ';
Line 1154  sub publish { Line 1304  sub publish {
     }      }
   
     $chparms='';      $chparms='';
     foreach (sort keys %oldparmstores) {      foreach my $olditem (sort(keys(%oldparmstores))) {
  if (($_=~/^parameter/) || ($_=~/^stores/)) {   if (($olditem=~/^parameter/) || ($olditem=~/^stores/)) {
     unless (($metadatafields{$_.'.name'}) ||      unless (($metadatafields{$olditem.'.name'}) ||
     ($metadatafields{$_.'.package'}) || ($_=~/\.\w+$/)) {      ($metadatafields{$olditem.'.package'}) || ($olditem=~/\.\w+$/)) {
  my $disp_key = $_;   my $disp_key = $olditem;
  $disp_key =~ tr/\0/_/;   $disp_key =~ tr/\0/_/;
  print $logfile ('Obsolete: '.$disp_key."\n");   print $logfile ('Obsolete: '.$disp_key."\n");
  $chparms.=$disp_key.' ';   $chparms.=$disp_key.' ';
Line 1235  sub publish { Line 1385  sub publish {
  &hiddenfield('phase','two').   &hiddenfield('phase','two').
  &hiddenfield('filename',$env{'form.filename'}).   &hiddenfield('filename',$env{'form.filename'}).
  &hiddenfield('allmeta',&escape($allmeta)).   &hiddenfield('allmeta',&escape($allmeta)).
  &hiddenfield('dependencies',join(',',keys %allow));   &hiddenfield('dependencies',join(',',keys(%allow)));
     unless ($env{'form.makeobsolete'}) {      unless ($env{'form.makeobsolete'}) {
        $intr_scrout.=         $intr_scrout.=
  &textfield('Title','title',$metadatafields{'title'}).   &textfield('Title','title',$metadatafields{'title'}).
Line 1480  Returns: Line 1630  Returns:
 0: fail  0: fail
 1: success  1: success
   
   =back
   
 =cut  =cut
   
 #'stupid emacs  #'stupid emacs
Line 1533  sub phasetwo { Line 1685  sub phasetwo {
     %metadatakeys=();      %metadatakeys=();
   
     &metaeval(&unescape($env{'form.allmeta'}));      &metaeval(&unescape($env{'form.allmeta'}));
       
       if ($batch) {
           my %commonaccess;
           map { $commonaccess{$_} = 1; } &Apache::loncommon::get_env_multiple('form.commonaccess');
           if ($commonaccess{'dist'}) {
               unless ($style eq 'prv') { 
                   if ($env{'form.commondistselect'} eq 'custom') {
                       unless ($source =~ /\.rights$/) {
                           if ($env{'form.commoncustomrights'} =~ m{^/res/.+\.rights$}) { 
                               $env{'form.customdistributionfile'} = $env{'form.commoncustomrights'}; 
                               $env{'form.copyright'} = $env{'form.commondistselect'};
                           }
                       }
                   } elsif ($env{'form.commondistselect'} =~ /^default|domain|public$/) {
                       $env{'form.copyright'} = $env{'form.commondistselect'};
                   }
               }
           }
           unless ($style eq 'prv') {
               if ($commonaccess{'source'}) {
                   if (($env{'form.commonsourceselect'} eq 'open') || ($env{'form.commonsourceselect'} eq 'closed')) {
                       $env{'form.sourceavail'} = $env{'form.commonsourceselect'};
                   }
               }
           }
       }
   
     $metadatafields{'title'}=$env{'form.title'};      $metadatafields{'title'}=$env{'form.title'};
     $metadatafields{'author'}=$env{'form.author'};      $metadatafields{'author'}=$env{'form.author'};
     $metadatafields{'subject'}=$env{'form.subject'};      $metadatafields{'subject'}=$env{'form.subject'};
Line 1594  sub phasetwo { Line 1772  sub phasetwo {
  '</span>');   '</span>');
     return 0;      return 0;
         }          }
         foreach (sort keys %metadatafields) {          foreach my $field (sort(keys(%metadatafields))) {
             unless ($_=~/\./) {              unless ($field=~/\./) {
                 my $unikey=$_;                  my $unikey=$field;
                 $unikey=~/^([A-Za-z]+)/;                  $unikey=~/^([A-Za-z]+)/;
                 my $tag=$1;                  my $tag=$1;
                 $tag=~tr/A-Z/a-z/;                  $tag=~tr/A-Z/a-z/;
                 print $mfh "\n\<$tag";                  print $mfh "\n\<$tag";
                 foreach (split(/\,/,$metadatakeys{$unikey})) {                  foreach my $item (split(/\,/,$metadatakeys{$unikey})) {
                     my $value=$metadatafields{$unikey.'.'.$_};                      my $value=$metadatafields{$unikey.'.'.$item};
                     $value=~s/\"/\'\'/g;                      $value=~s/\"/\'\'/g;
                     print $mfh ' '.$_.'="'.$value.'"';                      print $mfh ' '.$item.'="'.$value.'"';
                 }                  }
                 print $mfh '>'.                  print $mfh '>'.
                     &HTML::Entities::encode($metadatafields{$unikey},'<>&"')                      &HTML::Entities::encode($metadatafields{$unikey},'<>&"')
Line 1746  sub phasetwo { Line 1924  sub phasetwo {
   
 # ------------------------------------------------------------- Trigger updates  # ------------------------------------------------------------- Trigger updates
     push(@{$modified_urls},[$target,$source]);      push(@{$modified_urls},[$target,$source]);
     unless ($registered_cleanup) {      &notify_in_cleanup($r);
         my $handlers = $r->get_handlers('PerlCleanupHandler');  
         $r->set_handlers('PerlCleanupHandler' => [\&notify,@{$handlers}]);  
  $registered_cleanup=1;  
     }  
   
 # ---------------------------------------------------------- Clear local caches  # ---------------------------------------------------------- Clear local caches
     my $thisdistarget=$target;      my $thisdistarget=$target;
Line 1770  sub phasetwo { Line 1944  sub phasetwo {
         my $thissrcdir=$thissrc;          my $thissrcdir=$thissrc;
         $thissrcdir=~s/\/[^\/]+$/\//;          $thissrcdir=~s/\/[^\/]+$/\//;
                   
         $r->print(&Apache::loncommon::head_subbox(          $r->print(
             &Apache::lonhtmlcommon::start_funclist().              &Apache::lonhtmlcommon::actionbox([
             &Apache::lonhtmlcommon::add_item_funclist(  
                 '<a href="'.$thisdistarget.'">'.                  '<a href="'.$thisdistarget.'">'.
                 &mt('View Published Version').                  &mt('View Published Version').
                 '</a>').                  '</a>',
             &Apache::lonhtmlcommon::add_item_funclist(  
                 '<a href="'.$thissrc.'">'.                  '<a href="'.$thissrc.'">'.
                 &mt('Back to Source').                  &mt('Back to Source').
                 '</a>').                  '</a>',
             &Apache::lonhtmlcommon::add_item_funclist(  
                 '<a href="'.$thissrcdir.'">'.                  '<a href="'.$thissrcdir.'">'.
                 &mt('Back to Source Directory').                  &mt('Back to Source Directory').
                 '</a>').                  '</a>'])
             &Apache::lonhtmlcommon::end_funclist())  
         );          );
     }      }
     return 1;      return 1;
 }  }
   
   sub notify_in_cleanup {
       my ($r) = @_;
       unless ($registered_cleanup) {
           my $handlers = $r->get_handlers('PerlCleanupHandler');
           $r->set_handlers('PerlCleanupHandler' => [\&notify,@{$handlers}]);
           $registered_cleanup=1;
       }
   }
   
 # =============================================================== Notifications  # =============================================================== Notifications
 sub notify {    sub notify {  
 # --------------------------------------------------- Send update notifications  # --------------------------------------------------- Send update notifications
Line 1814  sub notify { Line 1993  sub notify {
 # --------------------------------------------------- Notify subscribed courses  # --------------------------------------------------- Notify subscribed courses
  my %courses=&coursedependencies($target);   my %courses=&coursedependencies($target);
  my $now=time;   my $now=time;
  foreach (keys %courses) {   foreach my $course (keys(%courses)) {
     print $logfile "\nNotifying course ".$_.':';      print $logfile "\nNotifying course ".$course.':';
     my ($cdom,$cname)=split(/\_/,$_);      my ($cdom,$cname)=split(/\_/,$course);
     my $reply=&Apache::lonnet::cput      my $reply=&Apache::lonnet::cput
  ('versionupdate',{$target => $now},$cdom,$cname);   ('versionupdate',{$target => $now},$cdom,$cname);
     print $logfile $reply;      print $logfile $reply;
Line 1880  sub publishdirectory { Line 2059  sub publishdirectory {
     $thisdisfn=~s/\/+/\//g;      $thisdisfn=~s/\/+/\//g;
     my $thisdisresdir=$thisdisfn;      my $thisdisresdir=$thisdisfn;
     $thisdisresdir=~s/^\/priv\//\/res\//;      $thisdisresdir=~s/^\/priv\//\/res\//;
     my $resdir='/home/httpd/html'.$thisdisresdir;      my $resdir = $r->dir_config('lonDocRoot').$thisdisresdir;
     $r->print(&Apache::lonhtmlcommon::start_pick_box()      $r->print('<form name="pubdirpref" method="post" action="">'
                .&Apache::lonhtmlcommon::start_pick_box()
              .&Apache::lonhtmlcommon::row_title(&mt('Directory'))               .&Apache::lonhtmlcommon::row_title(&mt('Directory'))
             .'<span class="LC_filename">'.$thisdisfn.'</span>'              .'<span class="LC_filename">'.$thisdisfn.'</span>'
             .&Apache::lonhtmlcommon::row_closure()              .&Apache::lonhtmlcommon::row_closure()
             .&Apache::lonhtmlcommon::row_title(&mt('Target'))              .&Apache::lonhtmlcommon::row_title(&mt('Target'))
             .'<span class="LC_filename">'.$thisdisresdir.'</span>'              .'<span class="LC_filename">'.$thisdisresdir.'</span>'
     );      );
       my %reasons = &Apache::lonlocal::texthash(
                         mod => 'Authoring Space file postdates published file',
                         modmeta => 'Authoring Space metadata file postdates published file',
                         unpub => 'Resource is unpublished',
       );
   
     my $dirptr=16384; # Mask indicating a directory in stat.cmode.      my $dirptr=16384; # Mask indicating a directory in stat.cmode.
     unless ($env{'form.phase'} eq 'two') {      unless ($env{'form.phase'} eq 'two') {
 # ask user what they want  # ask user what they want
         $r->print(&Apache::lonhtmlcommon::row_closure()          $r->print(&Apache::lonhtmlcommon::row_closure()
                  .&Apache::lonhtmlcommon::row_title(&mt('Options'))                   .&Apache::lonhtmlcommon::row_title(&mt('Options')
         );                   .&Apache::loncommon::help_open_topic('Publishing_Directory_Options')));
         $r->print('<form name="pubdirpref" method="post">'.          $r->print(&hiddenfield('phase','two').
   &hiddenfield('phase','two').  
   &hiddenfield('filename',$env{'form.filename'}).    &hiddenfield('filename',$env{'form.filename'}).
   &checkbox('pubrec','include subdirectories').                    '<fieldset><legend>'.&mt('Recurse').'</legend>'.
   &checkbox('forcerepub','force republication of previously published files').                    &checkbox('pubrec','include subdirectories').
                   &checkbox('obsolete','make file(s) obsolete').                    '</fieldset>'.
   &checkbox('forceoverride','force directory level metadata over existing').                    '<fieldset><legend>'.&mt('Force').'</legend>'.
   '<br /><input type="submit" value="'.&mt('Publish Directory').'" /></form>');                    &checkbox('forcerepub','force republication of previously published files').'<br />'.
                     &checkbox('forceoverride','force directory level metadata over existing').
                     '</fieldset>'.
                     '<fieldset><legend>'.&mt('Exclude').'</legend>'.
                     &checkbox('excludeunpub','exclude currently unpublished files').'<br />'.
                     &checkbox('excludemod','exclude modified files').'<br />'.
                     &checkbox('excludemodmeta','exclude files with modified metadata').
                     '</fieldset>'.
                     '<fieldset><legend>'.&mt('Actions').'</legend>'.
                     &checkbox('obsolete','make file(s) obsolete').'<br />'.
                     &common_access('dist',&mt('apply common copyright/distribution'),
                                    ['default','domain','public','custom']).'<br />'.
                     &common_access('source',&mt('apply common source availability'),
                                    ['closed','open']).
                     '</fieldset>'
           );
         $r->print(&Apache::lonhtmlcommon::row_closure(1)          $r->print(&Apache::lonhtmlcommon::row_closure(1)
                  .&Apache::lonhtmlcommon::end_pick_box()                   .&Apache::lonhtmlcommon::end_pick_box()
                    .'<br /><input type="submit" value="'.&mt('Publish Directory').'" /></form>'
         );          );
         $lock=0;          $lock=0;
     } else {      } else {
         $r->print(&Apache::lonhtmlcommon::row_closure(1)          $r->print(&Apache::lonhtmlcommon::row_closure(1)
                  .&Apache::lonhtmlcommon::end_pick_box()                   .&Apache::lonhtmlcommon::end_pick_box()
         );          );
           my %commonaccess;
           map { $commonaccess{$_} = 1; } &Apache::loncommon::get_env_multiple('form.commonaccess');
         unless ($lock) { $lock=&Apache::lonnet::set_lock(&mt('Publishing [_1]',$fn)); }          unless ($lock) { $lock=&Apache::lonnet::set_lock(&mt('Publishing [_1]',$fn)); }
           if ($lock) {
               &notify_in_cleanup($r);
           }
 # actually publish things  # actually publish things
  opendir(DIR,$fn);   opendir(DIR,$fn);
  my @files=sort(readdir(DIR));   my @files=sort(readdir(DIR));
Line 1920  sub publishdirectory { Line 2125  sub publishdirectory {
  $cuid,$cgid,$crdev,$csize,   $cuid,$cgid,$crdev,$csize,
  $catime,$cmtime,$cctime,   $catime,$cmtime,$cctime,
  $cblksize,$cblocks)=stat($fn.'/'.$filename);   $cblksize,$cblocks)=stat($fn.'/'.$filename);
       
     my $extension='';      my $extension='';
     if ($filename=~/\.(\w+)$/) { $extension=$1; }      if ($filename=~/\.(\w+)$/) { $extension=$1; }
     if ($cmode&$dirptr) {      if ($cmode&$dirptr) {
  if (($filename!~/^\./) && ($env{'form.pubrec'})) {   if (($filename!~/^\./) && ($env{'form.pubrec'})) {
     &publishdirectory($r,$docroot.$fn.'/'.$filename,$thisdisfn.'/'.$filename);      &publishdirectory($r,$fn.'/'.$filename,$thisdisfn.'/'.$filename);
  }   }
     } elsif ((&Apache::loncommon::fileembstyle($extension) ne 'hdn') &&      } elsif ((&Apache::loncommon::fileembstyle($extension) ne 'hdn') &&
      ($filename!~/^[\#\.]/) && ($filename!~/\~$/)) {       ($filename!~/^[\#\.]/) && ($filename!~/\~$/)) {
 # find out publication status and/or exiting metadata  # find out publication status and/or existing metadata
  my $publishthis=0;   my $publishthis=0;
                   my $skipthis;
  if (-e $resdir.'/'.$filename) {   if (-e $resdir.'/'.$filename) {
     my ($rdev,$rino,$rmode,$rnlink,      my ($rdev,$rino,$rmode,$rnlink,
  $ruid,$rgid,$rrdev,$rsize,   $ruid,$rgid,$rrdev,$rsize,
Line 1938  sub publishdirectory { Line 2144  sub publishdirectory {
  $rblksize,$rblocks)=stat($resdir.'/'.$filename);   $rblksize,$rblocks)=stat($resdir.'/'.$filename);
     if (($rmtime<$cmtime) || ($env{'form.forcerepub'})) {      if (($rmtime<$cmtime) || ($env{'form.forcerepub'})) {
 # previously published, modified now  # previously published, modified now
  $publishthis=1;                          if ($env{'form.excludemod'}) {
     }                              $skipthis='mod';
     my $meta_cmtime = (stat($fn.'/'.$filename.'.meta'))[9];                          } else {
     my $meta_rmtime = (stat($resdir.'/'.$filename.'.meta'))[9];                              $publishthis=1;
     if ( $meta_rmtime<$meta_cmtime ) {                          }
  $publishthis=1;  
     }      }
                       unless ($skipthis) {
                           my $meta_cmtime = (stat($fn.'/'.$filename.'.meta'))[9];
                           my $meta_rmtime = (stat($resdir.'/'.$filename.'.meta'))[9];
                           if ( $meta_rmtime<$meta_cmtime ) {
                               if ($env{'form.excludemodmeta'}) {
                                   $skipthis='modmeta';
                                   $publishthis=0;
                               } else {
                                   $publishthis=1;
                               }
                           } else {
                               unless (&Apache::loncommon::fileembstyle($extension) eq 'prv') {
                                   if ($commonaccess{'dist'}) {
                                       my ($currdist,$currdistfile,$currsourceavail);
                                       my $currdist =  &Apache::lonnet::metadata($thisdisresdir.'/'.$filename,'copyright');
                                       if ($currdist eq 'custom') {
                                           $currdistfile =  &Apache::lonnet::metadata($thisdisresdir.'/'.$filename,'customdistributionfile');
                                       }
                                       if ($env{'form.commondistselect'} eq 'custom') {
                                           if ($env{'form.commoncustomrights'} =~ m{^/res/.+\.rights$}) {
                                               if ($currdist eq 'custom') {
                                                   unless ($env{'form.commoncustomrights'} eq $currdistfile) {
                                                       $publishthis=1;
                                                   }
                                               } else {
                                                   $publishthis=1;
                                               }
                                           }
                                       } elsif ($env{'form.commondistselect'} =~ /^default|domain|public$/) {
                                           unless ($currdist eq $env{'form.commondistselect'}) {
                                               $publishthis=1;
                                           }
                                       }
                                   }
                               }
                           }
                       }
  } else {   } else {
 # never published  # never published
     $publishthis=1;                      if ($env{'form.excludeunpub'}) {
                           $skipthis='unpub';
                       } else {
                           $publishthis=1;
                       }
  }   }
   
  if ($publishthis) {   if ($publishthis) {
     &batchpublish($r,$fn.'/'.$filename,$resdir.'/'.$filename);      &batchpublish($r,$fn.'/'.$filename,$resdir.'/'.$filename);
  } else {   } else {
     $r->print('<br />'.&mt('Skipping').' '.$filename.'<br />');                      my $reason;
                       if ($skipthis) {
                           $reason = $reasons{$skipthis};
                       } else {
                           $reason = &mt('No changes needed to published resource or metadata');
                       }
                       $r->print('<br />'.&mt('Skipping').' '.$filename);
                       if ($reason) {
                           $r->print(' ('.$reason.')');
                       }
                       $r->print('<br />');
  }   }
  $r->rflush();   $r->rflush();
     }      }
Line 2014  sub defaultmetapublish { Line 2270  sub defaultmetapublish {
  $r->print($reply.'</p><br />');$r->rflush;   $r->print($reply.'</p><br />');$r->rflush;
     }      }
 # ------------------------------------------------------------------- Link back  # ------------------------------------------------------------------- Link back
     $r->print("<a href='".&Apache::lonnet::display($fn)."'>".&mt('Back to Metadata').'</a>');      $r->print("<a href='".&Apache::loncfile::display($fn)."'>".&mt('Back to Metadata').'</a>');
     $r->print(&Apache::loncommon::end_page());      $r->print(&Apache::loncommon::end_page());
     return OK;      return OK;
 }  }
Line 2078  sub handler { Line 2334  sub handler {
 # -------------------------------------------------------------- Check filename  # -------------------------------------------------------------- Check filename
   
     my $fn=&unescape($env{'form.filename'});      my $fn=&unescape($env{'form.filename'});
     ($cuname,$cudom)=&Apache::loncacc::constructaccess($fn);      ($cuname,$cudom)=&Apache::lonnet::constructaccess($fn);
 # ----------------------------------------------------- Do we have permissions?  # ----------------------------------------------------- Do we have permissions?
      unless (($cuname) && ($cudom)) {       unless (($cuname) && ($cudom)) {
        $r->log_reason($env{'user.name'}.' at '.$env{'user.domain'}.         $r->log_reason($env{'user.name'}.' at '.$env{'user.domain'}.
Line 2143  sub handler { Line 2399  sub handler {
     # Breadcrumbs      # Breadcrumbs
     &Apache::lonhtmlcommon::clear_breadcrumbs();      &Apache::lonhtmlcommon::clear_breadcrumbs();
     &Apache::lonhtmlcommon::add_breadcrumb({      &Apache::lonhtmlcommon::add_breadcrumb({
         'text'  => 'Construction Space',          'text'  => 'Authoring Space',
         'href'  => &Apache::loncommon::authorspace(),          'href'  => &Apache::loncommon::authorspace($fn),
     });      });
     &Apache::lonhtmlcommon::add_breadcrumb({      &Apache::lonhtmlcommon::add_breadcrumb({
         'text'  => 'Resource Publication',          'text'  => 'Resource Publication',
Line 2154  sub handler { Line 2410  sub handler {
     my $js='<script type="text/javascript">'.      my $js='<script type="text/javascript">'.
  &Apache::loncommon::browser_and_searcher_javascript().   &Apache::loncommon::browser_and_searcher_javascript().
  '</script>';   '</script>';
     $r->print(&Apache::loncommon::start_page('Resource Publication',$js)      my $startargs = {};
       if ($fn=~/\/$/) {
           unless ($env{'form.phase'} eq 'two') {
               $startargs->{'add_entries'} = { onload => 'javascript:setDefaultAccess();' };
               $js .= <<"END";
   <script type="text/javascript">
   // <![CDATA[
   function showHideAccess(caller,div) {
       if (document.getElementById(div)) {
           if (caller.checked) {
               document.getElementById(div).style.display='inline-block';
           } else {
               document.getElementById(div).style.display='none';
           }
       }
   }
   
   function showHideCustom(caller,divid) {
       if (document.getElementById(divid)) {
           if (caller.options[caller.selectedIndex].value == 'custom') {
               document.getElementById(divid).style.display="inline-block";
           } else {
               document.getElementById(divid).style.display="none";
           }
       }
   }
   function setDefaultAccess() {
       var chkids = Array('LC_commondist','LC_commonsource');
       for (var i=0; i<chkids.length; i++) {
           if (document.getElementById(chkids[i])) {
               document.getElementById(chkids[i]).checked = false;
           }
           if (document.getElementById(chkids[i]+'select')) {
              document.getElementById(chkids[i]+'select').selectedIndex = 0; 
           }
           if (document.getElementById(chkids[i]+'div')) {
               document.getElementById(chkids[i]+'div').style.display = 'none';
           }
       }
   }
   // ]]>
   </script>
   
   END
           }
       }
       $r->print(&Apache::loncommon::start_page('Resource Publication',$js,$startargs)
              .&Apache::lonhtmlcommon::breadcrumbs()               .&Apache::lonhtmlcommon::breadcrumbs()
              .&Apache::loncommon::head_subbox(               .&Apache::loncommon::head_subbox(
                   &Apache::loncommon::CSTR_pageheader()) # FIXME crumbs broken?                    &Apache::loncommon::CSTR_pageheader($docroot.$fn))
     );      );
   
     my $thisdisfn=&HTML::Entities::encode($fn,'<>&"');      my $thisdisfn=&HTML::Entities::encode($fn,'<>&"');
Line 2168  sub handler { Line 2470  sub handler {
     if ($fn=~/\/$/) {      if ($fn=~/\/$/) {
 # -------------------------------------------------------- This is a directory  # -------------------------------------------------------- This is a directory
  &publishdirectory($r,$docroot.$fn,$thisdisfn);   &publishdirectory($r,$docroot.$fn,$thisdisfn);
  $r->print('<hr /><a href="'.$thisdisfn.'">'.&mt('Return to Directory').'</a>');          $r->print(
               '<br /><br />'.
               &Apache::lonhtmlcommon::actionbox([
                   '<a href="'.$thisdisfn.'">'.&mt('Return to Directory').'</a>']));
     } else {      } else {
 # ---------------------- Evaluate individual file, and then output information.  # ---------------------- Evaluate individual file, and then output information.
  $fn=~/\.(\w+)$/;   $fn=~/\.(\w+)$/;
Line 2218  ENDCAPTION Line 2523  ENDCAPTION
             $r->print(&Apache::lonhtmlcommon::row_closure()              $r->print(&Apache::lonhtmlcommon::row_closure()
                      .&Apache::lonhtmlcommon::row_title(&mt('Diffs')));                       .&Apache::lonhtmlcommon::row_title(&mt('Diffs')));
     $r->print(<<ENDDIFF);      $r->print(<<ENDDIFF);
 <a href='javascript:void(window.open("/adm/diff?filename=$thisdisfn&versiontwo=priv","cat","height=300,width=500,scrollbars=1,resizable=1,menubar=0,location=1"))'>  <a href='javascript:void(window.open("/adm/diff?filename=$thisdisfn&amp;versiontwo=priv","cat","height=300,width=500,scrollbars=1,resizable=1,menubar=0,location=1"))'>
 ENDDIFF  ENDDIFF
             $r->print(&mt('Diffs with Current Version').'</a>');              $r->print(&mt('Diffs with Current Version').'</a>');
  }   }
Line 2260  __END__ Line 2565  __END__
   
 =back  =back
   
 =back  
   
 =cut  =cut
   

Removed from v.1.273  
changed lines
  Added in v.1.295.2.1.2.2


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>