Skip to content

Commit 8a0a1ee

Browse files
authored
Merge pull request #140 from php-school/realpath-listener
Realpath listener & Event Refactor
2 parents a395588 + a768bb0 commit 8a0a1ee

17 files changed

+362
-102
lines changed

app/config.php

+43-9
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
use PhpSchool\PhpWorkshop\Listener\CodePatchListener;
3131
use PhpSchool\PhpWorkshop\Listener\ConfigureCommandListener;
3232
use PhpSchool\PhpWorkshop\Listener\PrepareSolutionListener;
33+
use PhpSchool\PhpWorkshop\Listener\RealPathListener;
3334
use PhpSchool\PhpWorkshop\Listener\SelfCheckListener;
3435
use PhpSchool\PhpWorkshop\MenuItem\ResetProgress;
3536
use PhpSchool\PhpWorkshop\Output\OutputInterface;
@@ -197,7 +198,8 @@
197198
$c->get(RunnerManager::class)
198199
);
199200
},
200-
201+
RealPathListener::class => object(),
202+
201203
//checks
202204
FileExistsCheck::class => object(),
203205
PhpLintCheck::class => object(),
@@ -281,6 +283,20 @@
281283
],
282284
'appContributors' => [],
283285
'eventListeners' => [
286+
'realpath-student-submission' => [
287+
'cli.verify.start' => [
288+
containerListener(RealPathListener::class)
289+
],
290+
'cli.run.start' => [
291+
containerListener(RealPathListener::class)
292+
],
293+
'cgi.verify.start' => [
294+
containerListener(RealPathListener::class)
295+
],
296+
'cgi.run.start' => [
297+
containerListener(RealPathListener::class)
298+
]
299+
],
284300
'check-exercise-assigned' => [
285301
'route.pre.resolve.args' => [
286302
containerListener(CheckExerciseAssignedListener::class)
@@ -292,25 +308,43 @@
292308
],
293309
],
294310
'prepare-solution' => [
295-
'verify.start' => [
311+
'cli.verify.start' => [
312+
containerListener(PrepareSolutionListener::class),
313+
],
314+
'cli.run.start' => [
315+
containerListener(PrepareSolutionListener::class),
316+
],
317+
'cgi.verify.start' => [
296318
containerListener(PrepareSolutionListener::class),
297319
],
298-
'run.start' => [
320+
'cgi.run.start' => [
299321
containerListener(PrepareSolutionListener::class),
300322
],
301323
],
302324
'code-patcher' => [
303-
'run.start' => [
325+
'cli.verify.start' => [
304326
containerListener(CodePatchListener::class, 'patch'),
305327
],
306-
'verify.pre.execute' => [
328+
'cli.verify.finish' => [
307329
containerListener(CodePatchListener::class, 'patch'),
308330
],
309-
'verify.post.execute' => [
310-
containerListener(CodePatchListener::class, 'revert'),
331+
'cli.run.start' => [
332+
containerListener(CodePatchListener::class, 'patch'),
333+
],
334+
'cli.run.finish' => [
335+
containerListener(CodePatchListener::class, 'patch'),
336+
],
337+
'cgi.verify.start' => [
338+
containerListener(CodePatchListener::class, 'patch'),
311339
],
312-
'run.finish' => [
313-
containerListener(CodePatchListener::class, 'revert'),
340+
'cgi.verify.finish' => [
341+
containerListener(CodePatchListener::class, 'patch'),
342+
],
343+
'cgi.run.start' => [
344+
containerListener(CodePatchListener::class, 'patch'),
345+
],
346+
'cgi.run.finish' => [
347+
containerListener(CodePatchListener::class, 'patch'),
314348
],
315349
],
316350
'self-check' => [

src/Command/RunCommand.php

+1-9
Original file line numberDiff line numberDiff line change
@@ -61,15 +61,7 @@ public function __construct(
6161
*/
6262
public function __invoke(Input $input)
6363
{
64-
$program = $input->getArgument('program');
65-
if (!file_exists($program)) {
66-
$this->output->printError(
67-
sprintf('Could not run. File: "%s" does not exist', $program)
68-
);
69-
return 1;
70-
}
71-
$program = realpath($program);
7264
$exercise = $this->exerciseRepository->findByName($this->userState->getCurrentExercise());
73-
$this->exerciseDispatcher->run($exercise, $program, $this->output);
65+
$this->exerciseDispatcher->run($exercise, $input, $this->output);
7466
}
7567
}

src/Command/VerifyCommand.php

-9
Original file line numberDiff line numberDiff line change
@@ -79,15 +79,6 @@ public function __construct(
7979
*/
8080
public function __invoke(Input $input)
8181
{
82-
$program = $input->getArgument('program');
83-
if (!file_exists($program)) {
84-
$this->output->printError(
85-
sprintf('Could not verify. File: "%s" does not exist', $program)
86-
);
87-
return 1;
88-
}
89-
$program = realpath($program);
90-
9182
$exercise = $this->exerciseRepository->findByName($this->userState->getCurrentExercise());
9283
$results = $this->exerciseDispatcher->verify($exercise, $input);
9384

src/Event/ExerciseRunnerEvent.php

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
<?php
2+
3+
namespace PhpSchool\PhpWorkshop\Event;
4+
5+
use PhpSchool\PhpWorkshop\Exercise\ExerciseInterface;
6+
use PhpSchool\PhpWorkshop\Input\Input;
7+
8+
/**
9+
* @author Aydin Hassan <[email protected]>
10+
*/
11+
class ExerciseRunnerEvent extends Event
12+
{
13+
14+
/**
15+
* @var ExerciseInterface
16+
*/
17+
private $exercise;
18+
19+
/**
20+
* @var Input
21+
*/
22+
private $input;
23+
24+
/**
25+
* @param string $name
26+
* @param ExerciseInterface $exercise
27+
* @param Input $input
28+
* @param array $parameters
29+
*/
30+
public function __construct($name, ExerciseInterface $exercise, Input $input, array $parameters = [])
31+
{
32+
$parameters['input'] = $input;
33+
$parameters['exercise'] = $exercise;
34+
parent::__construct($name, $parameters);
35+
36+
$this->exercise = $exercise;
37+
$this->input = $input;
38+
}
39+
40+
/**
41+
* @return Input
42+
*/
43+
public function getInput()
44+
{
45+
return $this->input;
46+
}
47+
48+
/**
49+
* @return ExerciseInterface
50+
*/
51+
public function getExercise()
52+
{
53+
return $this->exercise;
54+
}
55+
}

src/ExerciseRunner/CgiRunner.php

+7-3
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,12 @@
88
use PhpSchool\PhpWorkshop\Event\CgiExecuteEvent;
99
use PhpSchool\PhpWorkshop\Event\Event;
1010
use PhpSchool\PhpWorkshop\Event\EventDispatcher;
11+
use PhpSchool\PhpWorkshop\Event\ExerciseRunnerEvent;
1112
use PhpSchool\PhpWorkshop\Exception\CodeExecutionException;
1213
use PhpSchool\PhpWorkshop\Exception\SolutionExecutionException;
1314
use PhpSchool\PhpWorkshop\Exercise\CgiExercise;
14-
use PhpSchool\PhpWorkshop\ExerciseDispatcher;
1515
use PhpSchool\PhpWorkshop\Input\Input;
1616
use PhpSchool\PhpWorkshop\Output\OutputInterface;
17-
use PhpSchool\PhpWorkshop\Result\CgiOutFailure;
1817
use PhpSchool\PhpWorkshop\Result\CgiOutRequestFailure;
1918
use PhpSchool\PhpWorkshop\Result\CgiOutResult;
2019
use PhpSchool\PhpWorkshop\Result\Failure;
@@ -237,7 +236,8 @@ private function getProcess($fileName, RequestInterface $request)
237236
*/
238237
public function verify(Input $input)
239238
{
240-
return new CgiOutResult(
239+
$this->eventDispatcher->dispatch(new ExerciseRunnerEvent('cgi.verify.start', $this->exercise, $input));
240+
$result = new CgiOutResult(
241241
$this->getName(),
242242
array_map(
243243
function (RequestInterface $request) use ($input) {
@@ -246,6 +246,8 @@ function (RequestInterface $request) use ($input) {
246246
$this->exercise->getRequests()
247247
)
248248
);
249+
$this->eventDispatcher->dispatch(new ExerciseRunnerEvent('cgi.verify.finish', $this->exercise, $input));
250+
return $result;
249251
}
250252

251253
/**
@@ -267,6 +269,7 @@ function (RequestInterface $request) use ($input) {
267269
*/
268270
public function run(Input $input, OutputInterface $output)
269271
{
272+
$this->eventDispatcher->dispatch(new ExerciseRunnerEvent('cgi.run.start', $this->exercise, $input));
270273
$success = true;
271274
foreach ($this->exercise->getRequests() as $i => $request) {
272275
$event = $this->eventDispatcher->dispatch(
@@ -295,6 +298,7 @@ public function run(Input $input, OutputInterface $output)
295298

296299
$output->lineBreak();
297300
}
301+
$this->eventDispatcher->dispatch(new ExerciseRunnerEvent('cgi.run.finish', $this->exercise, $input));
298302
return $success;
299303
}
300304
}

src/ExerciseRunner/CliRunner.php

+15-1
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@
88
use PhpSchool\PhpWorkshop\Event\CliExecuteEvent;
99
use PhpSchool\PhpWorkshop\Event\Event;
1010
use PhpSchool\PhpWorkshop\Event\EventDispatcher;
11+
use PhpSchool\PhpWorkshop\Event\ExerciseRunnerEvent;
1112
use PhpSchool\PhpWorkshop\Exception\CodeExecutionException;
1213
use PhpSchool\PhpWorkshop\Exception\SolutionExecutionException;
1314
use PhpSchool\PhpWorkshop\Exercise\CliExercise;
14-
use PhpSchool\PhpWorkshop\ExerciseDispatcher;
1515
use PhpSchool\PhpWorkshop\Input\Input;
1616
use PhpSchool\PhpWorkshop\Output\OutputInterface;
1717
use PhpSchool\PhpWorkshop\Result\Failure;
@@ -127,6 +127,18 @@ private function getPhpProcess($fileName, ArrayObject $args)
127127
* @return ResultInterface The result of the check.
128128
*/
129129
public function verify(Input $input)
130+
{
131+
$this->eventDispatcher->dispatch(new ExerciseRunnerEvent('cli.verify.start', $this->exercise, $input));
132+
$result = $this->doVerify($input);
133+
$this->eventDispatcher->dispatch(new ExerciseRunnerEvent('cli.verify.finish', $this->exercise, $input));
134+
return $result;
135+
}
136+
137+
/**
138+
* @param Input $input
139+
* @return ResultInterface
140+
*/
141+
private function doVerify(Input $input)
130142
{
131143
//arrays are not pass-by-ref
132144
$args = new ArrayObject($this->exercise->getArgs());
@@ -175,6 +187,7 @@ public function verify(Input $input)
175187
*/
176188
public function run(Input $input, OutputInterface $output)
177189
{
190+
$this->eventDispatcher->dispatch(new ExerciseRunnerEvent('cli.run.start', $this->exercise, $input));
178191
/** @var CliExecuteEvent $event */
179192
$event = $this->eventDispatcher->dispatch(
180193
new CliExecuteEvent('cli.run.student-execute.pre', new ArrayObject($this->exercise->getArgs()))
@@ -200,6 +213,7 @@ public function run(Input $input, OutputInterface $output)
200213
$output->writeLine($outputBuffer);
201214
});
202215

216+
$this->eventDispatcher->dispatch(new ExerciseRunnerEvent('cli.run.finish', $this->exercise, $input));
203217
return $process->isSuccessful();
204218
}
205219
}

src/Listener/CodePatchListener.php

+8-13
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use PhpSchool\PhpWorkshop\CodePatcher;
66
use PhpSchool\PhpWorkshop\Event\Event;
7+
use PhpSchool\PhpWorkshop\Event\ExerciseRunnerEvent;
78
use PhpSchool\PhpWorkshop\Input\Input;
89
use RuntimeException;
910

@@ -34,34 +35,28 @@ public function __construct(CodePatcher $codePatcher)
3435
}
3536

3637
/**
37-
* @param Event $event
38+
* @param ExerciseRunnerEvent $event
3839
*/
39-
public function patch(Event $event)
40+
public function patch(ExerciseRunnerEvent $event)
4041
{
41-
/** @var Input $input */
42-
$input = $event->getParameter('input');
43-
$fileName = $input->getArgument('program');
42+
$fileName = $event->getInput()->getArgument('program');
4443

4544
$this->originalCode = file_get_contents($fileName);
4645
file_put_contents(
4746
$fileName,
48-
$this->codePatcher->patch($event->getParameter('exercise'), $this->originalCode)
47+
$this->codePatcher->patch($event->getExercise(), $this->originalCode)
4948
);
5049
}
5150

5251
/**
53-
* @param Event $event
52+
* @param ExerciseRunnerEvent $event
5453
*/
55-
public function revert(Event $event)
54+
public function revert(ExerciseRunnerEvent $event)
5655
{
5756
if (null === $this->originalCode) {
5857
throw new RuntimeException('Can only revert previously patched code');
5958
}
6059

61-
/** @var Input $input */
62-
$input = $event->getParameter('input');
63-
$fileName = $input->getArgument('program');
64-
65-
file_put_contents($fileName, $this->originalCode);
60+
file_put_contents($event->getInput()->getArgument('program'), $this->originalCode);
6661
}
6762
}

src/Listener/PrepareSolutionListener.php

+4-3
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace PhpSchool\PhpWorkshop\Listener;
44

55
use PhpSchool\PhpWorkshop\Event\Event;
6+
use PhpSchool\PhpWorkshop\Event\ExerciseRunnerEvent;
67
use RuntimeException;
78
use Symfony\Component\Process\Process;
89

@@ -25,11 +26,11 @@ class PrepareSolutionListener
2526
];
2627

2728
/**
28-
* @param Event $event
29+
* @param ExerciseRunnerEvent $event
2930
*/
30-
public function __invoke(Event $event)
31+
public function __invoke(ExerciseRunnerEvent $event)
3132
{
32-
$solution = $event->getParameter('exercise')->getSolution();
33+
$solution = $event->getExercise()->getSolution();
3334

3435
if ($solution->hasComposerFile()) {
3536
//prepare composer deps

src/Listener/RealPathListener.php

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
3+
namespace PhpSchool\PhpWorkshop\Listener;
4+
5+
use PhpSchool\PhpWorkshop\CommandDefinition;
6+
use PhpSchool\PhpWorkshop\Event\Event;
7+
use PhpSchool\PhpWorkshop\Event\ExerciseRunnerEvent;
8+
use PhpSchool\PhpWorkshop\Input\Input;
9+
use PhpSchool\PhpWorkshop\UserState;
10+
11+
/**
12+
* @author Aydin Hassan <[email protected]>
13+
*/
14+
class RealPathListener
15+
{
16+
17+
/**
18+
* @param ExerciseRunnerEvent $event
19+
*/
20+
public function __invoke(ExerciseRunnerEvent $event)
21+
{
22+
$program = $event->getInput()->getArgument('program');
23+
24+
if (file_exists($program)) {
25+
$event->getInput()->setArgument('program', realpath($program));
26+
}
27+
}
28+
}

0 commit comments

Comments
 (0)