Parent Directory
|
Revision Log
Problem Editor now creates a temporary file to edit ( adding .tmp to the file name) Refresh causes a redirect to the Problem.pm with a GET command. Some of the arguments are unnecessary and need to be cleaned up. The seed and display mode in the problem editor are not properly initialized from the problem set. Problem.pm has been modified to check for these arguments and to read the temporary source file, seed and displayMode. These are passed through to a PG.pm object. PG also needed to be modified so that the source_file and seed values are overridden
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->{ce}->{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->{ce}->{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 $seed = ($r->param('seed')) ? $r->param('seed') : ''; 47 my $displayMode = ($r->param('displayMode')) ? $r->param('displayMode') : ''; 48 49 my $viewURL = "http://$hostname:$port"; 50 $viewURL .= "/webwork/$courseName/$setName/$problemNumber/?"; 51 $viewURL .= $self->url_authen_args; 52 $viewURL .= "&displayMode=$displayMode&seed=$seed"; # optional displayMode and seed overrides 53 $viewURL .= "&editMode=temporaryFile"; 54 $viewURL .= '&sourceFilePath='.$self->{ce}->{currentSourceFilePath}; # path to pg text for viewing 55 $viewURL .= "&submit_button=$submit_button"; # allows Problem.pg to recognize state 56 $viewURL .= '&editErrors='.$self->{ce}->{editErrors}; # of problem being viewed. 57 $r->header_out(Location => $viewURL ); 58 return REDIRECT; 59 } else { 60 # initialize and 61 # display the editing window 62 63 $self->SUPER::go(@_); 64 } 65 66 } 67 68 69 sub body { 70 my $self = shift; 71 72 # test area 73 my $r = $self->{r}; 74 my $db = $self->{db}; 75 my $ce = $self->{ce}; 76 my $user = $r->param('user'); 77 my $key = $db->getKey($user)->key(); 78 79 80 ################ 81 # Gathering info 82 # What is needed 83 # $problemPath -- 84 # $formURL -- given by $r->uri 85 # $tmpProblemPath 86 #my ($problemPath,$formURL,$tmpProblemPath) = $self->initialize(); 87 my $problemPath = $ce->{problemPath}; 88 89 #my $tmpProblemPath = $ce->{tmpProblemPath}; 90 91 92 93 94 95 96 my $header = "Problem Editor: $problemPath"; 97 98 ######################################################################### 99 # Find the text for the problem, either in the tmp file, if it exists 100 # or in the original file in the template directory 101 ######################################################################### 102 my $problemContents = ''; 103 # my $editMode = (defined($r->param('problemContents')))? 104 # 'tmpMode':'startMode'; 105 # 106 # if ( $editMode eq 'tmpMode') { 107 # $problemContents = $r->param('problemContents'); 108 # 109 # } else{ 110 eval { $problemContents = WeBWorK::Utils::readFile($problemPath) }; # try to read file 111 $problemContents = $@ if $@; 112 # } 113 114 # save Action FIXME -- is this the write place for this? 115 # my $actionString = ''; 116 # if ($r->param('submit') eq 'Save') { 117 # $actionString = "File saved to $problemPath"; 118 # #FIXME it would be MUCH better to work with temporary files 119 # open(FILE,">$problemPath") or die "Can't open $problemPath"; 120 # print FILE $problemContents; 121 # close(FILE); 122 # 123 # } 124 125 126 127 128 ######################################################################### 129 # Format the page 130 ######################################################################### 131 # Define parameters for textarea 132 # FIXME these parameters should be capable of being updated dynamically. 133 my $rows = 20; 134 my $columns = 80; 135 my $mode_list = ['HTML', 'HTML_tth','HTML_dpng', 'Latex2HTML']; 136 my $mode = ( defined($r->param('mode')) ) ? $r->param('mode') : 'HTML_tth'; 137 my $seed = ( defined($r->param('seed')) ) ? $r->param('seed') : '1234'; 138 my $uri = $r->uri; 139 ######################################################################## 140 # Define a link to view the problem 141 #FIXME 142 143 ######################################################################### 144 145 146 147 148 149 return CGI::p($header), 150 #CGI::start_form("POST",$r->uri,-target=>'_problem'), doesn't pass on the target parameter??? 151 qq!<form method="POST" action="$uri" enctype="application/x-www-form-urlencoded", target="_problem">!, 152 $self->hidden_authen_fields, 153 CGI::div( 154 CGI::textfield(-name=>'seed',-value=>$seed), 155 'Mode: ', 156 CGI::popup_menu(-name=>'mode', -'values'=>$mode_list, 157 -default=>$mode), 158 CGI::a( 159 {-href=>'http://webwork.math.rochester.edu/docs/docs/pglanguage/manpages/',-target=>"manpage_window"}, 160 'Manpages', 161 ) 162 ), 163 CGI::p( 164 CGI::textarea(-name => 'problemContents', -default => $problemContents, 165 -rows => $rows, -columns => $columns, -override => 1, 166 ), 167 ), 168 CGI::p( 169 CGI::submit(-value=>'Refresh',-name=>'submit'), 170 CGI::submit(-value=>'Save',-name=>'submit'), 171 # $actionString 172 ), 173 174 #CGI::a({-href=>$ce->{viewProblemURL},-target=>'_viewProblem'},'view problem'), 175 CGI::end_form(), 176 "<p> the parameters passed are " #FIXME -- debugging code 177 . join("<BR>", %{$r->param()}) . 178 "</p> and the gatheredInfo is ", 179 "problemPath=$problemPath<br> formURL=".$r->uri . "<br>" , 180 # "viewProblemURL ".$ce->{viewProblemURL}."<br>", 181 # "problem_obj =". $ce->{problem_obj}."<br>", 182 "path_components ". $ce->{path_components}.'<br>', 183 # "hostname =$hostname<br>", 184 # "port =$port <br>", 185 "uri = $uri <br>", 186 # "viewURL =".$ce->{viewURL}."<br>", 187 188 ; 189 190 191 } 192 193 sub initialize { 194 195 my ($self, $setName, $problemNumber) = @_; 196 my $ce = $self->{ce}; 197 my $r = $self->{r}; 198 my $path_info = $r->path_info || ""; 199 my $db = $self->{db}; 200 my $user = $r->param('user'); 201 my $effectiveUserName = $r->param('effectiveUser'); 202 my $courseName = $ce->{courseName}; 203 204 my $set = $db->getGlobalUserSet($effectiveUserName, $setName); 205 my $setID = $set->set_id; 206 207 # Find URL for viewing problem 208 # my $viewProblemURL = "/webwork/$courseName/".join("/",$setID,$problemNumber)."?" .$self->url_authen_args(); 209 210 # find path to pg file for the problem 211 # FIXME there is a descrepency in the way that the problems are found. 212 # my $problem_record = $db->getUserProblem($user,$setID,1); 213 my $problem_record = $db->getGlobalUserProblem($effectiveUserName, $setName, $problemNumber); 214 my $templateDirectory = $ce->{courseDirs}->{templates}; 215 my $problemPath = $templateDirectory."/".$problem_record->source_file; 216 my $editFileSuffix = 'tmp'; 217 my $submit_button = $r->param('submit'); 218 219 my $problemContents = ''; 220 my $currentSourceFilePath = ''; 221 # update the .pg and .pg.tmp files in the directory 222 if (not defined($submit_button) ) { 223 # this is a fresh editing job 224 # copy the pg file to a new file with the same name with .tmp added 225 # store this name in the $ce->currentSourceFilePath for use in body 226 227 eval { $problemContents = WeBWorK::Utils::readFile($problemPath) 228 }; # try to read file 229 $problemContents = $@ if $@; 230 $currentSourceFilePath = "$problemPath.$editFileSuffix"; 231 $ce->{currentSourceFilePath} = $currentSourceFilePath; 232 } elsif ($submit_button eq 'Refresh' ) { 233 # grab the problemContents from the form and save it to the tmp file 234 # store tmp file name in the $ce->currentSourceFilePath for use in body 235 236 $problemContents = $r->param('problemContents'); 237 $currentSourceFilePath = "$problemPath.$editFileSuffix"; 238 $ce->{currentSourceFilePath} = $currentSourceFilePath; 239 } elsif ($submit_button eq 'Save') { 240 # grab the problemContents from the form and save it to the permanent file 241 # unlink (delete) the temporary file 242 # store the permanent file name in the $ce->problemContents for use in body 243 244 $problemContents = $r->param('problemContents'); 245 $currentSourceFilePath = "$problemPath"; 246 $ce->{currentSourceFilePath} = $currentSourceFilePath; 247 } else { 248 # give a warning 249 die "Unrecognized submit command $submit_button"; 250 } 251 # print changed pg files 252 # FIXME make sure that the permissions are set correctly!!! 253 # Make sure that the warning is being transmitted properly. 254 eval { 255 local *OUTPUTFILE; 256 open OUTPUTFILE, ">", $currentSourceFilePath 257 or die "Failed to write to $currentSourceFilePath: $!"; 258 print OUTPUTFILE $problemContents; 259 close OUTPUTFILE; 260 }; 261 my $errors = $@ if $@; 262 if ( $errors) { 263 264 $ce->{editErrors} = "Unable to write to $currentSourceFilePath: $errors"; 265 266 } else { # unlink the temporary file if there are no errors. 267 $ce->{editErrors} = ''; 268 unlink("$problemPath.$editFileSuffix") if defined($submit_button) and $submit_button eq 'Save'; 269 270 }; 271 272 273 # return values. FIXME -- is this the right way to pass the values to body?? 274 # $ce->{viewProblemURL} = $viewProblemURL; 275 $ce->{problemPath} = $problemPath; 276 $ce->{path_components} = join("/",$setID,$problemNumber); 277 278 # FIXME there is no way to edit in a temporary file -- all editing takes place on disk!!! 279 280 281 282 } 283 284 # sub gatherProblemList { #workaround for obtaining the definition of a problem set (awaiting implementation of db function) 285 # my $self = shift; 286 # my $setName = shift; 287 # my $output = ""; 288 # if ( defined($setName) and $setName ne "" ) { 289 # my $templateDirectory = $self->{ce}->{courseDirs}->{templates}; 290 # my $fileName = "$templateDirectory/$setName.def"; 291 # my @output = split("\n",WeBWorK::Utils::readFile($fileName) ); 292 # @output = grep /\.pg/, @output; # only get the .pg files 293 # @output = grep !/Header/, @output; # eliminate header files 294 # $output = join("\n",@output); 295 # } else { 296 # $output = "No set name |$setName| is defined"; 297 # } 298 # 299 # 300 # return $output 301 # 302 # 303 # 304 # 305 # } 306 # sub fetchSetDirectories { 307 # 308 # my $self = shift; 309 # my $defaultChoice = shift; 310 # my $templateDirectory = $self->{ce}->{courseDirs}->{templates}; 311 # opendir SETDEFDIR, $templateDirectory 312 # or return "Can't open directory $templateDirectory"; 313 # 314 # my @allFiles = grep !/^\./, readdir SETDEFDIR; 315 # closedir SETDEFDIR; 316 # 317 # ## filter to find only the set directories 318 # ## -- it is assumed that these directories don't contain a period in their names 319 # ## and that all other files do. Directories names must also begin with "set". 320 # ## A better plan would be to read only the names of directories, not files. 321 # 322 # ## sort the directories 323 # my @setDefFiles = grep /^set[^\.]*$/, @allFiles; 324 # my @sortedNames = sort @setDefFiles; 325 # 326 # return "$libraryName/" . CGI::br(). CGI::popup_menu(-name=>'setDirectory', -size=>$rowheight, 327 # -values=>\@sortedNames, -default=>$defaultChoice ) .CGI::br() ; 328 # } 329 # 330 # sub fetchPGproblems { 331 # 332 # my $self = shift; 333 # my $setDirectory = shift; 334 # 335 # # Handle default for setDirectory 336 # # fix me -- this is not bullet proof 337 # $setDirectory = "set0" unless defined($setDirectory); 338 # my $templateDirectory = $self->{ce}->{courseDirs}->{templates}; 339 # 340 # ## 341 # opendir SETDEFDIR, "$templateDirectory/$setDirectory" 342 # or return "Can't open directory $templateDirectory/$setDirectory"; 343 # 344 # my @allFiles = grep !/^\./, readdir SETDEFDIR; 345 # closedir SETDEFDIR; 346 # 347 # ## filter to find only pg problems 348 # ## Some problems are themselves in directories (if they have auxiliary 349 # ## .png's for example. This eventuallity needs to be handled. 350 # 351 # ## sort the directories 352 # my @pgFiles = grep /\.pg$/, @allFiles; 353 # my @sortedNames = sort @pgFiles; 354 # 355 # return "$setDirectory ". CGI::br() . 356 # CGI::popup_menu(-name=>'pgProblem', -size=>$rowheight, -multiple=>undef, -values=>\@sortedNames, ) . 357 # CGI::br() ; 358 # } 359 360 1;
| aubreyja at gmail dot com | ViewVC Help |
| Powered by ViewVC 1.0.9 |