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

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

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

Revision 1747 Revision 2054
1################################################################################ 1################################################################################
2# WeBWorK Online Homework Delivery System 2# WeBWorK Online Homework Delivery System
3# Copyright © 2000-2003 The WeBWorK Project, http://openwebwork.sf.net/ 3# Copyright © 2000-2003 The WeBWorK Project, http://openwebwork.sf.net/
4# $CVSHeader: webwork-modperl/lib/WeBWorK/ContentGenerator/Instructor/PGProblemEditor.pm,v 1.22 2003/12/12 02:24:30 gage Exp $ 4# $CVSHeader: webwork-modperl/lib/WeBWorK/ContentGenerator/Instructor/PGProblemEditor.pm,v 1.29 2004/05/06 21:53:41 jj Exp $
5# 5#
6# This program is free software; you can redistribute it and/or modify it under 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 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 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. 9# version, or (b) the "Artistic License" which comes with this package.
27use strict; 27use strict;
28use warnings; 28use warnings;
29use CGI qw(); 29use CGI qw();
30use WeBWorK::Utils qw(readFile); 30use WeBWorK::Utils qw(readFile);
31use Apache::Constants qw(:common REDIRECT); 31use Apache::Constants qw(:common REDIRECT);
32use HTML::Entities;
33use WeBWorK::Utils::Tasks qw(fake_set fake_problem);
32 34
35###########################################################
36# This editor will edit problem files or set header files or files, such as course_info
37# whose name is defined in the global.conf database
38#
39# Only files under the template directory ( or linked to this location) can be edited.
40#
41# The course information and problems are located in the course templates directory.
42# Course information has the name defined by courseFiles->{course_info}
43#
44# Only files under the template directory ( or linked to this location) can be edited.
45#
46# editMode = temporaryFile (view the temp file defined by course_info.txt.user_name.tmp
47# instead of the file course_info.txt)
48# The editFileSuffix is "user_name.tmp" by default. It's definition should be moved to Instructor.pm #FIXME
49###########################################################
33 50
34our $libraryName; 51#our $libraryName;
35our $rowheight; 52#our $rowheight;
53
54sub pre_header_initialize {
55 my ($self) = @_;
56 my $r = $self->r;
57 my $ce = $r->ce;
58 my $urlpath = $r->urlpath;
59
60 my $submit_button = $r->param('submit'); # obtain submit command from form
61 my $file_type = $r->param("file_type") || '';
62
63 # Save problem to permanent or temporary file, then redirect for viewing
64 if (defined($submit_button) and
65 ($submit_button eq 'Save' or $submit_button eq 'Refresh'
66 or ($submit_button eq 'Save as' and $file_type eq 'problem'))) {
67 my $setName = $r->urlpath->arg("setID");
68 my $problemNumber = $r->urlpath->arg("problemID");
69
70 # write the necessary files
71 # return file path for viewing problem in $self->{currentSourceFilePath}
72 # obtain the appropriate seed
73 $self->saveFileChanges($setName, $problemNumber);
74
75 ##### calculate redirect URL based on file type #####
76
77 # get some information
78 #my $hostname = $r->hostname();
79 #my $port = $r->get_server_port();
80 #my $uri = $r->uri;
81 my $courseName = $urlpath->arg("courseID");
82 my $problemSeed = ($r->param('problemSeed')) ? $r->param('problemSeed') : '';
83 my $displayMode = ($r->param('displayMode')) ? $r->param('displayMode') : '';
84
85 my $viewURL = '';
86
87 if($self->{file_type} eq 'problem') {
88 if($submit_button eq 'Save as') { # redirect to myself
89 my $sourceFile = $self->{problemPath};
90 # strip off template directory prefix
91 my $edit_level = $r->param("edit_level") || 0;
92 $edit_level++;
93 $sourceFile =~ s|^$ce->{courseDirs}->{templates}/||;
94 my $problemPage = $urlpath->newFromModule("WeBWorK::ContentGenerator::Instructor::PGProblemEditor",
95 courseID => $courseName, setID => 'Undefined_Set', problemID => $problemNumber);
96 $viewURL = $self->systemLink($problemPage,
97params=>{sourceFilePath => $sourceFile, edit_level=>$edit_level});
98 } else { # other problems redirect to Problem.pm
99 my $problemPage = $urlpath->newFromModule("WeBWorK::ContentGenerator::Problem",
100 courseID => $courseName, setID => $setName, problemID => $problemNumber);
101 $viewURL = $self->systemLink($problemPage,
102 params => {
103 displayMode => $displayMode,
104 problemSeed => $problemSeed,
105 editMode => ($submit_button eq "Save" ? "savedFile" : "temporaryFile"),
106 sourceFilePath => $self->{currentSourceFilePath},
107 submiterror => $self->{submiterror},
108 }
109 );
110 }
111 }
112
113 # set headers redirect to ProblemSet.pm
114 $self->{file_type} eq 'set_header' and do {
115 my $problemSetPage = $urlpath->newFromModule("WeBWorK::ContentGenerator::ProblemSet",
116 courseID => $courseName, setID => $setName);
117 $viewURL = $self->systemLink($problemSetPage,
118 params => {
119 displayMode => $displayMode,
120 problemSeed => $problemSeed,
121 editMode => ($submit_button eq "Save" ? "savedFile" : "temporaryFile"),
122 }
123 );
124 };
125
126 # course info redirects to ProblemSets.pm
127 $self->{file_type} eq 'course_info' and do {
128 my $problemSetsPage = $urlpath->newFromModule("WeBWorK::ContentGenerator::ProblemSets",
129 courseID => $courseName);
130 $viewURL = $self->systemLink($problemSetsPage,
131 params => {
132 editMode => ($submit_button eq "Save" ? "savedFile" : "temporaryFile"),
133 }
134 );
135 };
136
137 if ($viewURL) {
138 $self->reply_with_redirect($viewURL);
139 } else {
140 die "Invalid file_type ", $self->{file_type}, " specified by saveFileChanges";
141 }
142 }
143}
144
145sub initialize {
146 my ($self) = @_;
147 my $r = $self->r;
148
149 my $setName = $r->urlpath->arg("setID");
150 my $problemNumber = $r->urlpath->arg("problemID");
151
152 # if we got to initialize(), then saveFileChanges was not called in pre_header_initialize().
153 # therefore we call it here:
154 $self->saveFileChanges($setName, $problemNumber);
155}
36 156
37sub title { 157sub title {
38 my $self = shift; 158 my $self = shift;
39 #FIXME don't need the entire path ?? 159 my $r = $self->r;
40 return "Instructor Tools - PG Problem Editor "; 160 my $problemNumber = $r->urlpath->arg("problemID");
161 my $file_type = $self->{'file_type'} || '';
162 return "Set Header" if($file_type eq 'set_header');
163 return "Course Information" if($file_type eq 'course_info');
164 return 'Problem ' . $r->{urlpath}->name;
41} 165}
42 166
43sub header { #FIXME this should be moved up to ContentGenerator 167sub body {
44 my $self = shift; 168 my ($self) = @_;
45 return REDIRECT if $self->{noContent};
46 my $r = $self->{r}; 169 my $r = $self->r;
47 $r->content_type('text/html'); 170 my $db = $r->db;
48 $r->send_http_header(); 171 my $ce = $r->ce;
49 return OK; 172
173 # Gathering info
174 my $editFilePath = $self->{problemPath}; # path to the permanent file to be edited
175 my $inputFilePath = $self->{inputFilePath}; # path to the file currently being worked with (might be a .tmp file)
176
177 my $header = CGI::i("Editing problem: $inputFilePath");
178
179 #########################################################################
180 # Find the text for the problem, either in the tmp file, if it exists
181 # or in the original file in the template directory
182 #########################################################################
183
184 my $problemContents = ${$self->{r_problemContents}};
185
186 #########################################################################
187 # Format the page
188 #########################################################################
189
190 # Define parameters for textarea
191 # FIXME
192 # Should the seed be set from some particular user instance??
193 # The mode list should be obtained from global.conf ultimately
194 my $rows = 20;
195 my $columns = 80;
196 my $mode_list = ['plainText','formattedText','images'];
197 my $displayMode = $self->{displayMode};
198 my $problemSeed = $self->{problemSeed};
199 my $uri = $r->uri;
200 my $edit_level = $r->param('edit_level') || 0;
201
202 my $force_field = defined($r->param('sourceFilePath')) ?
203 CGI::hidden(-name=>'sourceFilePath',
204 -default=>$r->param('sourceFilePath')) : '';
205 return CGI::p($header),
206 #CGI::start_form("POST",$r->uri,-target=>'_problem'), doesn't pass on the target parameter???
207 # THIS IS BECAUSE TARGET IS NOT A PARAMETER OF <FORM>!!!!!!!!
208 qq!<form method="POST" action="$uri" enctype="application/x-www-form-urlencoded", target="problem$edit_level">!,
209 $self->hidden_authen_fields,
210 $force_field,
211 CGI::hidden(-name=>'file_type',-default=>$self->{file_type}),
212 CGI::div(
213 'Seed: ',
214 CGI::textfield(-name=>'problemSeed',-value=>$problemSeed),
215 'Mode: ',
216 CGI::popup_menu(-name=>'displayMode', -values=>$mode_list, -default=>$displayMode),
217 CGI::a({-href=>'http://webwork.math.rochester.edu/docs/docs/pglanguage/manpages/',-target=>"manpage_window"},
218 'Manpages',
219 )
220 ),
221 CGI::p(
222 CGI::textarea(
223 -name => 'problemContents', -default => $problemContents,
224 -rows => $rows, -columns => $columns, -override => 1,
225 ),
226 ),
227 CGI::p(
228 CGI::submit(-value=>'Refresh',-name=>'submit'),
229 CGI::submit(-value=>'Save', -name=>'submit'),
230 CGI::submit(-value=>'Revert', -name=>'submit'),
231 CGI::submit(-value=>'Save as',-name=>'submit'),
232 CGI::textfield(-name=>'save_to_new_file', -value=>""),
233 ),
234 CGI::end_form(),
50} 235}
51 236
52 ########################################################### 237################################################################################
53 # This editor will edit problem files or set header files or files, such as course_info 238# Utilities
54 # whose name is defined in the global.conf database
55 #
56 # Only files under the template directory ( or linked to this location) can be edited.
57 #
58 # The course information and problems are located in the course templates directory.
59 # Course information has the name defined by courseFiles->{course_info}
60 #
61 # Only files under the template directory ( or linked to this location) can be edited.
62 #
63 # editMode = temporaryFile (view the temp file defined by course_info.txt.user_name.tmp
64 # instead of the file course_info.txt)
65 # The editFileSuffix is "user_name.tmp" by default. It's definition should be moved to Instructor.pm #FIXME
66 ########################################################### 239################################################################################
67 240
68sub pre_header_initialize { 241# saveFileChanges does most of the work. it is a separate method so that it can
69 my $self = shift; 242# be called from either pre_header_initialize() or initilize(), depending on
243# whether a redirect is needed or not.
244#
245# it actually does a lot more than save changes to the file being edited, and
246# sometimes less.
247
248sub saveFileChanges {
70 my ($setName, $problemNumber) = @_; 249 my ($self, $setName, $problemNumber) = @_;
71 my $r = $self->{r}; 250 my $r = $self->r;
72 my $ce = $self->{ce}; 251 my $ce = $r->ce;
73 my $submit_button = $r->param('submit'); # obtain submit command from form 252 my $db = $r->db;
74 253 my $urlpath = $r->urlpath;
75 #####################################################
76 # Save problem to permanent or temporary file
77 # Then redirect for viewing
78 #####################################################
79 if ( defined($submit_button) and ($submit_button eq 'Save' or $submit_button eq 'Refresh') ) {
80 254
81 $self->saveFileChanges($setName,$problemNumber); # write the necessary files 255 my $courseName = $urlpath->arg("courseID");
82 # return file path for viewing problem 256 my $user = $r->param('user');
83 # in $self->{currentSourceFilePath} 257 my $effectiveUserName = $r->param('effectiveUser');
84 # obtain the appropriate seed. 258
85 #redirect to view the problem 259 $setName = '' unless defined $setName;
260 $problemNumber = '' unless defined $problemNumber;
261
262 ##### Determine path to the file to be edited. #####
263
264 my $editFilePath = $ce->{courseDirs}->{templates};
265 my $problem_record = undef;
266
267 my $file_type = $r->param("file_type") || '';
268
269 if ($file_type eq 'course_info') {
270 # we are editing the course_info file
271 $self->{file_type} = 'course_info';
86 272
87 my $hostname = $r->hostname(); 273 # value of courseFiles::course_info is relative to templates directory
88 my $port = $r->get_server_port(); 274 $editFilePath .= '/' . $ce->{courseFiles}->{course_info};
89 my $uri = $r->uri; 275 } else {
90 my $courseName = $self->{ce}->{courseName}; 276 # we are editing a problem file or a set header file
91 my $problemSeed = ($r->param('problemSeed')) ? $r->param('problemSeed') : ''; 277
92 my $displayMode = ($r->param('displayMode')) ? $r->param('displayMode') : ''; 278 # FIXME there is a discrepancy in the way that the problems are found.
93 my $viewURL = ''; 279 # FIXME more error checking is needed in case the problem doesn't exist.
94 if ($self->{file_type} eq 'problem') { 280 # (i wonder what the above comments mean... -sam)
95 # redirect to have problem read by Problem.pm 281
96 $viewURL = "http://$hostname:$port"; 282 if (defined $problemNumber) {
97 $viewURL .= $ce->{webworkURLs}->{root}."/$courseName/$setName/$problemNumber/?"; 283 if ($problemNumber == 0) {
98 $viewURL .= $self->url_authen_args; 284 # we are editing a header file
99 $viewURL .= "&displayMode=$displayMode&problemSeed=$problemSeed"; # optional displayMode and problemSeed overrides 285 $self->{file_type} = 'set_header';
100 if ($submit_button eq 'Save') { 286
101 $viewURL .= "&editMode=savedFile"; 287 # first try getting the merged set for the effective user
288 my $set_record = $db->getMergedSet($effectiveUserName, $setName); # checked
289
290 # if that doesn't work (the set is not yet assigned), get the global record
291 $set_record = $db->getGlobalSet($setName); # checked
292
293 # bail if no set is found
294 die "Cannot find a set record for set $setName" unless defined($set_record);
295
296 $editFilePath .= '/' . $set_record->set_header;
102 } else { 297 } else {
103 $viewURL .= "&editMode=temporaryFile"; 298 # we are editing a "real" problem
299 $self->{file_type} = 'problem';
300
301 # first try getting the merged problem for the effective user
302 $problem_record = $db->getMergedProblem($effectiveUserName, $setName, $problemNumber); # checked
303
304 # if that doesn't work (the problem is not yet assigned), get the global record
305 $problem_record = $db->getGlobalProblem($setName, $problemNumber) unless defined($problem_record); # checked
306
307
308 if(not defined($problem_record)) {
309 my $forcedSourceFile = $r->param('sourceFilePath');
310 # bail if no problem is found and we aren't faking it
311 die "Cannot find a problem record for set $setName / problem $problemNumber" unless defined($forcedSourceFile);
312 $problem_record = fake_problem($db);
313 $problem_record->problem_id($problemNumber);
314 $problem_record->source_file($forcedSourceFile);
315 }
316
317
318 $editFilePath .= '/' . $problem_record->source_file;
104 } 319 }
105 $viewURL .= '&sourceFilePath='. $self->{currentSourceFilePath}; # path to pg text for viewing
106 # allows Problem.pg to recognize state
107 # of problem being viewed.
108 } elsif ($self->{file_type} eq 'set_header') {
109 # redirect set headers to ProblemList page
110 $viewURL = "http://$hostname:$port";
111 $viewURL .= $ce->{webworkURLs}->{root}."/$courseName/$setName/?";
112 $viewURL .= $self->url_authen_args;
113 $viewURL .= "&displayMode=$displayMode&problemSeed=$problemSeed"; # optional displayMode and problemSeed overrides
114 if ($submit_button eq 'Save') {
115 $viewURL .= "&editMode=savedFile";
116 } else {
117 $viewURL .= "&editMode=temporaryFile";
118 }
119 } elsif ($self->{file_type} eq 'course_info' ) {
120 $viewURL = "http://$hostname:$port";
121 $viewURL .= $ce->{webworkURLs}->{root}."/$courseName/?";
122 $viewURL .= $self->url_authen_args;
123 if ($submit_button eq 'Save') {
124 $viewURL .= "&editMode=savedFile";
125 } else {
126 $viewURL .= "&editMode=temporaryFile";
127 }
128 } else {
129 warn "PGProblemEditor does not have facilities for editing files with file_type ".$self->{file_type};
130 } 320 }
131
132 $r->header_out(Location => $viewURL );
133 $self->{noContent} = 1; # forces redirect
134 return;
135 }
136
137}
138
139sub initialize {
140 my $self = shift;
141 my ($setName, $problemNumber) = @_;
142 $self -> saveFileChanges(@_);
143
144
145
146}
147
148sub saveFileChanges {
149
150 my ($self, $setName, $problemNumber) = @_;
151 my $ce = $self->{ce};
152 my $r = $self->{r};
153 my $path_info = $r->path_info || "";
154 my $db = $self->{db};
155 my $user = $r->param('user');
156 my $effectiveUserName = $r->param('effectiveUser');
157 my $courseName = $ce->{courseName};
158
159 $setName = '' unless defined $setName;
160 $problemNumber = '' unless defined $problemNumber;
161
162 ##################################################
163 # Determine path to the file to be edited.
164 ##################################################
165 my $templateDirectory = $ce->{courseDirs}->{templates};
166 my $editFilePath = $templateDirectory;
167 my $problem_record = undef;
168
169 my $file_type = $r->param("file_type") || '';
170
171 if ($file_type eq 'course_info' ) {
172 $editFilePath .= '/'. $ce->{courseFiles}->{course_info};
173 $self->{file_type} = 'course_info';
174 # no problem_record is defined in this case
175
176 } else { # we areediting a problem file or a set header file
177
178 # FIXME there is a discrepancy in the way that the problems are found.
179 # FIXME more error checking is needed in case the problem doesn't exist.
180 if (defined($problemNumber) and $problemNumber) {
181 $problem_record = $db->getMergedProblem($effectiveUserName, $setName, $problemNumber); # checked
182 # If there is no global_user defined problem, (i.e. the sets haven't been assigned yet),
183 # look for a global version of the problem.
184 $problem_record = $db->getGlobalProblem($setName, $problemNumber) unless defined($problem_record); # checked
185 # bail if no problem is found
186 die "Cannot find a problem record for set $setName / problem $problemNumber"
187 unless defined($problem_record);
188 $editFilePath .= '/'.$problem_record->source_file;
189 $self->{file_type} = 'problem';
190 } elsif (defined($problemNumber) and $problemNumber==0) { # we are editing a header file
191 my $set_record = $db->getMergedSet($effectiveUserName, $setName); # checked
192 die "Cannot find a set record for set $setName" unless defined($set_record);
193 $editFilePath .= '/'.$set_record->set_header;
194 $self->{file_type} = 'set_header';
195 } 321 }
196 }
197 322
198
199
200
201 my $editFileSuffix = $user.'.tmp'; 323 my $editFileSuffix = $user.'.tmp';
202 my $submit_button = $r->param('submit'); 324 my $submit_button = $r->param('submit');
203
204 325
205 ############################################################################## 326 ##############################################################################
206 # Determine the display mode 327 # Determine the display mode
207 # try to get problem seed from the input parameter, or from the problem record 328 # try to get problem seed from the input parameter, or from the problem record
208 # This will be needed for viewing the problem via redirect. 329 # This will be needed for viewing the problem via redirect.
209 # They are also two of the parameters which can be set by the editor 330 # They are also two of the parameters which can be set by the editor
210 ############################################################################## 331 ##############################################################################
211 my $displayMode = ( defined($r->param('displayMode')) ) ? $r->param('displayMode') : $ce->{pg}->{options}->{displayMode}; 332
212 333 my $displayMode;
334 if (defined $r->param('displayMode')) {
335 $displayMode = $r->param('displayMode');
336 } else {
337 $displayMode = $ce->{pg}->{options}->{displayMode};
338 }
339
213 my $problemSeed; 340 my $problemSeed;
214 if ( defined($r->param('problemSeed')) ) { 341 if (defined $r->param('problemSeed')) {
215 $problemSeed = $r->param('problemSeed'); 342 $problemSeed = $r->param('problemSeed');
216 } elsif (defined($problem_record) and $problem_record->can('problem_seed')) { 343 } elsif (defined($problem_record) and $problem_record->can('problem_seed')) {
217 $problemSeed = $problem_record->problem_seed; 344 $problemSeed = $problem_record->problem_seed;
218 } 345 }
346
219 # make absolutely sure that the problem seed is defined, if it hasn't been. 347 # make absolutely sure that the problem seed is defined, if it hasn't been.
220 $problemSeed = '123456' unless defined($problemSeed) and $problemSeed =~/\S/; 348 $problemSeed = '123456' unless defined $problemSeed and $problemSeed =~/\S/;
221 349
222 ############################################################################## 350 ##############################################################################
223 # read and update the targetFile and targetFile.tmp files in the directory 351 # read and update the targetFile and targetFile.tmp files in the directory
224 # if a .tmp file already exists use that, unless the revert button has been pressed. 352 # if a .tmp file already exists use that, unless the revert button has been pressed.
225 # These .tmp files are 353 # These .tmp files are
226 # removed when the file is finally saved. 354 # removed when the file is finally saved.
227 ############################################################################## 355 ##############################################################################
228 356
229 my $problemContents = ''; 357 my $problemContents = '';
230 my $currentSourceFilePath = ''; 358 my $currentSourceFilePath = '';
231 my $editErrors = ''; 359 my $editErrors = '';
232 360
233 my $inputFilePath = (-r "$editFilePath.$editFileSuffix")?"$editFilePath.$editFileSuffix" : $editFilePath; 361 my $inputFilePath;
362 if (-r "$editFilePath.$editFileSuffix") {
363 $inputFilePath = "$editFilePath.$editFileSuffix";
364 } else {
365 $inputFilePath = $editFilePath;
366 }
367
234 $inputFilePath = $editFilePath if defined($submit_button) and $submit_button eq 'Revert'; 368 $inputFilePath = $editFilePath if defined($submit_button) and $submit_button eq 'Revert';
235 369
370 ##### handle button clicks #####
371
236 if (not defined($submit_button) or $submit_button eq 'Revert' ) { 372 if (not defined $submit_button or $submit_button eq 'Revert' ) {
237 # this is a fresh editing job 373 # this is a fresh editing job
238 # copy the pg file to a new file with the same name with .tmp added 374 # copy the pg file to a new file with the same name with .tmp added
239 # store this name in the $self->currentSourceFilePath for use in body 375 # store this name in the $self->currentSourceFilePath for use in body
240 eval { $problemContents = WeBWorK::Utils::readFile($inputFilePath) }; 376
241 # try to read file 377 # try to read file
378 if(-e $inputFilePath) {
379 eval { $problemContents = WeBWorK::Utils::readFile($inputFilePath) };
242 $problemContents = $@ if $@; 380 $problemContents = $@ if $@;
243 $editErrors .= $problemContents; 381 } else { # file not existing is not an error
382 $problemContents = '';
383 }
384
244 $currentSourceFilePath = "$editFilePath.$editFileSuffix"; 385 $currentSourceFilePath = "$editFilePath.$editFileSuffix";
245 $self->{currentSourceFilePath} = $currentSourceFilePath; 386 $self->{currentSourceFilePath} = $currentSourceFilePath;
387 $self->{problemPath} = $editFilePath;
246 } elsif ($submit_button eq 'Refresh' ) { 388 } elsif ($submit_button eq 'Refresh') {
247 # grab the problemContents from the form in order to save it to the tmp file 389 # grab the problemContents from the form in order to save it to the tmp file
248 # store tmp file name in the $self->currentSourceFilePath for use in body 390 # store tmp file name in the $self->currentSourceFilePath for use in body
249
250 $problemContents = $r->param('problemContents'); 391 $problemContents = $r->param('problemContents');
392
251 $currentSourceFilePath = "$editFilePath.$editFileSuffix"; 393 $currentSourceFilePath = "$editFilePath.$editFileSuffix";
252 $self->{currentSourceFilePath} = $currentSourceFilePath; 394 $self->{currentSourceFilePath} = $currentSourceFilePath;
395 $self->{problemPath} = $editFilePath;
253 } elsif ($submit_button eq 'Save') { 396 } elsif ($submit_button eq 'Save') {
254 # grab the problemContents from the form in order to save it to the permanent file 397 # grab the problemContents from the form in order to save it to the permanent file
255 # later we will unlink (delete) the temporary file 398 # later we will unlink (delete) the temporary file
256 # store permanent file name in the $self->currentSourceFilePath for use in body 399 # store permanent file name in the $self->currentSourceFilePath for use in body
257
258 $problemContents = $r->param('problemContents'); 400 $problemContents = $r->param('problemContents');
401
259 $currentSourceFilePath = "$editFilePath"; 402 $currentSourceFilePath = "$editFilePath";
260 $self->{currentSourceFilePath} = $currentSourceFilePath; 403 $self->{currentSourceFilePath} = $currentSourceFilePath;
404 $self->{problemPath} = $editFilePath;
405 } elsif ($submit_button eq 'Save as') {
406 # grab the problemContents from the form in order to save it to a new permanent file
407 # later we will unlink (delete) the current temporary file
408 # store new permanent file name in the $self->currentSourceFilePath for use in body
409 $problemContents = $r->param('problemContents');
410 $currentSourceFilePath = $ce->{courseDirs}->{templates} . '/' .$r->param('save_to_new_file');
411 $self->{currentSourceFilePath} = $currentSourceFilePath;
412 $self->{problemPath} = $currentSourceFilePath;
261 } else { 413 } else {
262 # give a warning
263 die "Unrecognized submit command $submit_button"; 414 die "Unrecognized submit command: $submit_button";
264 } 415 }
265 416
266 # Handle the problem of line endings. Make sure that all of the line endings. Convert \r\n to \n 417 # Handle the problem of line endings. Make sure that all of the line endings. Convert \r\n to \n
267 $problemContents =~ s/\r\n/\n/g; 418 $problemContents =~ s/\r\n/\n/g;
268 $problemContents =~ s/\r/\n/g; 419 $problemContents =~ s/\r/\n/g;
269 420
270 # FIXME convert all double returns to paragraphs 421 # FIXME convert all double returns to paragraphs for .txt files
422 # instead of doing this here, it should be done n the PLACE WHERE THE FILE IS DISPLAYED!!!
423 #if ($self->{file_type} eq 'course_info' ) {
271 $problemContents =~ s/\n\n/\n<p>\n/g; 424 # $problemContents =~ s/\n\n/\n<p>\n/g;
272 ##############################################################################
273 # 425 #}
426
427 ##############################################################################
274 # write changes to the approriate files 428 # write changes to the approriate files
275 # FIXME make sure that the permissions are set correctly!!! 429 # FIXME make sure that the permissions are set correctly!!!
276 # Make sure that the warning is being transmitted properly. 430 # Make sure that the warning is being transmitted properly.
277 ############################################################################## 431 ##############################################################################
432
433 # FIXME set a local state rather continue to call on the submit button.
434 if (defined $submit_button and $submit_button eq 'Save as' and defined $currentSourceFilePath and -e $currentSourceFilePath) {
435 warn "File $currentSourceFilePath exists. File not saved.";
436 } else {
278 eval { 437 eval {
279 local *OUTPUTFILE; 438 local *OUTPUTFILE;
280 open OUTPUTFILE, ">", $currentSourceFilePath 439 open OUTPUTFILE, ">", $currentSourceFilePath
281 or die "Failed to write to $currentSourceFilePath. 440 or die "Failed to open $currentSourceFilePath";
282 It is likely that the permissions in the template directory have not been set correctly.".
283 "The web server must be able to create and write to files in the directory containing the problem.
284 $!";
285 print OUTPUTFILE $problemContents; 441 print OUTPUTFILE $problemContents;
286 close OUTPUTFILE; 442 close OUTPUTFILE;
443 }; # any errors are caught in the next block
444
287 }; 445 }
288 # record an error string for later use if there was a difficulty in writing to the file
289 # FIXME is this string ever inspected?
290 446
447 ###########################################################
448 # Catch errors in saving files, clean up temp files
449 ###########################################################
450
291 my $openTempFileErrors = $@ if $@; 451 my $openTempFileErrors = $@ if $@;
292 452
293 if ( $openTempFileErrors) { 453 if ($openTempFileErrors) {
294 454 $self->{submiterror} = "Unable to write to $currentSourceFilePath: It is likely that the permissions in the template directory have not been set correctly. See log for details.";
295 $self->{openTempFileErrors} = "Unable to write to $currentSourceFilePath: $openTempFileErrors";
296 #diagnose errors: 455 #diagnose errors:
297 warn "Editing errors: $openTempFileErrors\n"; 456 warn "Unable to write to $currentSourceFilePath: $openTempFileErrors";
298 warn "The file $currentSourceFilePath exists. \n " if -e $currentSourceFilePath; #FIXME 457 warn "The file $currentSourceFilePath exists. \n " if -e $currentSourceFilePath; #FIXME
299 warn "The file $currentSourceFilePath cannot be found. \n " unless -e $currentSourceFilePath; 458 warn "The file $currentSourceFilePath cannot be found. \n " unless -e $currentSourceFilePath;
300 warn "The file $currentSourceFilePath does not have write permissions. \n" 459 warn "The file $currentSourceFilePath does not have write permissions. \n"
301 if -e $currentSourceFilePath and not -w $currentSourceFilePath; 460 if -e $currentSourceFilePath and not -w $currentSourceFilePath;
302
303
304
305 } else { 461 } else {
306 # unlink the temporary file if there are no errors and the save button has been pushed 462 # unlink the temporary file if there are no errors and the save button has been pushed
307 463 unlink("$editFilePath.$editFileSuffix")
308 $self->{openTempFileErrors} = ''; 464 if defined $submit_button and ($submit_button eq 'Save' or $submit_button eq 'Save as');
309 unlink("$editFilePath.$editFileSuffix") if defined($submit_button) and $submit_button eq 'Save';
310 }; 465 }
311
312 466
313 # return values for use in the body subroutine 467 # return values for use in the body subroutine
314 $self->{problemPath} = $editFilePath;
315 $self->{inputFilePath} = $inputFilePath; 468 $self->{inputFilePath} = $inputFilePath;
316 $self->{displayMode} = $displayMode; 469 $self->{displayMode} = $displayMode;
317 $self->{problemSeed} = $problemSeed; 470 $self->{problemSeed} = $problemSeed;
318 $self->{r_problemContents} = \$problemContents; 471 $self->{r_problemContents} = \$problemContents;
319 $self->{editFileSuffix} = $editFileSuffix; 472 $self->{editFileSuffix} = $editFileSuffix;
320
321
322
323
324} 473}
325sub saveFile {
326 my $self = shift;
327
328
329
330
331
332
333}
334sub path {
335 my $self = shift;
336 my $r = $self->{r};
337 my $set_id = '';
338 my $problem_id = '';
339 unless (defined( $r->param("file_type") and $r->param("file_type") eq 'course_info' ) ){
340 $set_id = shift;
341 $problem_id = shift;
342 }
343 #FIXME this is a bad way to pass the args, since it's position changes if the set/problem info
344 # isn't there
345 my $args = $_[-1];
346
347 my $ce = $self->{ce};
348 my $root = $ce->{webworkURLs}->{root};
349 my $courseName = $ce->{courseName};
350 return $self->pathMacro($args,
351 "Home" => "$root",
352 $courseName => "$root/$courseName",
353 'instructor' => "$root/$courseName/instructor",
354 'sets' => "$root/$courseName/instructor/sets/",
355 "$set_id" => "$root/$courseName/instructor/sets/$set_id/",
356 "problems" => "$root/$courseName/instructor/sets/$set_id/problems",
357 "$problem_id" => ''
358 );
359}
360sub body {
361 my $self = shift;
362
363 # test area
364 my $r = $self->{r};
365 my $db = $self->{db};
366 my $ce = $self->{ce};
367 my $user = $r->param('user');
368
369
370
371 ################
372 # Gathering info
373 # What is needed
374 # $editFilePath --
375 # $formURL -- given by $r->uri
376 # $tmpProblemPath
377 my $editFilePath = $self->{problemPath}; # path to the permanent file to be edited
378 my $inputFilePath = $self->{inputFilePath}; # path to the file currently being worked with (might be a .tmp file)
379
380
381
382
383
384 my $header = CGI::i("Editing problem: $inputFilePath");
385
386 #########################################################################
387 # Find the text for the problem, either in the tmp file, if it exists
388 # or in the original file in the template directory
389 #########################################################################
390 my $problemContents = ${$self->{r_problemContents}};
391
392# eval { $problemContents = WeBWorK::Utils::readFile($editFilePath) }; # try to read file
393# $problemContents = $@ if $@;
394
395
396
397 #########################################################################
398 # Format the page
399 #########################################################################
400 # Define parameters for textarea
401 # FIXME
402 # Should the seed be set from some particular user instance??
403 # The mode list should be obtained from global.conf ultimately
404 my $rows = 20;
405 my $columns = 80;
406 my $mode_list = ['plainText','formattedText','images'];
407 my $displayMode = $self->{displayMode};
408 my $problemSeed = $self->{problemSeed};
409 my $uri = $r->uri;
410 ########################################################################
411 # Define a link to view the problem
412 #FIXME
413
414 #########################################################################
415
416
417 warn "Errors in the problem ".CGI::br().$self->{editErrors} if $self->{editErrors};
418
419
420 return CGI::p($header),
421 #CGI::start_form("POST",$r->uri,-target=>'_problem'), doesn't pass on the target parameter???
422 qq!<form method="POST" action="$uri" enctype="application/x-www-form-urlencoded", target="_problem">!,
423 $self->hidden_authen_fields,
424 CGI::hidden(-name=>'file_type',-default=>$self->{file_type}),
425 CGI::div(
426 'Seed: ',
427 CGI::textfield(-name=>'problemSeed',-value=>$problemSeed),
428 'Mode: ',
429 CGI::popup_menu(-name=>'displayMode', -'values'=>$mode_list,
430 -default=>$displayMode),
431 CGI::a(
432 {-href=>'http://webwork.math.rochester.edu/docs/docs/pglanguage/manpages/',-target=>"manpage_window"},
433 'Manpages',
434 )
435 ),
436 CGI::p(
437 CGI::textarea(-name => 'problemContents', -default => $problemContents,
438 -rows => $rows, -columns => $columns, -override => 1,
439 ),
440 ),
441 CGI::p(
442 CGI::submit(-value=>'Refresh',-name=>'submit'),
443 CGI::submit(-value=>'Save',-name=>'submit'),
444 CGI::submit(-value=>'Revert',-name=>'submit'),
445 ),
446 CGI::end_form(),
447
448
449}
450
451
452 474
4531; 4751;

Legend:
Removed from v.1747  
changed lines
  Added in v.2054

aubreyja at gmail dot com
ViewVC Help
Powered by ViewVC 1.0.9