[system] / branches / rel-2-3-dev / webwork2 / lib / WeBWorK / ContentGenerator / Instructor / PGProblemEditor.pm Repository:
ViewVC logotype

View of /branches/rel-2-3-dev/webwork2/lib/WeBWorK/ContentGenerator/Instructor/PGProblemEditor.pm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1363 - (download) (as text) (annotate)
Fri Jul 11 19:52:42 2003 UTC (9 years, 11 months ago) by gage
Original Path: trunk/webwork2/lib/WeBWorK/ContentGenerator/Instructor/PGProblemEditor.pm
File size: 13069 byte(s)
Cosmetic changes to title
--Mike

    1 package WeBWorK::ContentGenerator::Instructor::PGProblemEditor;
    2 use base qw(WeBWorK::ContentGenerator::Instructor);
    3 
    4 
    5 =head1 NAME
    6 
    7 WeBWorK::ContentGenerator::Instructor::ProblemSetEditor - Edit a set definition list
    8 
    9 =cut
   10 
   11 use strict;
   12 use warnings;
   13 use CGI qw();
   14 use WeBWorK::Utils qw(readFile);
   15 use Apache::Constants qw(:common REDIRECT);
   16 
   17 
   18 our $libraryName;
   19 our $rowheight;
   20 
   21 sub title {
   22   my $self = shift;
   23   #FIXME  don't need the entire path  ??
   24   return "Instructor Tools - PG Problem Editor for ". $self->{problemPath};
   25 }
   26 sub go {
   27   my $self      = shift;
   28   my ($setName, $problemNumber) = @_;
   29   my $r         =   $self->{r};
   30   my $ce        = $self->{ce};
   31   my $submit_button   = $r->param('submit');  # obtain submit command from form
   32 
   33   # various actions depending on state.
   34   if (     defined($submit_button) and ($submit_button eq 'Save' or $submit_button eq 'Refresh')    ) {
   35 
   36     $self->initialize($setName,$problemNumber);  # write the necessary files
   37                            # return file path for viewing problem
   38                            # in $self->{currentSourceFilePath}
   39     #redirect to view the problem
   40 
   41     my $hostname    =   $r->hostname();
   42     my $port        =   $r->get_server_port();
   43     my $uri       =   $r->uri;
   44     my $courseName    = $self->{ce}->{courseName};
   45     my $editFileSuffix  = $self->{ce}->{editFileSuffix};
   46     my $problemSeed   =   ($r->param('problemSeed')) ? $r->param('problemSeed') : '';
   47     my $displayMode   = ($r->param('displayMode')) ? $r->param('displayMode') : '';
   48         my $viewURL         =   '';
   49         if ($self->{file_type} eq 'problem') {
   50           # redirect to have problem read by Problem.pm
   51       $viewURL      =   "http://$hostname:$port";
   52       $viewURL       .=   $ce->{webworkURLs}->{root}."/$courseName/$setName/$problemNumber/?";
   53       $viewURL       .= $self->url_authen_args;
   54       $viewURL       .=   "&displayMode=$displayMode&problemSeed=$problemSeed";   # optional displayMode and problemSeed overrides
   55       if ($submit_button eq 'Save') {
   56         $viewURL       .= "&editMode=savedFile";
   57       } else {
   58         $viewURL       .= "&editMode=temporaryFile";
   59       }
   60       $viewURL       .= '&sourceFilePath='. $self->{currentSourceFilePath}; # path to pg text for viewing
   61       #$viewURL      .= "&submit_button=$submit_button";                   # allows Problem.pg to recognize state
   62   #   $viewURL       .=   '&editErrors='.$self->{editErrors};
   63                                                                                      # of problem being viewed.
   64       } elsif ($self->{file_type} eq 'set_header') {
   65         # redirect set headers to ProblemList page
   66         $viewURL      =   "http://$hostname:$port";
   67       $viewURL       .=   $ce->{webworkURLs}->{root}."/$courseName/$setName/?";
   68       $viewURL       .= $self->url_authen_args;
   69       $viewURL       .=   "&displayMode=$displayMode&problemSeed=$problemSeed";   # optional displayMode and problemSeed overrides
   70       if ($submit_button eq 'Save') {
   71         $viewURL       .= "&editMode=savedFile";
   72       }
   73     }
   74     $r->header_out(Location => $viewURL );
   75     return REDIRECT;
   76   } else {
   77     # initialize and
   78     # display the editing window
   79 
   80     $self->SUPER::go(@_);
   81   }
   82 
   83 }
   84 
   85 sub initialize {
   86 
   87   my ($self, $setName, $problemNumber) = @_;
   88   my $ce            =   $self->{ce};
   89   my $r           = $self->{r};
   90   my $path_info         =   $r->path_info || "";
   91   my $db            = $self->{db};
   92   my $user          = $r->param('user');
   93   my $effectiveUserName   = $r->param('effectiveUser');
   94   my $courseName        = $ce->{courseName};
   95 
   96 #   FIXME -- sometimes this doesn't find a set
   97 # my $set                 =   $db->getMergedSet($effectiveUserName, $setName);
   98 # my $setID         = $set->set_id;
   99 
  100   # Find URL for viewing problem
  101 
  102   # find path to pg file for the problem
  103 
  104   my $templateDirectory   = $ce->{courseDirs}->{templates};
  105   my $problemPath             =   $templateDirectory;
  106   my $problem_record          =   undef;
  107     # FIXME  there is a discrepancy in the way that the problems are found.
  108     # FIXME  more error checking is needed in case the problem doesn't exist.
  109   if (defined($problemNumber) and $problemNumber) {
  110     $problem_record   = $db->getMergedProblem($effectiveUserName, $setName, $problemNumber);
  111     # If there is no global_user defined problem, (i.e. the sets haven't been assigned yet),
  112     # look for a global version of the problem.
  113     $problem_record     = $db->getGlobalProblem($setName, $problemNumber) unless defined($problem_record);
  114     # bail if no problem is found
  115     die "Cannot find a problem record for set $setName / problem $problemNumber"
  116       unless defined($problem_record);
  117     $problemPath           .=   '/'.$problem_record->source_file;
  118     $self->{file_type}      =   'problem';
  119   } elsif (defined($problemNumber) and $problemNumber==0) { # we are editing a header file
  120     my $set_record          =   $db->getMergedSet($effectiveUserName, $setName);
  121     die "Cannot find a set record for set $setName" unless defined($set_record);
  122     $problemPath           .=   '/'.$set_record->set_header;
  123     $self->{file_type}      =   'set_header';
  124   }
  125 
  126   my $editFileSuffix      = 'tmp';
  127   my $submit_button     =   $r->param('submit');
  128 
  129   my $displayMode         =   ( defined($r->param('displayMode'))   ) ? $r->param('displayMode') : $ce->{pg}->{options}->{displayMode};
  130   # try to get problem seed from the input parameter, or from the problem record
  131   my $problemSeed;
  132   if ( defined($r->param('problemSeed'))  ) {
  133     $problemSeed            =   $r->param('problemSeed');
  134   } elsif (defined($problem_record) and  $problem_record->can('problem_seed')) {
  135     $problemSeed            =   $problem_record->problem_seed;
  136   }
  137   # make absolutely sure that the problem seed is defined, if it hasn't been.
  138   $problemSeed        = '123456' unless defined($problemSeed) and $problemSeed =~/\S/;
  139 
  140   my $problemContents = '';
  141   my $currentSourceFilePath = '';
  142   my $editErrors = '';
  143   # update the .pg and .pg.tmp files in the directory
  144   if (not defined($submit_button) ) {
  145     # this is a fresh editing job
  146     # copy the pg file to a new file with the same name with .tmp added
  147     # store this name in the $self->currentSourceFilePath for use in body
  148 
  149     eval { $problemContents     = WeBWorK::Utils::readFile($problemPath)
  150     };  # try to read file
  151     $problemContents = $@ if $@;
  152     $editErrors .= $problemContents;
  153     $currentSourceFilePath      = "$problemPath.$editFileSuffix";
  154     $self->{currentSourceFilePath}  = $currentSourceFilePath;
  155   } elsif ($submit_button eq 'Refresh' ) {
  156     # grab the problemContents from the form in order to save it to the tmp file
  157     # store tmp file name in the $self->currentSourceFilePath for use in body
  158 
  159     $problemContents        = $r->param('problemContents');
  160     $currentSourceFilePath      = "$problemPath.$editFileSuffix";
  161     $self->{currentSourceFilePath}  = $currentSourceFilePath;
  162   } elsif ($submit_button eq 'Save') {
  163     # grab the problemContents from the form in order to save it to the permanent file
  164     # later we will unlink (delete) the temporary file
  165     # store permanent file name in the $self->currentSourceFilePath for use in body
  166 
  167     $problemContents        = $r->param('problemContents');
  168     $currentSourceFilePath      = "$problemPath";
  169     $self->{currentSourceFilePath}  = $currentSourceFilePath;
  170   } else {
  171     # give a warning
  172     die "Unrecognized submit command $submit_button";
  173   }
  174 
  175   # Handle the problem of line endings.  Make sure that all of the line endings.  Convert \r\n to \n
  176   $problemContents    =~    s/\r\n/\n/g;
  177   $problemContents    =~    s/\r/\n/g;
  178 
  179   # print changed pg files
  180   # FIXME  make sure that the permissions are set correctly!!!
  181   # Make sure that the warning is being transmitted properly.
  182 
  183   eval {
  184     local *OUTPUTFILE;
  185     open OUTPUTFILE, ">", $currentSourceFilePath
  186         or die "Failed to write to $currentSourceFilePath.
  187         It is likely that the permissions in the template directory have not been set correctly.".
  188         "The web server must be able to create and write to files in the directory containing the problem.
  189         $!";
  190     print OUTPUTFILE $problemContents;
  191     close OUTPUTFILE;
  192   };
  193   # record an error string for later use if there was a difficulty in writing to the file
  194   # FIXME is this string every inspected?
  195 
  196   my $openTempFileErrors = $@ if $@;
  197 
  198   if (  $openTempFileErrors)   {
  199 
  200     $self->{openTempFileErrors} = "Unable to write to $currentSourceFilePath: $openTempFileErrors";
  201     #diagnose errors:
  202     warn "Editing errors: $openTempFileErrors\n";
  203     warn "The file $currentSourceFilePath exists. \n " if -e $currentSourceFilePath; #FIXME
  204     warn "The file $currentSourceFilePath cannot be found. \n " unless -e $currentSourceFilePath;
  205     warn "The file $currentSourceFilePath does not have write permissions. \n"
  206                      if -e $currentSourceFilePath and not -w $currentSourceFilePath;
  207 
  208 
  209 
  210   } else {
  211     # unlink the temporary file if there are no errors and the save button has been pushed
  212 
  213     $self->{openTempFileErrors} = '';
  214     unlink("$problemPath.$editFileSuffix") if defined($submit_button) and $submit_button eq 'Save';
  215   };
  216 
  217 
  218   # return values for use in the body subroutine
  219   $self->{problemPath}    =   $problemPath;
  220   $self->{displayMode}    =   $displayMode;
  221   $self->{problemSeed}    =   $problemSeed;
  222 
  223   # FIXME  there is no way to edit in a temporary file -- all editing takes place on disk!!!
  224 
  225 
  226 
  227 }
  228 
  229 sub path {
  230   my $self          = shift;
  231   my $set_id        = shift;
  232   my $problem_id    = shift;
  233   my $args          = $_[-1];
  234 
  235   my $ce = $self->{ce};
  236   my $root = $ce->{webworkURLs}->{root};
  237   my $courseName = $ce->{courseName};
  238   return $self->pathMacro($args,
  239     "Home"          => "$root",
  240     $courseName     => "$root/$courseName",
  241     'instructor'    => "$root/$courseName/instructor",
  242     'sets'          => "$root/$courseName/instructor/sets/",
  243     "$set_id"   => "$root/$courseName/instructor/sets/$set_id/",
  244     "problems"      => "$root/$courseName/instructor/sets/$set_id/problems",
  245     "$problem_id"   => ''
  246   );
  247 }
  248 sub body {
  249   my $self = shift;
  250 
  251   # test area
  252   my $r       =   $self->{r};
  253   my $db      =   $self->{db};
  254   my $ce      =   $self->{ce};
  255   my $user    =   $r->param('user');
  256   my $key     =   $db->getKey($user)->key();
  257 
  258 
  259   ################
  260   # Gathering info
  261   # What is needed
  262   #     $problemPath  --
  263   #     $formURL -- given by $r->uri
  264   #     $tmpProblemPath
  265   my $problemPath   =   $self->{problemPath};
  266 
  267 
  268 
  269 
  270 
  271 
  272 
  273   my $header = "Editing problem:  $problemPath";
  274 
  275   #########################################################################
  276   # Find the text for the problem, either in the tmp file, if it exists
  277   # or in the original file in the template directory
  278   #########################################################################
  279   my $problemContents = '';
  280 
  281   eval { $problemContents = WeBWorK::Utils::readFile($problemPath)  };  # try to read file
  282   $problemContents = $@ if $@;
  283 
  284 
  285 
  286   #########################################################################
  287   # Format the page
  288   #########################################################################
  289   # Define parameters for textarea
  290   # FIXME
  291   # Should the seed be set from some particular user instance??
  292   # The mode list should be obtained from global.conf ultimately
  293   my $rows    =   20;
  294   my $columns   =   80;
  295   my $mode_list   =   ['plainText','formattedText','images'];
  296   my $displayMode =   $self->{displayMode};
  297   my $problemSeed = $self->{problemSeed};
  298   my $uri     = $r->uri;
  299   ########################################################################
  300   # Define a link to view the problem
  301   #FIXME
  302 
  303   #########################################################################
  304 
  305 
  306   warn "Errors in the problem ".CGI::br().$self->{editErrors} if $self->{editErrors};
  307 
  308 
  309   return CGI::p($header),
  310     #CGI::start_form("POST",$r->uri,-target=>'_problem'),  doesn't pass on the target parameter???
  311     qq!<form method="POST" action="$uri" enctype="application/x-www-form-urlencoded", target="_problem">!,
  312     $self->hidden_authen_fields,
  313     CGI::hidden(-name=>'file_type',-default=>$self->{file_type}),
  314     CGI::div(
  315     'Seed: ',
  316     CGI::textfield(-name=>'problemSeed',-value=>$problemSeed),
  317     'Mode: ',
  318     CGI::popup_menu(-name=>'displayMode', -'values'=>$mode_list,
  319                            -default=>$displayMode),
  320     CGI::a(
  321       {-href=>'http://webwork.math.rochester.edu/docs/docs/pglanguage/manpages/',-target=>"manpage_window"},
  322       'Manpages',
  323       )
  324     ),
  325     CGI::p(
  326       CGI::textarea(-name => 'problemContents', -default => $problemContents,
  327               -rows => $rows, -columns => $columns, -override => 1,
  328       ),
  329     ),
  330     CGI::p(
  331       ( ($self->{file_type} eq 'problem') ? CGI::submit(-value=>'Refresh',-name=>'submit') : ''   ),
  332       CGI::submit(-value=>'Save',-name=>'submit'),
  333 #     $actionString
  334     ),
  335 
  336     #CGI::a({-href=>$ce->{viewProblemURL},-target=>'_viewProblem'},'view problem'),
  337     CGI::end_form(),
  338 #   "<p> the parameters passed are "  #FIXME -- debugging code
  339 #   . join("<BR>", %{$r->param()}) .
  340 #   "</p> and the gatheredInfo is ",
  341 #   "problemPath=$problemPath<br> formURL=".$r->uri . "<br>"   ,
  342 #   "viewProblemURL ".$ce->{viewProblemURL}."<br>",
  343 #   "problem_obj =". $ce->{problem_obj}."<br>",
  344 #   "path_components ". $ce->{path_components}.'<br>',
  345 #     "hostname =$hostname<br>",
  346 #     "port =$port <br>",
  347 #     "uri = $uri <br>",
  348 #     "viewURL =".$ce->{viewURL}."<br>",
  349 
  350   ;
  351 
  352 
  353 }
  354 
  355 
  356 
  357 1;

aubreyja at gmail dot com
ViewVC Help
Powered by ViewVC 1.0.9