1010use PhpSchool \PhpWorkshop \Check \FileExistsCheck ;
1111use PhpSchool \PhpWorkshop \Check \PhpLintCheck ;
1212use PhpSchool \PhpWorkshop \Event \CgiExecuteEvent ;
13+ use PhpSchool \PhpWorkshop \Event \CgiExerciseRunnerEvent ;
1314use PhpSchool \PhpWorkshop \Event \Event ;
1415use PhpSchool \PhpWorkshop \Event \EventDispatcher ;
1516use PhpSchool \PhpWorkshop \Event \ExerciseRunnerEvent ;
@@ -85,33 +86,84 @@ public function getRequiredChecks(): array
8586 }
8687
8788 /**
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.
91104 */
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
93121 {
94122 try {
95123 /** @var CgiExecuteEvent $event */
96124 $ 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 )
98126 );
99127 $ solutionResponse = $ this ->executePhpFile (
128+ $ input ,
100129 $ this ->exercise ->getSolution ()->getEntryPoint ()->getAbsolutePath (),
101130 $ event ->getRequest (),
102131 'reference '
103132 );
104133 } 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+ );
106143 throw new SolutionExecutionException ($ e ->getMessage ());
107144 }
108145
109146 try {
110147 /** @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+ );
113157 } 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+ );
115167 return GenericFailure::fromRequestAndCodeExecutionFailure ($ request , $ e );
116168 }
117169
@@ -146,12 +198,18 @@ private function getHeaders(ResponseInterface $response): array
146198 * @param string $type
147199 * @return ResponseInterface
148200 */
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 {
151207 $ process = $ this ->getPhpProcess (dirname ($ fileName ), basename ($ fileName ), $ request );
152208
153209 $ 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+ );
155213 $ process ->wait ();
156214
157215 if (!$ process ->isSuccessful ()) {
@@ -206,38 +264,6 @@ private function getPhpProcess(string $workingDirectory, string $fileName, Reque
206264 return $ this ->processFactory ->create ($ processInput );
207265 }
208266
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- 241267 /**
242268 * Runs a student's solution by invoking PHP via the `php-cgi` binary, populating all the super globals with
243269 * the information from the request objects returned from the exercise. The exercise can return multiple
@@ -257,12 +283,12 @@ function (RequestInterface $request) use ($input) {
257283 */
258284 public function run (Input $ input , OutputInterface $ output ): bool
259285 {
260- $ this ->eventDispatcher ->dispatch (new ExerciseRunnerEvent ('cgi.run.start ' , $ this ->exercise , $ input ));
286+ $ this ->eventDispatcher ->dispatch (new CgiExerciseRunnerEvent ('cgi.run.start ' , $ this ->exercise , $ input ));
261287 $ success = true ;
262288 foreach ($ this ->exercise ->getRequests () as $ i => $ request ) {
263289 /** @var CgiExecuteEvent $event */
264290 $ 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 )
266292 );
267293 $ process = $ this ->getPhpProcess (
268294 dirname ($ input ->getRequiredArgument ('program ' )),
@@ -272,7 +298,13 @@ public function run(Input $input, OutputInterface $output): bool
272298
273299 $ process ->start ();
274300 $ 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+ )
276308 );
277309 $ process ->wait (function ($ outputType , $ outputBuffer ) use ($ output ) {
278310 $ output ->write ($ outputBuffer );
@@ -286,10 +318,10 @@ public function run(Input $input, OutputInterface $output): bool
286318 $ output ->lineBreak ();
287319
288320 $ this ->eventDispatcher ->dispatch (
289- new CgiExecuteEvent ('cgi.run.student-execute.post ' , $ request )
321+ new CgiExecuteEvent ('cgi.run.student-execute.post ' , $ this -> exercise , $ input , $ request )
290322 );
291323 }
292- $ this ->eventDispatcher ->dispatch (new ExerciseRunnerEvent ('cgi.run.finish ' , $ this ->exercise , $ input ));
324+ $ this ->eventDispatcher ->dispatch (new CgiExerciseRunnerEvent ('cgi.run.finish ' , $ this ->exercise , $ input ));
293325 return $ success ;
294326 }
295327}
0 commit comments