Parent Directory
|
Revision Log
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 |