Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 9d08a52

Browse files
Merge pull request #134 from php-school/exercise-selected-event
Dispatch event when an exercise is selected
2 parents 79aef98 + ca50272 commit 9d08a52

File tree

5 files changed

+82
-24
lines changed

5 files changed

+82
-24
lines changed

‎src/Exercise/AbstractExercise.php‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ public function getSolution()
4141
sprintf(
4242
'%s/../../exercises/%s/solution/solution.php',
4343
dirname((new ReflectionClass(static::class))->getFileName()),
44-
$this->normaliseName($this->getName())
44+
self::normaliseName($this->getName())
4545
)
4646
)
4747
);
@@ -55,7 +55,7 @@ public function getSolution()
5555
*/
5656
public function getProblem()
5757
{
58-
$name = $this->normaliseName($this->getName());
58+
$name = self::normaliseName($this->getName());
5959
$dir = dirname((new ReflectionClass(static::class))->getFileName());
6060
return sprintf('%s/../../exercises/%s/problem/problem.md', $dir, $name);
6161
}
@@ -74,7 +74,7 @@ public function tearDown()
7474
* @param string $name
7575
* @return string
7676
*/
77-
private function normaliseName($name)
77+
publicstatic function normaliseName($name)
7878
{
7979
return preg_replace('/[^A-Za-z\-]+/', '', str_replace('', '-', strtolower($name)));
8080
}

‎src/Factory/EventDispatcherFactory.php‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ public function __invoke(ContainerInterface $container)
4040
$dispatcher->listen('verify.post.check', $container->get(SelfCheckListener::class));
4141

4242
//add listeners from config
43-
$eventListeners = $container->get('eventListeners') ?: [];
43+
$eventListeners = $container->has('eventListeners') ?$container->get('eventListeners') : [];
4444

4545
if (!is_array($eventListeners)) {
4646
throw InvalidArgumentException::typeMisMatch('array', $eventListeners);

‎src/Factory/MenuFactory.php‎

Lines changed: 35 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@
99
use PhpSchool\PhpWorkshop\Command\CreditsCommand;
1010
use PhpSchool\PhpWorkshop\Command\HelpCommand;
1111
use PhpSchool\PhpWorkshop\Command\MenuCommandInvoker;
12+
use PhpSchool\PhpWorkshop\Event\Event;
13+
use PhpSchool\PhpWorkshop\Event\EventDispatcher;
14+
use PhpSchool\PhpWorkshop\Exercise\AbstractExercise;
1215
use PhpSchool\PhpWorkshop\Exercise\ExerciseInterface;
1316
use PhpSchool\PhpWorkshop\ExerciseRenderer;
1417
use PhpSchool\PhpWorkshop\ExerciseRepository;
@@ -34,6 +37,7 @@ public function __invoke(ContainerInterface $c)
3437
$userState = $userStateSerializer->deSerialize();
3538
$exerciseRenderer = $c->get(ExerciseRenderer::class);
3639
$workshopType = $c->get(WorkshopType::class);
40+
$eventDispatcher = $c->get(EventDispatcher::class);
3741

3842
$builder = (new CliMenuBuilder)
3943
->addLineBreak();
@@ -46,17 +50,21 @@ public function __invoke(ContainerInterface $c)
4650
->addLineBreak('_')
4751
->addLineBreak()
4852
->addStaticItem('Exercises')
49-
->addStaticItem('---------')
50-
->addItems(
51-
array_map(function (ExerciseInterface $exercise) use ($exerciseRenderer, $userState, $workshopType) {
52-
return [
53-
$exercise->getName(),
54-
$exerciseRenderer,
55-
$userState->completedExercise($exercise->getName()),
56-
$this->isExerciseDisabled($exercise, $userState, $workshopType)
57-
];
58-
}, $exerciseRepository->findAll())
59-
)
53+
->addStaticItem('---------');
54+
55+
foreach ($exerciseRepository->findAll() as $exercise) {
56+
$builder->addItem(
57+
$exercise->getName(),
58+
function (CliMenu $menu) use ($exerciseRenderer, $eventDispatcher, $exercise) {
59+
$this->dispatchExerciseSelectedEvent($eventDispatcher, $exercise);
60+
$exerciseRenderer->__invoke($menu);
61+
},
62+
$userState->completedExercise($exercise->getName()),
63+
$this->isExerciseDisabled($exercise, $userState, $workshopType)
64+
);
65+
}
66+
67+
$builder
6068
->addLineBreak()
6169
->addLineBreak('-')
6270
->addLineBreak()
@@ -121,4 +129,20 @@ private function isExerciseDisabled(ExerciseInterface $exercise, UserState $user
121129
$previous = $exercise;
122130
return true;
123131
}
132+
133+
/**
134+
* @param EventDispatcher $eventDispatcher
135+
* @param ExerciseInterface $exercise
136+
*/
137+
private function dispatchExerciseSelectedEvent(EventDispatcher $eventDispatcher, ExerciseInterface $exercise)
138+
{
139+
$eventDispatcher->dispatch(
140+
new Event(
141+
sprintf(
142+
'exercise.selected.%s',
143+
AbstractExercise::normaliseName($exercise->getName())
144+
)
145+
)
146+
);
147+
}
124148
}

‎test/Factory/EventDispatcherFactoryTest.php‎

Lines changed: 40 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,11 @@ public function testConfigEventListenersThrowsExceptionIfEventsNotArray()
109109
->will($this->returnValue($selfCheckListener));
110110

