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