10
10
use PhpSchool \PhpWorkshop \Check \FileExistsCheck ;
11
11
use PhpSchool \PhpWorkshop \Check \PhpLintCheck ;
12
12
use PhpSchool \PhpWorkshop \Event \CgiExecuteEvent ;
13
+ use PhpSchool \PhpWorkshop \Event \CgiExerciseRunnerEvent ;
13
14
use PhpSchool \PhpWorkshop \Event \Event ;
14
15
use PhpSchool \PhpWorkshop \Event \EventDispatcher ;
15
16
use PhpSchool \PhpWorkshop \Event \ExerciseRunnerEvent ;
@@ -85,33 +86,84 @@ public function getRequiredChecks(): array
85
86
}
86
87
87
88
/**
88
- * @param RequestInterface $request
89
- * @param string $fileName
90
- * @return CgiResultInterface
89
+ * Verifies a solution by invoking PHP via the `php-cgi` binary, populating all the super globals with
90
+ * the information from the request objects returned from the exercise. The exercise can return multiple
91
+ * requests so the solution will be invoked for however many requests there are.
92
+ *
93
+ * Events dispatched (for each request):
94
+ *
95
+ * * cgi.verify.reference-execute.pre
96
+ * * cgi.verify.reference.executing
97
+ * * cgi.verify.reference-execute.fail (if the reference solution fails to execute)
98
+ * * cgi.verify.student-execute.pre
99
+ * * cgi.verify.student.executing
100
+ * * cgi.verify.student-execute.fail (if the student's solution fails to execute)
101
+ *
102
+ * @param Input $input The command line arguments passed to the command.
103
+ * @return CgiResult The result of the check.
91
104
*/
92
- private function checkRequest (RequestInterface $ request , string $ fileName ): CgiResultInterface
105
+ public function verify (Input $ input ): ResultInterface
106
+ {
107
+ $ this ->eventDispatcher ->dispatch (new CgiExerciseRunnerEvent ('cgi.verify.start ' , $ this ->exercise , $ input ));
108
+ $ result = new CgiResult (
109
+ array_map (
110
+ function (RequestInterface $ request ) use ($ input ) {
111
+ return $ this ->doVerify ($ request , $ input );
112
+ },
113
+ $ this ->exercise ->getRequests ()
114
+ )
115
+ );
116
+ $ this ->eventDispatcher ->dispatch (new CgiExerciseRunnerEvent ('cgi.verify.finish ' , $ this ->exercise , $ input ));
117
+ return $ result ;
118
+ }
119
+
120
+ private function doVerify (RequestInterface $ request , Input $ input ): CgiResultInterface
93
121
{
94
122
try {
95
123
/** @var CgiExecuteEvent $event */
96
124
$ event = $ this ->eventDispatcher ->dispatch (
97
- new CgiExecuteEvent ('cgi.verify.reference-execute.pre ' , $ request )
125
+ new CgiExecuteEvent ('cgi.verify.reference-execute.pre ' , $ this -> exercise , $ input , $ request )
98
126
);
99
127
$ solutionResponse = $ this ->executePhpFile (
128
+ $ input ,
100
129
$ this ->exercise ->getSolution ()->getEntryPoint ()->getAbsolutePath (),
101
130
$ event ->getRequest (),
102
131
'reference '
103
132
);
104
133
} catch (CodeExecutionException $ e ) {
105
- $ this ->eventDispatcher ->dispatch (new Event ('cgi.verify.reference-execute.fail ' , ['exception ' => $ e ]));
134
+ $ this ->eventDispatcher ->dispatch (
135
+ new CgiExecuteEvent (
136
+ 'cgi.verify.reference-execute.fail ' ,
137
+ $ this ->exercise ,
138
+ $ input ,
139
+ $ request ,
140
+ ['exception ' => $ e ]
141
+ )
142
+ );
106
143
throw new SolutionExecutionException ($ e ->getMessage ());
107
144
}
108
145
109
146
try {
110
147
/** @var CgiExecuteEvent $event */
111
- $ event = $ this ->eventDispatcher ->dispatch (new CgiExecuteEvent ('cgi.verify.student-execute.pre ' , $ request ));
112
- $ userResponse = $ this ->executePhpFile ($ fileName , $ event ->getRequest (), 'student ' );
148
+ $ event = $ this ->eventDispatcher ->dispatch (
149
+ new CgiExecuteEvent ('cgi.verify.student-execute.pre ' , $ this ->exercise , $ input , $ request )
150
+ );
151
+ $ userResponse = $ this ->executePhpFile (
152
+ $ input ,
153
+ $ input ->getRequiredArgument ('program ' ),
154
+ $ event ->getRequest (),
155
+ 'student '
156
+ );
113
157
} catch (CodeExecutionException $ e ) {
114
- $ this ->eventDispatcher ->dispatch (new Event ('cgi.verify.student-execute.fail ' , ['exception ' => $ e ]));
158
+ $ this ->eventDispatcher ->dispatch (
159
+ new CgiExecuteEvent (
160
+ 'cgi.verify.student-execute.fail ' ,
161
+ $ this ->exercise ,
162
+ $ input ,
163
+ $ request ,
164
+ ['exception ' => $ e ]
165
+ )
166
+ );
115
167
return GenericFailure::fromRequestAndCodeExecutionFailure ($ request , $ e );
116
168
}
117
169
@@ -146,12 +198,18 @@ private function getHeaders(ResponseInterface $response): array
146
198
* @param string $type
147
199
* @return ResponseInterface
148
200
*/
149
- private function executePhpFile (string $ fileName , RequestInterface $ request , string $ type ): ResponseInterface
150
- {
201
+ private function executePhpFile (
202
+ Input $ input ,
203
+ string $ fileName ,
204
+ RequestInterface $ request ,
205
+ string $ type
206
+ ): ResponseInterface {
151
207
$ process = $ this ->getPhpProcess (dirname ($ fileName ), basename ($ fileName ), $ request );
152
208
153
209
$ process ->start ();
154
- $ this ->eventDispatcher ->dispatch (new CgiExecuteEvent (sprintf ('cgi.verify.%s.executing ' , $ type ), $ request ));
210
+ $ this ->eventDispatcher ->dispatch (
211
+ new CgiExecuteEvent (sprintf ('cgi.verify.%s.executing ' , $ type ), $ this ->exercise , $ input , $ request )
212
+ );
155
213
$ process ->wait ();
156
214
157
215
if (!$ process ->isSuccessful ()) {
@@ -206,38 +264,6 @@ private function getPhpProcess(string $workingDirectory, string $fileName, Reque
206
264
return $ this ->processFactory ->create ($ processInput );
207
265
}
208
266
209
- /**
210
- * Verifies a solution by invoking PHP via the `php-cgi` binary, populating all the super globals with
211
- * the information from the request objects returned from the exercise. The exercise can return multiple
212
- * requests so the solution will be invoked for however many requests there are.
213
- *
214
- * Events dispatched (for each request):
215
- *
216
- * * cgi.verify.reference-execute.pre
217
- * * cgi.verify.reference.executing
218
- * * cgi.verify.reference-execute.fail (if the reference solution fails to execute)
219
- * * cgi.verify.student-execute.pre
220
- * * cgi.verify.student.executing
221
- * * cgi.verify.student-execute.fail (if the student's solution fails to execute)
222
- *
223
- * @param Input $input The command line arguments passed to the command.
224
- * @return CgiResult The result of the check.
225
- */
226
- public function verify (Input $ input ): ResultInterface
227
- {
228
- $ this ->eventDispatcher ->dispatch (new ExerciseRunnerEvent ('cgi.verify.start ' , $ this ->exercise , $ input ));
229
- $ result = new CgiResult (
230
- array_map (
231
- function (RequestInterface $ request ) use ($ input ) {
232
- return $ this ->checkRequest ($ request , $ input ->getRequiredArgument ('program ' ));
233
- },
234
- $ this ->exercise ->getRequests ()
235
- )
236
- );
237
- $ this ->eventDispatcher ->dispatch (new ExerciseRunnerEvent ('cgi.verify.finish ' , $ this ->exercise , $ input ));
238
- return $ result ;
239
- }
240
-
241
267
/**
242
268
* Runs a student's solution by invoking PHP via the `php-cgi` binary, populating all the super globals with
243
269
* the information from the request objects returned from the exercise. The exercise can return multiple
@@ -257,12 +283,12 @@ function (RequestInterface $request) use ($input) {
257
283
*/
258
284
public function run (Input $ input , OutputInterface $ output ): bool
259
285
{
260
- $ this ->eventDispatcher ->dispatch (new ExerciseRunnerEvent ('cgi.run.start ' , $ this ->exercise , $ input ));
286
+ $ this ->eventDispatcher ->dispatch (new CgiExerciseRunnerEvent ('cgi.run.start ' , $ this ->exercise , $ input ));
261
287
$ success = true ;
262
288
foreach ($ this ->exercise ->getRequests () as $ i => $ request ) {
263
289
/** @var CgiExecuteEvent $event */
264
290
$ event = $ this ->eventDispatcher ->dispatch (
265
- new CgiExecuteEvent ('cgi.run.student-execute.pre ' , $ request )
291
+ new CgiExecuteEvent ('cgi.run.student-execute.pre ' , $ this -> exercise , $ input , $ request )
266
292
);
267
293
$ process = $ this ->getPhpProcess (
268
294
dirname ($ input ->getRequiredArgument ('program ' )),
@@ -272,7 +298,13 @@ public function run(Input $input, OutputInterface $output): bool
272
298
273
299
$ process ->start ();
274
300
$ this ->eventDispatcher ->dispatch (
275
- new CgiExecuteEvent ('cgi.run.student.executing ' , $ request , ['output ' => $ output ])
301
+ new CgiExecuteEvent (
302
+ 'cgi.run.student.executing ' ,
303
+ $ this ->exercise ,
304
+ $ input ,
305
+ $ request ,
306
+ ['output ' => $ output ]
307
+ )
276
308
);
277
309
$ process ->wait (function ($ outputType , $ outputBuffer ) use ($ output ) {
278
310
$ output ->write ($ outputBuffer );
@@ -286,10 +318,10 @@ public function run(Input $input, OutputInterface $output): bool
286
318
$ output ->lineBreak ();
287
319
288
320
$ this ->eventDispatcher ->dispatch (
289
- new CgiExecuteEvent ('cgi.run.student-execute.post ' , $ request )
321
+ new CgiExecuteEvent ('cgi.run.student-execute.post ' , $ this -> exercise , $ input , $ request )
290
322
);
291
323
}
292
- $ this ->eventDispatcher ->dispatch (new ExerciseRunnerEvent ('cgi.run.finish ' , $ this ->exercise , $ input ));
324
+ $ this ->eventDispatcher ->dispatch (new CgiExerciseRunnerEvent ('cgi.run.finish ' , $ this ->exercise , $ input ));
293
325
return $ success ;
294
326
}
295
327
}
0 commit comments