[system] / trunk / webwork2 / lib / WeBWorK / ContentGenerator / Instructor / PGProblemEditor.pm Repository:
ViewVC logotype

Annotation of /trunk/webwork2/lib/WeBWorK/ContentGenerator/Instructor/PGProblemEditor.pm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1348 - (view) (download) (as text)

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

aubreyja at gmail dot com
ViewVC Help
Powered by ViewVC 1.0.9