Skip to content

Commit

Permalink
Merge cf58d3a into 57edd92
Browse files Browse the repository at this point in the history
  • Loading branch information
adaamz committed Mar 21, 2019
2 parents 57edd92 + cf58d3a commit 8a6defb
Show file tree
Hide file tree
Showing 9 changed files with 55 additions and 45 deletions.
12 changes: 6 additions & 6 deletions .travis.yml
Expand Up @@ -11,6 +11,7 @@ php:
- 7.0
- 7.1
- 7.2
- 7.3

env:
- # dev
Expand All @@ -20,28 +21,27 @@ env:
matrix:
fast_finish: true
include:
- php: 7.2
- php: 7.3
env: COMPOSER_EXTRA_ARGS="--prefer-stable" COVERAGE="--coverage ./coverage.xml --coverage-src ./src" TESTER_RUNTIME="phpdbg"
- php: 7.2
- php: 7.3
env: COMPOSER_EXTRA_ARGS="--prefer-stable" PHPSTAN=1
- php: 7.2
- php: 7.3
env: COMPOSER_EXTRA_ARGS="--prefer-stable" CODING_STANDARD=1
allow_failures:
- env:
- php: 7.2
- php: 7.3
env: COMPOSER_EXTRA_ARGS="--prefer-stable" COVERAGE="--coverage ./coverage.xml --coverage-src ./src" TESTER_RUNTIME="phpdbg"

install:
- if [ "$CODING_STANDARD" = "1" ]; then composer require --dev --no-update kdyby/coding-standard:^1.0@dev; fi
- if [ "$PHPSTAN" = "1" ]; then composer require --dev --no-update phpstan/phpstan-shim:^0.7; fi
- travis_retry composer update --no-interaction --no-suggest --no-progress --prefer-dist $COMPOSER_EXTRA_ARGS
- travis_retry composer create-project --no-interaction jakub-onderka/php-parallel-lint /tmp/php-parallel-lint
- if [ "$COVERAGE" != "" ]; then travis_retry wget -O /tmp/coveralls.phar https://github.com/satooshi/php-coveralls/releases/download/v1.0.1/coveralls.phar; fi

script:
- vendor/bin/tester $COVERAGE -s -p ${TESTER_RUNTIME:-php} -c ./tests/php.ini-unix ./tests/KdybyTests/
- php /tmp/php-parallel-lint/parallel-lint.php -e php,phpt --exclude vendor .
- if [ "$PHPSTAN" = "1" ]; then php vendor/phpstan/phpstan-shim/phpstan.phar analyse --ansi --no-progress -l7 -c phpstan.neon src tests/KdybyTests; fi
- if [ "$PHPSTAN" = "1" ]; then php vendor/bin/phpstan analyse --ansi --no-progress; fi
- if [ "$CODING_STANDARD" = "1" ]; then php vendor/bin/phpcs --standard=ruleset.xml --encoding=utf-8 -sp src tests; fi

after_script:
Expand Down
3 changes: 2 additions & 1 deletion composer.json
Expand Up @@ -33,7 +33,8 @@

"symfony/event-dispatcher": "^3.0 || ^4.0",