111111
$c->expects($this->at(4))
112+
->method('has')
113+
->with('eventListeners')
114+
->willReturn(true);
115+
116+
$c->expects($this->at(5))
112117
->method('get')
113118
->with('eventListeners')
114119
->will($this->returnValue(new \stdClass));
@@ -150,6 +155,11 @@ public function testConfigEventListenersThrowsExceptionIfEventsListenersNotArray
150155
->will($this->returnValue($selfCheckListener));
151156

152157
$c->expects($this->at(4))
158+
->method('has')
159+
->with('eventListeners')
160+
->willReturn(true);
161+
162+
$c->expects($this->at(5))
153163
->method('get')
154164
->with('eventListeners')
155165
->will($this->returnValue([ 'someEvent' => new \stdClass]));
@@ -191,6 +201,11 @@ public function testConfigEventListenersThrowsExceptionIfEventsListenerNotCallab
191201
->will($this->returnValue($selfCheckListener));
192202

193203
$c->expects($this->at(4))
204+
->method('has')
205+
->with('eventListeners')
206+
->willReturn(true);
207+
208+
$c->expects($this->at(5))
194209
->method('get')
195210
->with('eventListeners')
196211
->will($this->returnValue([ 'someEvent' => [new \stdClass]]));
@@ -232,11 +247,16 @@ public function testConfigEventListenersThrowsExceptionIfEventsListenerContainer
232247
->will($this->returnValue($selfCheckListener));
233248

234249
$c->expects($this->at(4))
250+
->method('has')
251+
->with('eventListeners')
252+
->willReturn(true);
253+
254+
$c->expects($this->at(5))
235255
->method('get')
236256
->with('eventListeners')
237257
->will($this->returnValue([ 'someEvent' => ['nonExistingContainerEntry']]));
238258

239-
$c->expects($this->once())
259+
$c->expects($this->at(6))
240260
->method('has')
241261
->with('nonExistingContainerEntry')
242262
->will($this->returnValue(false));
@@ -278,16 +298,21 @@ public function testConfigEventListenersThrowsExceptionIfEventsListenerContainer
278298
->will($this->returnValue($selfCheckListener));
279299

280300
$c->expects($this->at(4))
301+
->method('has')
302+
->with('eventListeners')
303+
->willReturn(true);
304+
305+
$c->expects($this->at(5))
281306
->method('get')
282307
->with('eventListeners')
283308
->will($this->returnValue([ 'someEvent' => ['notCallableEntry']]));
284309

285-
$c->expects($this->once())
310+
$c->expects($this->at(6))
286311
->method('has')
287312
->with('notCallableEntry')
288313
->will($this->returnValue(true));
289314

290-
$c->expects($this->at(6))
315+
$c->expects($this->at(7))
291316
->method('get')
292317
->with('notCallableEntry')
293318
->will($this->returnValue(null));
@@ -332,11 +357,15 @@ public function testConfigEventListenersWithAnonymousFunction()
332357
};
333358

334359
$c->expects($this->at(4))
360+
->method('has')
361+
->with('eventListeners')
362+
->willReturn(true);
363+
364+
$c->expects($this->at(5))
335365
->method('get')
336366
->with('eventListeners')
337367
->will($this->returnValue([ 'someEvent' => [$callback]]));
338368

339-
340369
$dispatcher = (new EventDispatcherFactory)->__invoke($c);
341370
$this->assertInstanceOf(EventDispatcher::class, $dispatcher);
342371
$this->assertSame(
@@ -398,22 +427,25 @@ public function testConfigEventListenersWithContainerEntry()
398427
->with(SelfCheckListener::class)
399428
->will($this->returnValue($selfCheckListener));
400429

401-
402-
403430
$c->expects($this->at(4))
431+
->method('has')
432+
->with('eventListeners')
433+
->willReturn(true);
434+
435+
$c->expects($this->at(5))
404436
->method('get')
405437
->with('eventListeners')
406438
->will($this->returnValue([ 'someEvent' => ['containerEntry']]));
407439

408-
$c->expects($this->once())
440+
$c->expects($this->at(6))
409441
->method('has')
410442
->with('containerEntry')
411443
->will($this->returnValue(true));
412444

413445
$callback = function () {
414446
};
415447

416-
$c->expects($this->at(6))
448+
$c->expects($this->at(7))
417449
->method('get')
418450
->with('containerEntry')
419451
->will($this->returnValue($callback));

‎test/Factory/MenuFactoryTest.php‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use PhpSchool\CliMenu\CliMenu;
77
use PhpSchool\PhpWorkshop\Command\CreditsCommand;
88
use PhpSchool\PhpWorkshop\Command\HelpCommand;
9+
use PhpSchool\PhpWorkshop\Event\EventDispatcher;
910
use PhpSchool\PhpWorkshop\Exercise\ExerciseInterface;
1011
use PhpSchool\PhpWorkshop\ExerciseRenderer;
1112
use PhpSchool\PhpWorkshop\ExerciseRepository;
@@ -53,7 +54,8 @@ public function testFactoryReturnsInstance()
5354
'bgColour' => 'black',
5455
'fgColour' => 'green',
5556
'workshopTitle' => 'TITLE',
56-
WorkshopType::class => WorkshopType::STANDARD()
57+
WorkshopType::class => WorkshopType::STANDARD(),
58+
EventDispatcher::class => $this->createMock(EventDispatcher::class),
5759
];
5860

5961
$container

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /