public function it_can_add_a_converter(ConverterInterface $converter, Emitter $emitter) { $pHigh = EmitterInterface::P_HIGH; $pNormal = EmitterInterface::P_NORMAL; $pLow = EmitterInterface::P_LOW; $converter->getSubscribedEvents()->shouldBeCalled()->willReturn(['img' => 'handleImg', 'convert.foo' => ['handleFoo', $pHigh], 'convert.bar' => ['handleBar', $pLow], 'convertfizz' => ['badFizzHandler'], 'convert..buzz' => ['badBuzzHandler']]); $emitter->addListener('convert.img', [$converter, 'handleImg'], $pNormal)->shouldBeCalled(); $emitter->addListener('convert.foo', [$converter, 'handleFoo'], $pHigh)->shouldBeCalled(); $emitter->addListener('convert.bar', [$converter, 'handleBar'], $pLow)->shouldBeCalled(); $emitter->addListener('convert.convertfizz', [$converter, 'badFizzHandler'], $pNormal)->shouldBeCalled(); $emitter->addListener('convert..buzz', [$converter, 'badBuzzHandler'], $pNormal)->shouldBeCalled(); $this->addConverter($converter)->shouldReturn($this); }
/** * Register Event Listeners. * * @param array $appEvents * @return void */ protected function loadEvents($appEvents) { foreach ((array) $appEvents as $appEventType => $events) { foreach ($events as $event) { $this->eventDispatcher->addListener($appEventType, $this->container->get($event)); } } }
public function testDecoratingRenderedOutputInAfterRenderEvent() { $mock = $this->getMockRenderer('foobar'); $dispatcher = new Emitter(); $dispatcher->addListener(EventTriggeringRenderer::AFTER_RENDER_EVENT, function ($event) { $event->setOutput($event->getOutput() . ' + called from event'); }); $renderer = new EventTriggeringRenderer($mock, $dispatcher); $text = $renderer->render('some source'); $this->assertSame('foobar + called from event', $text); }
public function testResponseReady() { $emitter = new Emitter(); $callback = function ($event, $parms) { $this->assertInstanceOf(Response::class, $parms['response']); }; $emitter->addListener('response_ready', CallbackListener::fromCallable($callback)); $api = new Server($emitter); $api->registerServiceLoader(new DirectoryServiceLoader(__DIR__ . '/services', '\\TestApi')); $request = Request::create('/v1/test/123', 'GET'); $response = $api->run($request); }
public function register(ContainerInterface $container) { $config = $this->getConfig(); $container['events'] = function () use($config) { $emitter = new Emitter(); foreach ($config['listeners'] as $event => $eventListeners) { foreach ($eventListeners as $eventListener) { $emitter->addListener($event, $eventListener); } } return $emitter; }; }
/** * Inform ContentEvent of our ModifyContentListener in order to transform the content body attribute * from Markdown to HTML. * * @param \League\Event\Emitter $event */ protected function registerEventListeners(Emitter $event) { $event->addListener('ContentEvent', new ContentListener()); }
/** * @param BoardFactory $boardFactory * * @throws \Illuminate\Contracts\Filesystem\FileNotFoundException * @throws \React\Socket\ConnectionException */ public function run(BoardFactory $boardFactory) { $emitter = new Emitter(); $wamp = new WampConnector($emitter); $webSocket = new \React\Socket\Server($this->eventLoop); $webSocket->listen(self::SOCKET_LISTEN_PORT, '0.0.0.0'); $board = $boardFactory->initialize(); new IoServer(new HttpServer(new WsServer(new WampServer($wamp))), $webSocket); $emitter->addListener(QuestionSubscriptionEvent::class, function (QuestionSubscriptionEvent $event) use($wamp, $board) { $wamp->onQuestionSubscribe($board->getCategories(), $event->getSessionId()); }); $emitter->addListener(ContestantScoreSubscriptionEvent::class, function (ContestantScoreSubscriptionEvent $event) use($wamp, $board) { $wamp->onContestantScoreSubscription($board->getContestants(), $event->getSessionId()); }); $emitter->addListener(BuzzerStatusSubscriptionEvent::class, function (BuzzerStatusSubscriptionEvent $event) use($wamp, $board) { $wamp->onBuzzerStatusChange($board->getBuzzerStatus(), [], [$event->getSessionId()]); }); $emitter->addListener(BuzzerResolutionEvent::class, function (BuzzerResolutionEvent $event) use($wamp) { //TODO Store this event echo 'Buzzer Resolution: ' . $event->getResolution()->getContestant()->getName() . " buzzed in ({$event->getResolution()->getTime()}ms)\n"; $wamp->onBuzzerResolution($event->getResolution()); }); $emitter->addListener(QuestionAnswerEvent::class, function (QuestionAnswerEvent $event) use($wamp, $board, $emitter) { try { $questionAnswer = $event->getQuestionAnswer(); $board->addScore($questionAnswer->getContestant(), $questionAnswer->getRealValue()); $wamp->onQuestionAnswer($questionAnswer); } catch (ContestantNotFoundException $exception) { echo $exception->getMessage(); // TODO handle exception } if ($questionAnswer->isCorrect()) { $emitter->emit(new QuestionDismissalEvent(new QuestionDismissal($questionAnswer->getCategory(), $questionAnswer->getValue()))); return; } $emitter->emit(new BuzzerStatusChangeEvent(new BuzzerStatus(true))); }); $emitter->addListener(QuestionDisplayRequestEvent::class, function (QuestionDisplayRequestEvent $event) use($wamp, $board) { try { $question = $board->getQuestionByCategoryAndValue($event->getCategoryName(), $event->getValue()); $question->setUsed(); $wamp->onQuestionDisplay($question, $event->getCategoryName()); } catch (QuestionNotFoundException $exception) { //TODO log this somewhere. echo "Error occured, could not find question in category: {$event->getCategoryName()} valued at: {$event->getValue()}"; } }); $emitter->addListener(DailyDoubleBetEvent::class, function (DailyDoubleBetEvent $event) use($wamp, $board) { try { $question = $board->getQuestionByCategoryAndValue($event->getCategory(), $event->getValue()); } catch (QuestionNotFoundException $e) { // TODO } $wamp->onDailyDoubleBetRecieved($question, $event->getCategory(), $event->getBet()); }); $emitter->addListener(QuestionDismissalEvent::class, function (QuestionDismissalEvent $event) use($wamp, $board) { $dismissal = $event->getDismissal(); $wamp->onQuestionDismiss($dismissal); }); $emitter->addListener(BuzzReceivedEvent::class, function (BuzzReceivedEvent $event) use($board, $emitter) { if (!$board->getBuzzerStatus()->isActive()) { // The buzzer isn't active, so there's nothing to do. return; } if ($board->getResolver()->isEmpty()) { // If this is the first buzz, then we want to resolve it after the timeout. $this->eventLoop->addTimer($this->buzzer_resolve_timeout, function () use($board, $emitter) { $resolution = $board->resolveBuzzes(); $emitter->emit(new BuzzerResolutionEvent($resolution)); }); } // TODO store this event echo 'Buzz in (' . $event->getContestant()->getName() . '): ' . $event->getDifference() . "ms \n"; $board->getResolver()->addBuzz($event); }); $emitter->addListener(BuzzerStatusChangeEvent::class, function (BuzzerStatusChangeEvent $event) use($wamp, $board) { $board->setBuzzerStatus($event->getBuzzerStatus()); $wamp->onBuzzerStatusChange($event->getBuzzerStatus()); }); $emitter->addListener(FinalJeopardyCategoryRequest::class, function (FinalJeopardyCategoryRequest $event) use($wamp, $board) { $wamp->onFinalJeopardyRequest('category', $board->getFinalJeopardyClue()); }); $emitter->addListener(FinalJeopardyClueRequest::class, function (FinalJeopardyClueRequest $event) use($wamp, $board) { $wamp->onFinalJeopardyBetCollectionRequest(); // We're going to wait for a set time //TODO this doesn't work for some reason in every case, so we simply don't close the acceptance of responses. $this->eventLoop->addTimer($this->final_jeopardy_collection_timeout, function () use($wamp, $board) { if (!$board->getFinalJeopardy()->hasAllBets()) { //TODO logging echo "Did not recieve all bets.\n"; $missingbets = $board->getFinalJeopardy()->getMissingBets(); $missingbets = implode(', ', $missingbets); echo "Require bets from: {$missingbets}\n"; } $wamp->onFinalJeopardyRequest('clue', $board->getFinalJeopardyClue()); }); }); $emitter->addListener(ContestantScoreChangeEvent::class, function (ContestantScoreChangeEvent $event) use($wamp, $board) { try { $board->addScore(new Contestant($event->getContestant()), $event->getScoreChange()); } catch (ContestantNotFoundException $e) { //TODO } $contestant = $board->getContestants()->first(function ($key, Contestant $contestant) use($event) { return $contestant->getName() === $event->getContestant(); }); $wamp->onContestantScoreUpdate($contestant); }); $emitter->addListener(FinalJeopardyBetEvent::class, function (FinalJeopardyBetEvent $event) use($wamp, $board) { $finalJeopardy = $board->getFinalJeopardy(); $finalJeopardy->setBet($event->getContestant(), $event->getBet()); }); $emitter->addListener(FinalJeopardyAnswerRequest::class, function (FinalJeopardyAnswerRequest $event) use($wamp, $board) { $wamp->onFinalJeopardyAnswerCollectionRequest(); $this->eventLoop->addTimer($this->final_jeopardy_collection_timeout, function () use($wamp, $board) { if (!$board->getFinalJeopardy()->hasAllAnswers()) { //TODO logging echo "Did not receive all final jeopardy answers!\n"; $missingAnswers = $board->getFinalJeopardy()->getMissingAnswers(); $missingAnswers = implode(', ', $missingAnswers); echo "Require answers from: {$missingAnswers}\n"; } $wamp->onFinalJeopardyRequest('answer', $board->getFinalJeopardyClue()); }); }); $emitter->addListener(FinalJeopardyAnswerEvent::class, function (FinalJeopardyAnswerEvent $event) use($wamp, $board) { $finalJeopardy = $board->getFinalJeopardy(); if ($finalJeopardy->hasAnswer($event->getContestant())) { //TODO logging echo "{$event->getContestant()} has already submitted a final answer"; return; } $finalJeopardy->setAnswer($event->getContestant(), $event->getAnswer()); }); $emitter->addListener(FinalJeopardyResponseRequest::class, function (FinalJeopardyResponseRequest $event) use($wamp, $board) { $finalJeopardy = $board->getFinalJeopardy(); if (!$finalJeopardy->hasAnswer($event->getContestant())) { //TODO logging $response = new FinalJeopardyQuestionResponse($event->getContestant(), 0, 'No answer, Troy'); $wamp->onFinalJeopardyResponse($response); return; } $wamp->onFinalJeopardyResponse($finalJeopardy->getResponse($event->getContestant())); }); $this->eventLoop->run(); }
/** * Add a listener * * @param string event name * @param mixed listener a closure or FQCN * @param int priority, default = 0 * @return void */ public function listen($name, $listener, $priority = EmitterInterface::P_NORMAL) { self::$emitter->addListener($name, $listener, $priority); }
/** * @see AbstractDispatcherAdapter::on */ public function on($name, callable $listener, $priority = 0) { $this->emitter->addListener($name, $listener, $priority); return $this; }
/** * @param \League\Event\Emitter $event */ protected function registerEventListeners(Emitter $event) { $event->addListener('RouterEvent', function ($event) { $event->router->addRoute('GET', '/{fileId:[a-zA-Z0-9_\\-\\/]*}.json', 'Songbird\\Package\\Jsonable\\Handler::__invoke'); }, 100); }
/** * @dataProvider eventEmitterProxyData */ public function testEventEmitArguments($engineMethod, $eventType) { $emitter = new Emitter(); $actual = null; $emitter->addListener($eventType, function (...$args) use(&$actual) { array_shift($args); // we expect the first argument to be an event $actual = $args; }); $engine = new ExtraEventEmitArgs($this->mockPluginManager, $emitter); if ($eventType === Engine::EXCEPTION_THROWN_EVENT) { $engine->onAppExecute(function () { throw new \Exception(); }); } $engine->run(); $this->assertSame([$engine, 1, 'foo', 'bar'], $actual); }
/** * {@inheritdoc} */ public function on(Input $input, State $currentState, Listener $listener, int $priority = Emitter::P_NORMAL) { $this->emitter->addListener($this->getEventName('on', $input, $currentState), $listener, $priority); }
/** * Add an event listener to the event emitter * * @param string $eventName Event name * @param callable $listener Callable function or method */ public function addEventListener($eventName, callable $listener) { $this->eventEmitter->addListener($eventName, $listener); }
use League\Event\Emitter; use League\Event\AbstractEvent; use League\Event\CallbackListener; use Monolog\Logger; use Monolog\Handler\StreamHandler; // Setup a logger $log = new Logger('API'); $log->pushHandler(new StreamHandler('/tmp/api_log.txt', Logger::WARNING)); // We are interested in some events generated by the server $emitter = new Emitter(); // This will be emitted right before control is dispatched to the actual service $callback = function (AbstractEvent $event, $param = null) use($log) { // In the real world, you would (for an example) validate OAuth2 headers here $log->addNotice(serialize($param)); }; $emitter->addListener('dispatch', CallbackListener::fromCallable($callback)); // This will be emitted when an exception is going to be processed and "converted" into JSON $callback = function ($event, $param) use($log) { $log->addError($param['exception']->getMessage()); }; $emitter->addListener('exception', CallbackListener::fromCallable($callback)); // This will be emitted when an PHP error (warning, notice, fatal) has happened and the processing $callback = function ($event, $errorStr) use($log) { $log->addWarning($errorStr); }; $emitter->addListener('error', CallbackListener::fromCallable($callback)); // Create the actual REST server $api = new Server($emitter); // Use the built-in error handlers that prevent any default PHP behavior and ensure all errors are // cleanly returned as JSON. For logging purposes you should use the event listeners $api->registerErrorHandlers();
public function testControllerMustReturnResponse() { $req = (new Request())->withMethod('GET')->withUri(new Uri('http://test.example.com')); $resolved = new ResolvedRoute($req, function () { return 'not a response'; }, StatusCodes::OK); $this->mockRouter->expects($this->once())->method('match')->with($this->isInstanceOf(ServerRequestInterface::class))->willReturn($resolved); $emitter = new EventEmitter(); $actual = [null, null]; $emitter->addListener(Engine::EXCEPTION_THROWN_EVENT, function (ExceptionThrownEvent $event) use(&$actual) { $actual = [get_class($event->getException()), $event->getException()->getMessage()]; }); $this->runEngine($this->getMockedEngine(null, $emitter), $req, false); list($actualType, $actualMsg) = $actual; $expectedExcType = InvalidTypeException::class; $expectedMsg = "Controller MUST return an instance of Psr\\Http\\Message\\ResponseInterface, \"string\" was returned."; $this->assertSame($expectedExcType, $actualType); $this->assertSame($expectedMsg, $actualMsg); }
/** * The thread's run() method that runs asynchronously. * * @link http://www.php.net/manual/en/thread.run.php */ public function run() { // register a shutdown handler for controlled shutdown register_shutdown_function(array(&$this, 'shutdown')); // we need the autloader again require SERVER_AUTOLOADER; // create the service emitter $emitter = new Emitter(); // load the bootstrap configuration /** @var \AppserverIo\Appserver\Core\Api\Node\BootstrapNodeInterface $bootstrapNode */ $bootstrapNode = $this->doLoadBootstrap($this->getBootstrapConfigurationFilename()); // iterate over the listeners and add them to the emitter /** @var \AppserverIo\Appserver\Core\Api\Node\ListenerNodeInterface $listener */ foreach ($bootstrapNode->getListeners() as $listener) { // load the listener class name $listenerClassName = $listener->getType(); // create a new instance of the listener class /** @var \League\Event\ListenerInterface $listenerInstance */ $listenerInstance = new $listenerClassName(); // query whether we've to inject the application server instance or not if ($listenerInstance instanceof ApplicationServerAwareListenerInterface) { $listenerInstance->injectApplicationServer($this); } // add the listeners $emitter->addListener($listener->getEvent(), $listenerInstance); } // synchronize the emitter $this->emitter = $emitter; // override the default runlevel with the value found in the bootstrap configuration $this->runlevel = $this->runlevelFromString($bootstrapNode->getDefaultRunlevel()); // flag to keep the server running or to stop it $keepRunning = true; // initialize the actual runlevel with -1 $actualRunlevel = -1; // start with the default runlevel $this->init(null, $this->runlevel); do { try { switch ($this->command) { case InitCommand::COMMAND: // copy command params -> the requested runlevel in that case $this->runlevel = $this->params; if ($this->runlevel == ApplicationServerInterface::REBOOT) { // backup the runlevel $backupRunlevel = $actualRunlevel; // shutdown the application server for ($i = $actualRunlevel; $i >= ApplicationServerInterface::SHUTDOWN; $i--) { $this->emitter->emit(sprintf('leave.runlevel.%s', $this->runlevelToString($i)), $i); // stop the services of the PREVIOUS runlevel $this->doStopServices($i + 1); } // switch back to the runlevel we backed up before for ($z = ApplicationServerInterface::SHUTDOWN; $z <= $backupRunlevel; $z++) { $this->emitter->emit(sprintf('enter.runlevel.%s', $this->runlevelToString($z)), $z); } // set the runlevel to the one before we restart $actualRunlevel = $backupRunlevel; // reset the runlevel and the params $this->runlevel = $this->params = $actualRunlevel; } elseif ($actualRunlevel == ApplicationServerInterface::SHUTDOWN) { // we want to shutdown the application server $keepRunning = false; } elseif ($actualRunlevel < $this->runlevel) { // switch to the requested runlevel for ($i = $actualRunlevel + 1; $i <= $this->runlevel; $i++) { $this->emitter->emit(sprintf('enter.runlevel.%s', $this->runlevelToString($i)), $i); } // set the new runlevel $actualRunlevel = $this->runlevel; } elseif ($actualRunlevel > $this->runlevel) { // switch down to the requested runlevel for ($i = $actualRunlevel; $i >= $this->runlevel; $i--) { $this->emitter->emit(sprintf('leave.runlevel.%s', $this->runlevelToString($i)), $i); // stop the services of the PREVIOUS runlevel $this->doStopServices($i + 1); } // set the new runlevel $actualRunlevel = $this->runlevel; } else { // signal that we've finished switching the runlevels and wait $this->locked = false; $this->command = null; // print a message and wait $this->getSystemLogger()->info(sprintf('Switched to runlevel %s!!!', $actualRunlevel)); // wait for a new command $this->synchronized(function ($self) { $self->wait(); }, $this); } break; case ModeCommand::COMMAND: // switch the application server mode $this->doSwitchSetupMode($this->params, $this->getConfigurationFilename()); // singal that we've finished setting umask and wait $this->locked = false; $this->command = null; // wait for a new command $this->synchronized(function ($self) { $self->wait(); }, $this); break; case DoctrineCommand::COMMAND: // execute the Doctrine command $this->result = $this->doDoctrine($this->params); // singal that we've finished setting umask and wait $this->locked = false; $this->command = null; // wait for a new command $this->synchronized(function ($self) { $self->wait(); }, $this); break; default: // print a message and wait $this->getSystemLogger()->info('Can\'t find any command!!!'); // singal that we've finished setting umask and wait $this->locked = false; // wait for a new command $this->synchronized(function ($self) { $self->wait(); }, $this); break; } } catch (\Exception $e) { $this->getSystemLogger()->error($e->getMessage()); } } while ($keepRunning); }
/** * Loads the events emitter * * @param Container $container * @return Emitter */ private function loadEvents(Container $container) { $events = (require_once __DIR__ . '/../config/events.php'); $emitter = new Emitter(); foreach ($events as $event) { $emitter->addListener($event['name'], $event['listener'], isset($event['priority']) ? $event['priority'] : 0); } return $emitter; }
/** * Add an event listener to the event emitter * * @param string $eventName Event name * @param callable $listener Callable function or method * @param int $priority Priority of event listener */ public function addEventListener($eventName, callable $listener, $priority = Emitter::P_NORMAL) { $this->eventEmitter->addListener($eventName, $listener, $priority); }