"nette/tester": "^2.0"
"nette/tester": "^2.0",
"phpstan/phpstan-shim": "^0.11"
},
"minimum-stability": "dev",
"autoload": {
Expand Down
3 changes: 0 additions & 3 deletions phpstan.neon

This file was deleted.

5 changes: 5 additions & 0 deletions phpstan.neon.dist
@@ -0,0 +1,5 @@
parameters:
level: 7
paths:
- src
- tests/KdybyTests
24 changes: 13 additions & 11 deletions src/Events/DI/EventsExtension.php
Expand Up @@ -174,9 +174,9 @@ public function afterCompile(ClassTypeGenerator $class)

/** @hack This tries to add the event invokation right after the code, generated by NetteExtension. */
$foundNetteInitStart = $foundNetteInitEnd = FALSE;
$lines = explode(";\n", trim($init->getBody()));
$lines = explode(";\n", trim((string) $init->getBody()));
$init->setBody(NULL);
while (($line = array_shift($lines)) || $lines) {
while (($line = array_shift($lines)) !== NULL) {
if ($foundNetteInitStart && !$foundNetteInitEnd &&
stripos($line, 'Nette\\') === FALSE && stripos($line, 'set_include_path') === FALSE && stripos($line, 'date_default_timezone_set') === FALSE
) {
Expand Down Expand Up @@ -237,7 +237,9 @@ private function validateSubscribers(DIContainerBuilder $builder, ServiceDefinit
);
}

if (!$def->getClass()) {
$defClass = $def->getClass();

if (!$defClass) {
throw new \Nette\Utils\AssertionException(
sprintf(
'Please, specify existing class for %sservice @%s explicitly, and make sure, that the class exists and can be autoloaded.',
Expand All @@ -246,49 +248,49 @@ private function validateSubscribers(DIContainerBuilder $builder, ServiceDefinit
)
);

} elseif (!class_exists($def->getClass())) {
} elseif (!class_exists($defClass)) {
throw new \Nette\Utils\AssertionException(
sprintf(
'Class %s of %sservice @%s cannot be found. Please make sure, that the class exists and can be autoloaded.',
$def->getClass(),
$defClass,
is_numeric($serviceName) ? 'anonymous ' : '',
$serviceName
)
);
}

if (!in_array(EventSubscriber::class, class_implements($def->getClass()))) {
if (!in_array(EventSubscriber::class, class_implements($defClass), TRUE)) {
// the minimum is Doctrine EventSubscriber, but recommend is Kdyby Subscriber
throw new \Nette\Utils\AssertionException(sprintf('Subscriber @%s doesn\'t implement %s.', $serviceName, Subscriber::class));
}

$eventNames = [];
$listenerInst = self::createEventSubscriberInstanceWithoutConstructor($def->getClass());
$listenerInst = self::createEventSubscriberInstanceWithoutConstructor($defClass);
foreach ($listenerInst->getSubscribedEvents() as $eventName => $params) {
if (is_numeric($eventName) && is_string($params)) { // [EventName, ...]
list(, $method) = Event::parseName($params);
$eventNames[] = ltrim($params, '\\');
if (!method_exists($listenerInst, $method)) {
throw new \Nette\Utils\AssertionException(sprintf('Event listener %s::%s() is not implemented.', $def->getClass(), $method));
throw new \Nette\Utils\AssertionException(sprintf('Event listener %s::%s() is not implemented.', $defClass, $method));
}

} elseif (is_string($eventName)) { // [EventName => ???, ...]
$eventNames[] = ltrim($eventName, '\\');

if (is_string($params)) { // [EventName => method, ...]
if (!method_exists($listenerInst, $params)) {
throw new \Nette\Utils\AssertionException(sprintf('Event listener %s::%s() is not implemented.', $def->getClass(), $params));
throw new \Nette\Utils\AssertionException(sprintf('Event listener %s::%s() is not implemented.', $defClass, $params));
}

} elseif (is_string($params[0])) { // [EventName => [method, priority], ...]
if (!method_exists($listenerInst, $params[0])) {
throw new \Nette\Utils\AssertionException(sprintf('Event listener %s::%s() is not implemented.', $def->getClass(), $params[0]));
throw new \Nette\Utils\AssertionException(sprintf('Event listener %s::%s() is not implemented.', $defClass, $params[0]));
}

} else {
foreach ($params as $listener) { // [EventName => [[method, priority], ...], ...]
if (!method_exists($listenerInst, $listener[0])) {
throw new \Nette\Utils\AssertionException(sprintf('Event listener %s::%s() is not implemented.', $def->getClass(), $listener[0]));
throw new \Nette\Utils\AssertionException(sprintf('Event listener %s::%s() is not implemented.', $defClass, $listener[0]));
}
}
}
Expand Down
14 changes: 7 additions & 7 deletions src/Events/Diagnostics/Panel.php
Expand Up @@ -70,7 +70,7 @@ class Panel implements \Tracy\IBarPanel
private $registeredClasses;

/**
* @var bool
* @var bool|array<string, mixed>
*/
public $renderPanel = TRUE;

Expand Down Expand Up @@ -151,7 +151,7 @@ public function getTab()
}

return '<span title="Kdyby/Events">'
. '<img width="16" height="16" src="data:image/png;base64,' . base64_encode(file_get_contents(__DIR__ . '/icon.png')) . '" />'
. '<img width="16" height="16" src="data:image/png;base64,' . base64_encode((string) file_get_contents(__DIR__ . '/icon.png')) . '" />'
. '<span class="tracy-label">' . count(Arrays::flatten($this->dispatchLog)) . ' calls</span>'
. '</span>';
}
Expand Down Expand Up @@ -190,7 +190,7 @@ public function getPanel()
$totalListeners = count(array_unique(Arrays::flatten($this->listenerIds)));

return '<style>' . $this->renderStyles() . '</style>' .
'<h1>' . $h($totalEvents) . ' registered events, ' . $h($totalListeners) . ' registered listeners</h1>' .
'<h1>' . $h((string) $totalEvents) . ' registered events, ' . $h((string) $totalListeners) . ' registered listeners</h1>' .
'<div class="nette-inner tracy-inner nette-KdybyEventsPanel"><table>' . $s . '</table></div>';
}

Expand Down Expand Up @@ -343,18 +343,18 @@ private function renderListeners($ids)
{
static $addIcon;
if (empty($addIcon)) {
$addIcon = '<img width="18" height="18" src="data:image/png;base64,' . base64_encode(file_get_contents(__DIR__ . '/add.png')) . '" title="Listener" />';
$addIcon = '<img width="18" height="18" src="data:image/png;base64,' . base64_encode((string) file_get_contents(__DIR__ . '/add.png')) . '" title="Listener" />';
}

$registeredClasses = $this->getClassMap();

$h = 'htmlspecialchars';

$shortFilename = function (ReflectionFunctionAbstract $refl) {
$title = '.../' . basename($refl->getFileName()) . ':' . $refl->getStartLine();
$title = '.../' . basename((string) $refl->getFileName()) . ':' . $refl->getStartLine();

/** @var string|NULL $editor */
$editor = TracyHelpers::editorUri($refl->getFileName(), $refl->getStartLine());
$editor = TracyHelpers::editorUri((string) $refl->getFileName(), (int) $refl->getStartLine());
if ($editor !== NULL) {
return sprintf(' defined at <a href="%s">%s</a>', htmlspecialchars($editor), $title);
}
Expand Down Expand Up @@ -425,7 +425,7 @@ private function renderCalls(array $calls)
{
static $runIcon;
if (empty($runIcon)) {
$runIcon = '<img width="18" height="18" src="data:image/png;base64,' . base64_encode(file_get_contents(__DIR__ . '/run.png')) . '" title="Event dispatch" />';
$runIcon = '<img width="18" height="18" src="data:image/png;base64,' . base64_encode((string) file_get_contents(__DIR__ . '/run.png')) . '" title="Event dispatch" />';
}

$s = '';
Expand Down
11 changes: 7 additions & 4 deletions src/Events/Event.php
Expand Up @@ -46,7 +46,7 @@ class Event implements \ArrayAccess, \IteratorAggregate, \Countable
private $namespace;

/**
* @var \Kdyby\Events\EventManager
* @var \Kdyby\Events\EventManager|null
*/
private $eventManager;

Expand All @@ -56,13 +56,13 @@ class Event implements \ArrayAccess, \IteratorAggregate, \Countable
private $argsClass;

/**
* @var \Kdyby\Events\Diagnostics\Panel
* @var \Kdyby\Events\Diagnostics\Panel|null
*/
private $panel;

/**
* @param string|array $name
* @param array $defaults
* @param array|\Traversable|null $defaults
* @param string $argsClass
*/
public function __construct($name, $defaults = [], $argsClass = NULL)
Expand Down Expand Up @@ -162,6 +162,7 @@ public function getListeners()

$name = $this->getName();
$evm = $this->eventManager;
assert($evm !== null);
$argsClass = $this->argsClass;
$globalDispatch = function () use ($name, $evm, $argsClass) {
if ($argsClass === NULL) {
Expand All @@ -171,6 +172,8 @@ public function getListeners()
$args = ClassTypeReflection::from($argsClass)->newInstanceArgs(func_get_args());
}

assert($args instanceof \Doctrine\Common\EventArgs);

$evm->dispatchEvent($name, $args);
};

Expand All @@ -193,7 +196,7 @@ public function __invoke()
}

/**
* @param string $name
* @param string|array $name
* @return array
*/
public static function parseName(&$name)
Expand Down
24 changes: 13 additions & 11 deletions src/Events/EventManager.php
Expand Up @@ -26,31 +26,31 @@ class EventManager extends \Doctrine\Common\EventManager
/**
* [Event => [Priority => [[Listener, method], Subscriber, Subscriber, ...]]]
*
* @var array[]
* @var array<string, array<int, callable[]>>
*/
private $listeners = [];

/**
* [Event => Subscriber|callable]
*
* @var \Doctrine\Common\EventSubscriber[][]|callable[][]
* @var array<\Doctrine\Common\EventSubscriber[]|callable[]>
*/
private $sorted = [];

/**
* [SubscriberHash => Subscriber]
*
* @var \Doctrine\Common\EventSubscriber[]
* @var array<string, \Doctrine\Common\EventSubscriber>
*/
private $subscribers = [];

/**
* @var \Kdyby\Events\Diagnostics\Panel
* @var \Kdyby\Events\Diagnostics\Panel|null
*/
private $panel;

/**
* @var \Kdyby\Events\IExceptionHandler
* @var \Kdyby\Events\IExceptionHandler|null
*/
private $exceptionHandler;

Expand Down Expand Up @@ -90,6 +90,8 @@ public function dispatchEvent($eventName, DoctrineEventArgs $eventArgs = NULL)
$listener = [$listener, $event];
}

assert(is_callable($listener));

if ($eventArgs instanceof EventArgsList) {
/** @var \Kdyby\Events\EventArgsList $eventArgs */
call_user_func_array($listener, $eventArgs->getArgs());
Expand All @@ -115,7 +117,7 @@ public function dispatchEvent($eventName, DoctrineEventArgs $eventArgs = NULL)
/**
* Gets the listeners of a specific event or all listeners.
*
* @param string $eventName
* @param string|null $eventName
* @return \Doctrine\Common\EventSubscriber[]|callable[]|\Doctrine\Common\EventSubscriber[][]|callable[][]
*/
public function getListeners($eventName = NULL)
Expand All @@ -140,7 +142,7 @@ public function getListeners($eventName = NULL)
/**
* Checks whether an event has any registered listeners.
*
* @param string $eventName
* @param string|null $eventName
* @return bool TRUE if the specified event has any listeners, FALSE otherwise.
*/
public function hasListeners($eventName)
Expand All @@ -166,7 +168,7 @@ public function addEventListener($events, $subscriber, $priority = 0)
$callback = !is_array($subscriber) ? [$subscriber, $event] : $subscriber;
if ($callback[0] instanceof CallableSubscriber) {
if (!is_callable($callback)) {
throw new \Kdyby\Events\InvalidListenerException(sprintf('Event listener "%s" is not callable.', $callback[0]));
throw new \Kdyby\Events\InvalidListenerException(sprintf('Event listener "%s" is not callable.', get_class($callback[0])));
}

} elseif (!method_exists($callback[0], $callback[1])) {
Expand Down Expand Up @@ -310,8 +312,8 @@ public function removeEventSubscriber(EventSubscriber $subscriber)
}

/**
* @param string|array $name
* @param array $defaults
* @param string $name
* @param array|\Traversable|null $defaults
* @param string $argsClass
* @param bool $globalDispatchFirst
* @return \Kdyby\Events\Event
Expand Down Expand Up @@ -360,7 +362,7 @@ private function sortListeners($eventName)
}

krsort($available); // [priority => [[listener, ...], ...]
$sorted = call_user_func_array('array_merge', $available);
$sorted = array_merge(...$available);

$this->sorted[$eventName] = array_map(function ($callable) use ($event) {
if ($callable instanceof EventSubscriber) {
Expand Down
4 changes: 2 additions & 2 deletions src/Events/LazyEventManager.php
Expand Up @@ -22,7 +22,7 @@ class LazyEventManager extends \Kdyby\Events\EventManager
{

/**
* @var array
* @var array<string, string[]>
*/
private $listenerIds;

Expand All @@ -32,7 +32,7 @@ class LazyEventManager extends \Kdyby\Events\EventManager
private $container;

/**
* @param array $listenerIds
* @param array<string, string[]> $listenerIds
* @param \Nette\DI\Container $container
*/
public function __construct(array $listenerIds, DIContainer $container)
Expand Down

0 comments on commit 8a6defb

Please sign in to comment.