1
0
Fork 0
forked from lino/radar-wp

Upgrading to 1.0.0-beta1 version of the API PHP implementation.

This commit is contained in:
ekes 2017-06-09 13:30:20 +01:00
parent 4424f09f06
commit 4ed51243b5
56 changed files with 1330 additions and 824 deletions

View file

@ -11,12 +11,12 @@
"repositories": [ "repositories": [
{ {
"type": "vcs", "type": "vcs",
"url": "https://github.com/events-radar/radar-api-php" "url": "https://0xacab.org/radar/radar-api-php"
} }
], ],
"minimum-stability": "alpha", "minimum-stability": "beta",
"prefer-stable": true, "prefer-stable": true,
"require": { "require": {
"events-radar/radar-api-php": "0.1.*@alpha" "events-radar/radar-api-php": "0.1.*@beta"
} }
} }

103
composer.lock generated
View file

@ -1,10 +1,11 @@
{ {
"_readme": [ "_readme": [
"This file locks the dependencies of your project to a known state", "This file locks the dependencies of your project to a known state",
"Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"hash": "80ea414a6d35f60a21a71bfd55c8ed5a", "hash": "1c78465da129002f122b2e8e75f6e1db",
"content-hash": "c8fa5cf6c9d380ba0857cf9b16b3103e",
"packages": [ "packages": [
{ {
"name": "doctrine/common", "name": "doctrine/common",
@ -78,17 +79,11 @@
}, },
{ {
"name": "events-radar/radar-api-php", "name": "events-radar/radar-api-php",
"version": "0.1.0-alpha3", "version": "0.1.0-beta1",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/events-radar/radar-api-php.git", "url": "https://0xacab.org/radar/radar-api-php",
"reference": "20e0b5c7d268f413fc1705bb81c46bce99b5ec1d" "reference": "e272465d34853ffb781b3ea99bad53f40e567f82"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/events-radar/radar-api-php/zipball/20e0b5c7d268f413fc1705bb81c46bce99b5ec1d",
"reference": "20e0b5c7d268f413fc1705bb81c46bce99b5ec1d",
"shasum": ""
}, },
"require": { "require": {
"doctrine/common": "2.3.0", "doctrine/common": "2.3.0",
@ -111,11 +106,7 @@
"GPL-2.0+" "GPL-2.0+"
], ],
"description": "Radar API connect", "description": "Radar API connect",
"support": { "time": "2017-04-27 15:31:59"
"source": "https://github.com/events-radar/radar-api-php/tree/0.1.0-alpha3",
"issues": "https://github.com/events-radar/radar-api-php/issues"
},
"time": "2015-02-24 20:52:50"
}, },
{ {
"name": "guzzle/cache", "name": "guzzle/cache",
@ -123,12 +114,12 @@
"target-dir": "Guzzle/Cache", "target-dir": "Guzzle/Cache",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/guzzle/cache.git", "url": "https://github.com/Guzzle3/cache.git",
"reference": "9d20d5afd4203f84893e809777ffa01e47bd4ea7" "reference": "9d20d5afd4203f84893e809777ffa01e47bd4ea7"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/guzzle/cache/zipball/9d20d5afd4203f84893e809777ffa01e47bd4ea7", "url": "https://api.github.com/repos/Guzzle3/cache/zipball/9d20d5afd4203f84893e809777ffa01e47bd4ea7",
"reference": "9d20d5afd4203f84893e809777ffa01e47bd4ea7", "reference": "9d20d5afd4203f84893e809777ffa01e47bd4ea7",
"shasum": "" "shasum": ""
}, },
@ -167,6 +158,7 @@
"doctrine", "doctrine",
"zf" "zf"
], ],
"abandoned": "guzzle/guzzle",
"time": "2014-01-08 21:24:51" "time": "2014-01-08 21:24:51"
}, },
{ {
@ -175,12 +167,12 @@
"target-dir": "Guzzle/Common", "target-dir": "Guzzle/Common",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/guzzle/common.git", "url": "https://github.com/Guzzle3/common.git",
"reference": "2e36af7cf2ce3ea1f2d7c2831843b883a8e7b7dc" "reference": "2e36af7cf2ce3ea1f2d7c2831843b883a8e7b7dc"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/guzzle/common/zipball/2e36af7cf2ce3ea1f2d7c2831843b883a8e7b7dc", "url": "https://api.github.com/repos/Guzzle3/common/zipball/2e36af7cf2ce3ea1f2d7c2831843b883a8e7b7dc",
"reference": "2e36af7cf2ce3ea1f2d7c2831843b883a8e7b7dc", "reference": "2e36af7cf2ce3ea1f2d7c2831843b883a8e7b7dc",
"shasum": "" "shasum": ""
}, },
@ -211,6 +203,7 @@
"event", "event",
"exception" "exception"
], ],
"abandoned": "guzzle/guzzle",
"time": "2014-08-11 04:32:36" "time": "2014-08-11 04:32:36"
}, },
{ {
@ -219,12 +212,12 @@
"target-dir": "Guzzle/Http", "target-dir": "Guzzle/Http",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/guzzle/http.git", "url": "https://github.com/Guzzle3/http.git",
"reference": "1e8dd1e2ba9dc42332396f39fbfab950b2301dc5" "reference": "1e8dd1e2ba9dc42332396f39fbfab950b2301dc5"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/guzzle/http/zipball/1e8dd1e2ba9dc42332396f39fbfab950b2301dc5", "url": "https://api.github.com/repos/Guzzle3/http/zipball/1e8dd1e2ba9dc42332396f39fbfab950b2301dc5",
"reference": "1e8dd1e2ba9dc42332396f39fbfab950b2301dc5", "reference": "1e8dd1e2ba9dc42332396f39fbfab950b2301dc5",
"shasum": "" "shasum": ""
}, },
@ -268,6 +261,7 @@
"http", "http",
"http client" "http client"
], ],
"abandoned": "guzzle/guzzle",
"time": "2014-08-11 04:32:36" "time": "2014-08-11 04:32:36"
}, },
{ {
@ -276,12 +270,12 @@
"target-dir": "Guzzle/Parser", "target-dir": "Guzzle/Parser",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/guzzle/parser.git", "url": "https://github.com/Guzzle3/parser.git",
"reference": "6874d171318a8e93eb6d224cf85e4678490b625c" "reference": "6874d171318a8e93eb6d224cf85e4678490b625c"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/guzzle/parser/zipball/6874d171318a8e93eb6d224cf85e4678490b625c", "url": "https://api.github.com/repos/Guzzle3/parser/zipball/6874d171318a8e93eb6d224cf85e4678490b625c",
"reference": "6874d171318a8e93eb6d224cf85e4678490b625c", "reference": "6874d171318a8e93eb6d224cf85e4678490b625c",
"shasum": "" "shasum": ""
}, },
@ -312,6 +306,7 @@
"message", "message",
"url" "url"
], ],
"abandoned": "guzzle/guzzle",
"time": "2014-02-05 18:29:46" "time": "2014-02-05 18:29:46"
}, },
{ {
@ -320,12 +315,12 @@
"target-dir": "Guzzle/Plugin/Cache", "target-dir": "Guzzle/Plugin/Cache",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/guzzle/plugin-cache.git", "url": "https://github.com/Guzzle3/plugin-cache.git",
"reference": "152bc4fa58e1578d01d501a97cbeee1c34edecb6" "reference": "152bc4fa58e1578d01d501a97cbeee1c34edecb6"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/guzzle/plugin-cache/zipball/152bc4fa58e1578d01d501a97cbeee1c34edecb6", "url": "https://api.github.com/repos/Guzzle3/plugin-cache/zipball/152bc4fa58e1578d01d501a97cbeee1c34edecb6",
"reference": "152bc4fa58e1578d01d501a97cbeee1c34edecb6", "reference": "152bc4fa58e1578d01d501a97cbeee1c34edecb6",
"shasum": "" "shasum": ""
}, },
@ -362,6 +357,7 @@
"Guzzle", "Guzzle",
"plugin" "plugin"
], ],
"abandoned": "guzzle/guzzle",
"time": "2014-02-05 10:00:42" "time": "2014-02-05 10:00:42"
}, },
{ {
@ -370,12 +366,12 @@
"target-dir": "Guzzle/Stream", "target-dir": "Guzzle/Stream",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/guzzle/stream.git", "url": "https://github.com/Guzzle3/stream.git",
"reference": "60c7fed02e98d2c518dae8f97874c8f4622100f0" "reference": "60c7fed02e98d2c518dae8f97874c8f4622100f0"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/guzzle/stream/zipball/60c7fed02e98d2c518dae8f97874c8f4622100f0", "url": "https://api.github.com/repos/Guzzle3/stream/zipball/60c7fed02e98d2c518dae8f97874c8f4622100f0",
"reference": "60c7fed02e98d2c518dae8f97874c8f4622100f0", "reference": "60c7fed02e98d2c518dae8f97874c8f4622100f0",
"shasum": "" "shasum": ""
}, },
@ -415,6 +411,7 @@
"component", "component",
"stream" "stream"
], ],
"abandoned": "guzzle/guzzle",
"time": "2014-05-01 21:36:02" "time": "2014-05-01 21:36:02"
}, },
{ {
@ -455,29 +452,30 @@
}, },
{ {
"name": "symfony/event-dispatcher", "name": "symfony/event-dispatcher",
"version": "v2.6.5", "version": "v3.3.2",
"target-dir": "Symfony/Component/EventDispatcher",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/EventDispatcher.git", "url": "https://github.com/symfony/event-dispatcher.git",
"reference": "70f7c8478739ad21e3deef0d977b38c77f1fb284" "reference": "4054a102470665451108f9b59305c79176ef98f0"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/EventDispatcher/zipball/70f7c8478739ad21e3deef0d977b38c77f1fb284", "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/4054a102470665451108f9b59305c79176ef98f0",
"reference": "70f7c8478739ad21e3deef0d977b38c77f1fb284", "reference": "4054a102470665451108f9b59305c79176ef98f0",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"php": ">=5.3.3" "php": ">=5.5.9"
},
"conflict": {
"symfony/dependency-injection": "<3.3"
}, },
"require-dev": { "require-dev": {
"psr/log": "~1.0", "psr/log": "~1.0",
"symfony/config": "~2.0,>=2.0.5", "symfony/config": "~2.8|~3.0",
"symfony/dependency-injection": "~2.6", "symfony/dependency-injection": "~3.3",
"symfony/expression-language": "~2.6", "symfony/expression-language": "~2.8|~3.0",
"symfony/phpunit-bridge": "~2.7", "symfony/stopwatch": "~2.8|~3.0"
"symfony/stopwatch": "~2.3"
}, },
"suggest": { "suggest": {
"symfony/dependency-injection": "", "symfony/dependency-injection": "",
@ -486,38 +484,41 @@
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-master": "2.6-dev" "dev-master": "3.3-dev"
} }
}, },
"autoload": { "autoload": {
"psr-0": { "psr-4": {
"Symfony\\Component\\EventDispatcher\\": "" "Symfony\\Component\\EventDispatcher\\": ""
} },
"exclude-from-classmap": [
"/Tests/"
]
}, },
"notification-url": "https://packagist.org/downloads/", "notification-url": "https://packagist.org/downloads/",
"license": [ "license": [
"MIT" "MIT"
], ],
"authors": [ "authors": [
{
"name": "Symfony Community",
"homepage": "http://symfony.com/contributors"
},
{ {
"name": "Fabien Potencier", "name": "Fabien Potencier",
"email": "fabien@symfony.com" "email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
} }
], ],
"description": "Symfony EventDispatcher Component", "description": "Symfony EventDispatcher Component",
"homepage": "http://symfony.com", "homepage": "https://symfony.com",
"time": "2015-03-13 17:37:22" "time": "2017-06-04 18:15:29"
} }
], ],
"packages-dev": [], "packages-dev": [],
"aliases": [], "aliases": [],
"minimum-stability": "alpha", "minimum-stability": "beta",
"stability-flags": { "stability-flags": {
"events-radar/radar-api-php": 15 "events-radar/radar-api-php": 10
}, },
"prefer-stable": true, "prefer-stable": true,
"prefer-lowest": false, "prefer-lowest": false,

View file

@ -24,7 +24,9 @@ function radar_retrieve_events($settings) {
$settings['fields'] = _radar_field_name_mapping($settings['fields']); $settings['fields'] = _radar_field_name_mapping($settings['fields']);
$filter = radar_filter($settings); $filter = radar_filter($settings);
$request = $client->prepareEventsRequest($filter, $settings['fields'], $settings['max_count']); $request = $client->prepareEventsRequest($filter, $settings['fields'], $settings['max_count']);
return $client->retrieve($request); $response = $client->retrieveResponse($request);
$events = $client->parseResponse($response);
return $events;
} }
function radar_retrieve_entities(array $entities) { function radar_retrieve_entities(array $entities) {
@ -111,6 +113,10 @@ function _radar_field_name_mapping($fields) {
function _radar_parse_items($type, $items, $fields, $subfields = array()) { function _radar_parse_items($type, $items, $fields, $subfields = array()) {
$content = array(); $content = array();
foreach ((array) $items as $item) { foreach ((array) $items as $item) {
if (!is_object($item)) {
error_log('_radar_parse_items called with empty item');
continue;
}
$current_content = array(); $current_content = array();
// Cycle through the fields in best order that we can. // Cycle through the fields in best order that we can.
foreach ($fields as $field_name) { foreach ($fields as $field_name) {
@ -131,7 +137,6 @@ function _radar_parse_items($type, $items, $fields, $subfields = array()) {
} }
$content[] = $current_content; $content[] = $current_content;
} }
return $content; return $content;
} }

View file

@ -13,9 +13,7 @@
namespace Composer\Autoload; namespace Composer\Autoload;
/** /**
* ClassLoader implements a PSR-0 class loader * ClassLoader implements a PSR-0, PSR-4 and classmap class loader.
*
* See https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md
* *
* $loader = new \Composer\Autoload\ClassLoader(); * $loader = new \Composer\Autoload\ClassLoader();
* *
@ -39,6 +37,8 @@ namespace Composer\Autoload;
* *
* @author Fabien Potencier <fabien@symfony.com> * @author Fabien Potencier <fabien@symfony.com>
* @author Jordi Boggiano <j.boggiano@seld.be> * @author Jordi Boggiano <j.boggiano@seld.be>
* @see http://www.php-fig.org/psr/psr-0/
* @see http://www.php-fig.org/psr/psr-4/
*/ */
class ClassLoader class ClassLoader
{ {
@ -147,7 +147,7 @@ class ClassLoader
* appending or prepending to the ones previously set for this namespace. * appending or prepending to the ones previously set for this namespace.
* *
* @param string $prefix The prefix/namespace, with trailing '\\' * @param string $prefix The prefix/namespace, with trailing '\\'
* @param array|string $paths The PSR-0 base directories * @param array|string $paths The PSR-4 base directories
* @param bool $prepend Whether to prepend the directories * @param bool $prepend Whether to prepend the directories
* *
* @throws \InvalidArgumentException * @throws \InvalidArgumentException

21
vendor/composer/LICENSE vendored Normal file
View file

@ -0,0 +1,21 @@
Copyright (c) 2016 Nils Adermann, Jordi Boggiano
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View file

@ -6,7 +6,6 @@ $vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir); $baseDir = dirname($vendorDir);
return array( return array(
'Symfony\\Component\\EventDispatcher\\' => array($vendorDir . '/symfony/event-dispatcher'),
'Guzzle\\Stream' => array($vendorDir . '/guzzle/stream'), 'Guzzle\\Stream' => array($vendorDir . '/guzzle/stream'),
'Guzzle\\Plugin\\Cache' => array($vendorDir . '/guzzle/plugin-cache'), 'Guzzle\\Plugin\\Cache' => array($vendorDir . '/guzzle/plugin-cache'),
'Guzzle\\Parser' => array($vendorDir . '/guzzle/parser'), 'Guzzle\\Parser' => array($vendorDir . '/guzzle/parser'),

View file

@ -6,5 +6,6 @@ $vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir); $baseDir = dirname($vendorDir);
return array( return array(
'Symfony\\Component\\EventDispatcher\\' => array($vendorDir . '/symfony/event-dispatcher'),
'Radar\\Connect\\' => array($vendorDir . '/events-radar/radar-api-php/src'), 'Radar\\Connect\\' => array($vendorDir . '/events-radar/radar-api-php/src'),
); );

View file

@ -23,19 +23,26 @@ class ComposerAutoloaderInit0602dde9fe6a3b6e770da50fa17cf0fd
self::$loader = $loader = new \Composer\Autoload\ClassLoader(); self::$loader = $loader = new \Composer\Autoload\ClassLoader();
spl_autoload_unregister(array('ComposerAutoloaderInit0602dde9fe6a3b6e770da50fa17cf0fd', 'loadClassLoader')); spl_autoload_unregister(array('ComposerAutoloaderInit0602dde9fe6a3b6e770da50fa17cf0fd', 'loadClassLoader'));
$map = require __DIR__ . '/autoload_namespaces.php'; $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION');
foreach ($map as $namespace => $path) { if ($useStaticLoader) {
$loader->set($namespace, $path); require_once __DIR__ . '/autoload_static.php';
}
$map = require __DIR__ . '/autoload_psr4.php'; call_user_func(\Composer\Autoload\ComposerStaticInit0602dde9fe6a3b6e770da50fa17cf0fd::getInitializer($loader));
foreach ($map as $namespace => $path) { } else {
$loader->setPsr4($namespace, $path); $map = require __DIR__ . '/autoload_namespaces.php';
} foreach ($map as $namespace => $path) {
$loader->set($namespace, $path);
}
$classMap = require __DIR__ . '/autoload_classmap.php'; $map = require __DIR__ . '/autoload_psr4.php';
if ($classMap) { foreach ($map as $namespace => $path) {
$loader->addClassMap($classMap); $loader->setPsr4($namespace, $path);
}
$classMap = require __DIR__ . '/autoload_classmap.php';
if ($classMap) {
$loader->addClassMap($classMap);
}
} }
$loader->register(true); $loader->register(true);
@ -43,8 +50,3 @@ class ComposerAutoloaderInit0602dde9fe6a3b6e770da50fa17cf0fd
return $loader; return $loader;
} }
} }
function composerRequire0602dde9fe6a3b6e770da50fa17cf0fd($file)
{
require $file;
}

82
vendor/composer/autoload_static.php vendored Normal file
View file

@ -0,0 +1,82 @@
<?php
// autoload_static.php @generated by Composer
namespace Composer\Autoload;
class ComposerStaticInit0602dde9fe6a3b6e770da50fa17cf0fd
{
public static $prefixLengthsPsr4 = array (
'S' =>
array (
'Symfony\\Component\\EventDispatcher\\' => 34,
),
'R' =>
array (
'Radar\\Connect\\' => 14,
),
);
public static $prefixDirsPsr4 = array (
'Symfony\\Component\\EventDispatcher\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/event-dispatcher',
),
'Radar\\Connect\\' =>
array (
0 => __DIR__ . '/..' . '/events-radar/radar-api-php/src',
),
);
public static $prefixesPsr0 = array (
'G' =>
array (
'Guzzle\\Stream' =>
array (
0 => __DIR__ . '/..' . '/guzzle/stream',
),
'Guzzle\\Plugin\\Cache' =>
array (
0 => __DIR__ . '/..' . '/guzzle/plugin-cache',
),
'Guzzle\\Parser' =>
array (
0 => __DIR__ . '/..' . '/guzzle/parser',
),
'Guzzle\\Http' =>
array (
0 => __DIR__ . '/..' . '/guzzle/http',
),
'Guzzle\\Common' =>
array (
0 => __DIR__ . '/..' . '/guzzle/common',
),
'Guzzle\\Cache' =>
array (
0 => __DIR__ . '/..' . '/guzzle/cache',
),
),
'D' =>
array (
'Doctrine\\Common' =>
array (
0 => __DIR__ . '/..' . '/doctrine/common/lib',
),
),
);
public static $classMap = array (
'geoPHP' => __DIR__ . '/..' . '/phayes/geophp/geoPHP.inc',
);
public static function getInitializer(ClassLoader $loader)
{
return \Closure::bind(function () use ($loader) {
$loader->prefixLengthsPsr4 = ComposerStaticInit0602dde9fe6a3b6e770da50fa17cf0fd::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticInit0602dde9fe6a3b6e770da50fa17cf0fd::$prefixDirsPsr4;
$loader->prefixesPsr0 = ComposerStaticInit0602dde9fe6a3b6e770da50fa17cf0fd::$prefixesPsr0;
$loader->classMap = ComposerStaticInit0602dde9fe6a3b6e770da50fa17cf0fd::$classMap;
}, null, ClassLoader::class);
}
}

View file

@ -116,12 +116,12 @@
"target-dir": "Guzzle/Common", "target-dir": "Guzzle/Common",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/guzzle/common.git", "url": "https://github.com/Guzzle3/common.git",
"reference": "2e36af7cf2ce3ea1f2d7c2831843b883a8e7b7dc" "reference": "2e36af7cf2ce3ea1f2d7c2831843b883a8e7b7dc"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/guzzle/common/zipball/2e36af7cf2ce3ea1f2d7c2831843b883a8e7b7dc", "url": "https://api.github.com/repos/Guzzle3/common/zipball/2e36af7cf2ce3ea1f2d7c2831843b883a8e7b7dc",
"reference": "2e36af7cf2ce3ea1f2d7c2831843b883a8e7b7dc", "reference": "2e36af7cf2ce3ea1f2d7c2831843b883a8e7b7dc",
"shasum": "" "shasum": ""
}, },
@ -153,7 +153,8 @@
"common", "common",
"event", "event",
"exception" "exception"
] ],
"abandoned": "guzzle/guzzle"
}, },
{ {
"name": "guzzle/cache", "name": "guzzle/cache",
@ -162,12 +163,12 @@
"target-dir": "Guzzle/Cache", "target-dir": "Guzzle/Cache",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/guzzle/cache.git", "url": "https://github.com/Guzzle3/cache.git",
"reference": "9d20d5afd4203f84893e809777ffa01e47bd4ea7" "reference": "9d20d5afd4203f84893e809777ffa01e47bd4ea7"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/guzzle/cache/zipball/9d20d5afd4203f84893e809777ffa01e47bd4ea7", "url": "https://api.github.com/repos/Guzzle3/cache/zipball/9d20d5afd4203f84893e809777ffa01e47bd4ea7",
"reference": "9d20d5afd4203f84893e809777ffa01e47bd4ea7", "reference": "9d20d5afd4203f84893e809777ffa01e47bd4ea7",
"shasum": "" "shasum": ""
}, },
@ -207,7 +208,8 @@
"cache", "cache",
"doctrine", "doctrine",
"zf" "zf"
] ],
"abandoned": "guzzle/guzzle"
}, },
{ {
"name": "guzzle/stream", "name": "guzzle/stream",
@ -216,12 +218,12 @@
"target-dir": "Guzzle/Stream", "target-dir": "Guzzle/Stream",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/guzzle/stream.git", "url": "https://github.com/Guzzle3/stream.git",
"reference": "60c7fed02e98d2c518dae8f97874c8f4622100f0" "reference": "60c7fed02e98d2c518dae8f97874c8f4622100f0"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/guzzle/stream/zipball/60c7fed02e98d2c518dae8f97874c8f4622100f0", "url": "https://api.github.com/repos/Guzzle3/stream/zipball/60c7fed02e98d2c518dae8f97874c8f4622100f0",
"reference": "60c7fed02e98d2c518dae8f97874c8f4622100f0", "reference": "60c7fed02e98d2c518dae8f97874c8f4622100f0",
"shasum": "" "shasum": ""
}, },
@ -262,7 +264,8 @@
"Guzzle", "Guzzle",
"component", "component",
"stream" "stream"
] ],
"abandoned": "guzzle/guzzle"
}, },
{ {
"name": "guzzle/parser", "name": "guzzle/parser",
@ -271,12 +274,12 @@
"target-dir": "Guzzle/Parser", "target-dir": "Guzzle/Parser",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/guzzle/parser.git", "url": "https://github.com/Guzzle3/parser.git",
"reference": "6874d171318a8e93eb6d224cf85e4678490b625c" "reference": "6874d171318a8e93eb6d224cf85e4678490b625c"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/guzzle/parser/zipball/6874d171318a8e93eb6d224cf85e4678490b625c", "url": "https://api.github.com/repos/Guzzle3/parser/zipball/6874d171318a8e93eb6d224cf85e4678490b625c",
"reference": "6874d171318a8e93eb6d224cf85e4678490b625c", "reference": "6874d171318a8e93eb6d224cf85e4678490b625c",
"shasum": "" "shasum": ""
}, },
@ -308,7 +311,8 @@
"http", "http",
"message", "message",
"url" "url"
] ],
"abandoned": "guzzle/guzzle"
}, },
{ {
"name": "guzzle/http", "name": "guzzle/http",
@ -317,12 +321,12 @@
"target-dir": "Guzzle/Http", "target-dir": "Guzzle/Http",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/guzzle/http.git", "url": "https://github.com/Guzzle3/http.git",
"reference": "1e8dd1e2ba9dc42332396f39fbfab950b2301dc5" "reference": "1e8dd1e2ba9dc42332396f39fbfab950b2301dc5"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/guzzle/http/zipball/1e8dd1e2ba9dc42332396f39fbfab950b2301dc5", "url": "https://api.github.com/repos/Guzzle3/http/zipball/1e8dd1e2ba9dc42332396f39fbfab950b2301dc5",
"reference": "1e8dd1e2ba9dc42332396f39fbfab950b2301dc5", "reference": "1e8dd1e2ba9dc42332396f39fbfab950b2301dc5",
"shasum": "" "shasum": ""
}, },
@ -367,7 +371,8 @@
"curl", "curl",
"http", "http",
"http client" "http client"
] ],
"abandoned": "guzzle/guzzle"
}, },
{ {
"name": "guzzle/plugin-cache", "name": "guzzle/plugin-cache",
@ -376,12 +381,12 @@
"target-dir": "Guzzle/Plugin/Cache", "target-dir": "Guzzle/Plugin/Cache",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/guzzle/plugin-cache.git", "url": "https://github.com/Guzzle3/plugin-cache.git",
"reference": "152bc4fa58e1578d01d501a97cbeee1c34edecb6" "reference": "152bc4fa58e1578d01d501a97cbeee1c34edecb6"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/guzzle/plugin-cache/zipball/152bc4fa58e1578d01d501a97cbeee1c34edecb6", "url": "https://api.github.com/repos/Guzzle3/plugin-cache/zipball/152bc4fa58e1578d01d501a97cbeee1c34edecb6",
"reference": "152bc4fa58e1578d01d501a97cbeee1c34edecb6", "reference": "152bc4fa58e1578d01d501a97cbeee1c34edecb6",
"shasum": "" "shasum": ""
}, },
@ -419,23 +424,83 @@
"keywords": [ "keywords": [
"Guzzle", "Guzzle",
"plugin" "plugin"
] ],
"abandoned": "guzzle/guzzle"
}, },
{ {
"name": "events-radar/radar-api-php", "name": "symfony/event-dispatcher",
"version": "0.1.0-alpha3", "version": "v3.3.2",
"version_normalized": "0.1.0.0-alpha3", "version_normalized": "3.3.2.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/events-radar/radar-api-php.git", "url": "https://github.com/symfony/event-dispatcher.git",
"reference": "20e0b5c7d268f413fc1705bb81c46bce99b5ec1d" "reference": "4054a102470665451108f9b59305c79176ef98f0"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/events-radar/radar-api-php/zipball/20e0b5c7d268f413fc1705bb81c46bce99b5ec1d", "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/4054a102470665451108f9b59305c79176ef98f0",
"reference": "20e0b5c7d268f413fc1705bb81c46bce99b5ec1d", "reference": "4054a102470665451108f9b59305c79176ef98f0",
"shasum": "" "shasum": ""
}, },
"require": {
"php": ">=5.5.9"
},
"conflict": {
"symfony/dependency-injection": "<3.3"
},
"require-dev": {
"psr/log": "~1.0",
"symfony/config": "~2.8|~3.0",
"symfony/dependency-injection": "~3.3",
"symfony/expression-language": "~2.8|~3.0",
"symfony/stopwatch": "~2.8|~3.0"
},
"suggest": {
"symfony/dependency-injection": "",
"symfony/http-kernel": ""
},
"time": "2017-06-04 18:15:29",
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "3.3-dev"
}
},
"installation-source": "dist",
"autoload": {
"psr-4": {
"Symfony\\Component\\EventDispatcher\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony EventDispatcher Component",
"homepage": "https://symfony.com"
},
{
"name": "events-radar/radar-api-php",
"version": "0.1.0-beta1",
"version_normalized": "0.1.0.0-beta1",
"source": {
"type": "git",
"url": "https://0xacab.org/radar/radar-api-php",
"reference": "e272465d34853ffb781b3ea99bad53f40e567f82"
},
"require": { "require": {
"doctrine/common": "2.3.0", "doctrine/common": "2.3.0",
"guzzle/cache": "3.9.2", "guzzle/cache": "3.9.2",
@ -447,9 +512,9 @@
"guzzle/guzzle": "3.9.2", "guzzle/guzzle": "3.9.2",
"phpunit/phpunit": "~4.5" "phpunit/phpunit": "~4.5"
}, },
"time": "2015-02-24 20:52:50", "time": "2017-04-27 15:31:59",
"type": "library", "type": "library",
"installation-source": "dist", "installation-source": "source",
"autoload": { "autoload": {
"psr-4": { "psr-4": {
"Radar\\Connect\\": "src" "Radar\\Connect\\": "src"
@ -458,71 +523,6 @@
"license": [ "license": [
"GPL-2.0+" "GPL-2.0+"
], ],
"description": "Radar API connect", "description": "Radar API connect"
"support": {
"source": "https://github.com/events-radar/radar-api-php/tree/0.1.0-alpha3",
"issues": "https://github.com/events-radar/radar-api-php/issues"
}
},
{
"name": "symfony/event-dispatcher",
"version": "v2.6.5",
"version_normalized": "2.6.5.0",
"target-dir": "Symfony/Component/EventDispatcher",
"source": {
"type": "git",
"url": "https://github.com/symfony/EventDispatcher.git",
"reference": "70f7c8478739ad21e3deef0d977b38c77f1fb284"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/EventDispatcher/zipball/70f7c8478739ad21e3deef0d977b38c77f1fb284",
"reference": "70f7c8478739ad21e3deef0d977b38c77f1fb284",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"require-dev": {
"psr/log": "~1.0",
"symfony/config": "~2.0,>=2.0.5",
"symfony/dependency-injection": "~2.6",
"symfony/expression-language": "~2.6",
"symfony/phpunit-bridge": "~2.7",
"symfony/stopwatch": "~2.3"
},
"suggest": {
"symfony/dependency-injection": "",
"symfony/http-kernel": ""
},
"time": "2015-03-13 17:37:22",
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.6-dev"
}
},
"installation-source": "dist",
"autoload": {
"psr-0": {
"Symfony\\Component\\EventDispatcher\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Symfony Community",
"homepage": "http://symfony.com/contributors"
},
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
}
],
"description": "Symfony EventDispatcher Component",
"homepage": "http://symfony.com"
} }
] ]

View file

@ -44,7 +44,7 @@ class Connect {
$this->apiUrl = $configuration['api_url']; $this->apiUrl = $configuration['api_url'];
} }
else { else {
$this->apiUrl = 'https://new-radar.squat.net/api/1.0/'; $this->apiUrl = 'https://radar.squat.net/api/1.0/';
} }
$this->debug = !empty($configuration['debug']); $this->debug = !empty($configuration['debug']);
} }

View file

@ -16,8 +16,17 @@ require('radar_client.php');
// Shared radar connect client. // Shared radar connect client.
$client = radar_client(); $client = radar_client();
// Basic cache for output. // Basic cache for output.
$cache = radar_cache(); $cache = radar_cache();
// If you want to empty the cache completely
//$cache->flushAll();
// If you want to remove one item like the stored HTML for evets.php
$cache->delete('events.php');
// Add a prefered language for requests. If none is set 'und' is used and
// content is returned in its original language, first language posted..
$client->setLanguage('de');
// Check to see if there is a copy in the cache. // Check to see if there is a copy in the cache.
if ($cache->contains('events.php') && $page = $cache->fetch('events.php')) { if ($cache->contains('events.php') && $page = $cache->fetch('events.php')) {
@ -25,15 +34,14 @@ if ($cache->contains('events.php') && $page = $cache->fetch('events.php')) {
print $page['html']; print $page['html'];
// If it's more than an hour old, get a new one. // If it's more than an hour old, get a new one.
if ($page['created'] + 60 * 60 < time()) { if ($page['created'] + 60 * 60 < time()) {
$events = radar_events_retrieve($client); $html = radar_events_page_html($client);
$html = radar_events_format($client, $events);
$cache->delete('events.php'); $cache->delete('events.php');
} }
} }
else { else {
// Generate the page and output it. // Generate the page and output it.
$events = radar_events_retrieve($client); $html = radar_events_page_html($client);
$html = radar_events_format($client, $events, true); print $html;
} }
if (!empty($html)) { if (!empty($html)) {
@ -42,6 +50,17 @@ if (!empty($html)) {
$cache->save('events.php', $page); $cache->save('events.php', $page);
} }
/**
* Make HTML page.
*/
function radar_events_page_html($client) {
$request = radar_prepare_events_request($client);
$response = $client->retrieveResponse($request);
$events = $client->parseResponse($response);
$metadata = $client->parseResponseMeta($response);
return radar_events_format($client, $events, $metadata);
}
/** /**
* Set a filter and retrieve events matching the filter. * Set a filter and retrieve events matching the filter.
* *
@ -51,14 +70,19 @@ if (!empty($html)) {
* @return Radar\Connect\Event[] * @return Radar\Connect\Event[]
* Array of radar connect events. * Array of radar connect events.
*/ */
function radar_events_retrieve(\Radar\Connect\Connect $client) { function radar_prepare_events_request(\Radar\Connect\Connect $client) {
$filter = new \Radar\Connect\Filter; $filter = new \Radar\Connect\Filter;
$filter->addCity('Berlin'); $filter->addCity('Berlin');
// Alternatives:- // Alternatives:-
//$filter->addCity('Amsterdam'); //$filter->addCity('Amsterdam');
//$filter->addDate(new DateTime('tomorrow')); //$filter->addDate(new DateTime('tomorrow'));
//$filter->addDay(); //$filter->addDay();
//$filter->addCategory('music');
//Some filters don't have explicit methods to set them so for tags...
//$filter->add('tag', 'Punk');
// See docs/classes/Radar.Connect.Filter.html for full list of methods. // See docs/classes/Radar.Connect.Filter.html for full list of methods.
// You can also see all the filter values and their counts in the metadata
// returned. See the examples at the top of radar_events_format().
// Get the request. // Get the request.
// arguments: // arguments:
@ -66,6 +90,9 @@ function radar_events_retrieve(\Radar\Connect\Connect $client) {
// $fields - array of field names to collect, empty for default // $fields - array of field names to collect, empty for default
// $limit - maximum number of events to return. // $limit - maximum number of events to return.
$request = $client->prepareEventsRequest($filter, array(), 50); $request = $client->prepareEventsRequest($filter, array(), 50);
return $request;
// Execute request. // Execute request.
return $client->retrieve($request); return $client->retrieve($request);
} }
@ -77,17 +104,43 @@ function radar_events_retrieve(\Radar\Connect\Connect $client) {
* The connect client. * The connect client.
* @param \Radar\Connect\Event[] $events * @param \Radar\Connect\Event[] $events
* Array of Event entities, for example response to events request. * Array of Event entities, for example response to events request.
* @param bool $output * @param array $metadata
* If HTML output should also be sent to stdout. * Array of counts and facets.
* *
* @return string * @return string
* The HTML output. * The HTML output.
*/ */
function radar_events_format(\Radar\Connect\Connect $client, array $events, $output = FALSE) { function radar_events_format(\Radar\Connect\Connect $client, array $events, array $metadata) {
ob_start(); ob_start();
ob_implicit_flush(TRUE); ob_implicit_flush(TRUE);
$html = ''; $html = '';
// Metadata includes the result count.
print "<p>There are {$metadata['count']} results for the query</p>\n";
// Retrieve some facets. Summaries of filters you can use
// in further narrowed queries, and their result counts.
print '<h1>Forthcoming days</h1><ul>';
foreach ($metadata['facets']['date'] as $facet) {
print '<li>' . date('Y-m-d', $facet['formatted']) . " has {$facet['count']} events</li>\n";
}
print "</ul>\n";
// For other factets it's even more convenient. The 'filter' value is also the value you set to filter the query.
print "<h1>Categories</h1><ul>\n";
foreach ($metadata['facets']['category'] as $facet) {
print "<li>{$facet['formatted']} has {$facet['count']} events you could add a filter for them with the \$filter->addCategory('{$facet['filter']}');</li>\n";
}
print "<ul>\n";
// There's no direct method to set the tag filter. They can all be set using the key that is in this array - here tag.
// So in the example above instead of $filter->addCategory you could have equally $filter->add('category', $facet['filter']);
print "<h1>Tags</h1><ul>\n";
foreach ($metadata['facets']['tag'] as $facet) {
print "<li>{$facet['formatted']} has {$facet['count']} events you could add a filter for them with the \$filter->add('tag', '{$facet['filter']}');</li>\n";
}
print "<ul>\n";
foreach ($events as $event) { foreach ($events as $event) {
// Title and date. // Title and date.
print '<h1>' . $event->getTitle() . '</h1>'; print '<h1>' . $event->getTitle() . '</h1>';
@ -98,20 +151,24 @@ function radar_events_format(\Radar\Connect\Connect $client, array $events, $out
// The groups are references. If we want to get details about // The groups are references. If we want to get details about
// them we actually load the group itself as well. // them we actually load the group itself as well.
$groups = $client->retrieveEntityMultiple($event->getGroups()); $groups = $event->getGroups();
$groups = $client->retrieveEntityMultiple($groups);
foreach ($groups as $group) { foreach ($groups as $group) {
print '<p><strong>' . $group->getTitle() . '</strong></p>'; print '<p><strong>' . $group->getTitle() . '</strong></p>';
print '<p>' . var_dump($group->getLink(), true) . ' ' . var_dump($group->getLinkRaw(), true) . '</strong></p>';
} }
// Just as with the groups the locations are just the references. // Just as with the groups the locations are just the references.
// So we load them here. // So we load them here.
$locations = $client->retrieveEntityMultiple($event->getLocations()); $locations = $event->getLocations();
$locations = $client->retrieveEntityMultiple($locations);
foreach ($locations as $location) { foreach ($locations as $location) {
print '<p>' . $location->getAddress() . '</p>'; print '<p>' . $location->getAddress() . '</p>';
} }
// Yep and the categories, and topics. // Yep and the categories, and topics.
$categories = $client->retrieveEntityMultiple($event->getCategories()); $categories = $event->getCategories();
$categories = $client->retrieveEntityMultiple($categories);
$category_names = array(); $category_names = array();
foreach ($categories as $category) { foreach ($categories as $category) {
$category_names[] = $category->getTitle(); $category_names[] = $category->getTitle();
@ -120,7 +177,8 @@ function radar_events_format(\Radar\Connect\Connect $client, array $events, $out
print '<p>Categories: ' . implode(', ', $category_names); print '<p>Categories: ' . implode(', ', $category_names);
} }
$topics = $client->retrieveEntityMultiple($event->getTopics()); $topics = $event->getTopics();
$topics = $client->retrieveEntityMultiple($topics);
$topic_names = array(); $topic_names = array();
foreach ($topics as $topic) { foreach ($topics as $topic) {
$topic_names[] = $topic->getTitle(); $topic_names[] = $topic->getTitle();
@ -131,12 +189,7 @@ function radar_events_format(\Radar\Connect\Connect $client, array $events, $out
// Outputs the HTML if requested. // Outputs the HTML if requested.
$html .= ob_get_contents(); $html .= ob_get_contents();
if ($output) { ob_clean();
ob_flush();
}
else {
ob_clean();
}
} }
ob_end_clean(); ob_end_clean();

View file

@ -5,7 +5,7 @@
* Helper functions to create radar connect classes. * Helper functions to create radar connect classes.
*/ */
require 'vendor/autoload.php'; require __DIR__ . '/vendor/autoload.php';
use Radar\Connect\Connect; use Radar\Connect\Connect;
use Radar\Connect\Filter; use Radar\Connect\Filter;

View file

@ -20,15 +20,15 @@ class Cache {
$this->cache = $cache; $this->cache = $cache;
} }
public function contains(Entity $entity) { public function contains($uri) {
return $this->cache->contains($entity->apiUri()); return $this->cache->contains($uri);
} }
public function fetch(Entity $entity) { public function fetch($uri) {
return $this->cache->fetch($entity->apiUri()); return $this->cache->fetch($uri);
} }
public function save(Entity $entity) { public function save($uri, Entity $entity) {
// TODO Make configurable. // TODO Make configurable.
$ttl = array( $ttl = array(
'group' => 60 * 60, 'group' => 60 * 60,
@ -36,11 +36,12 @@ class Cache {
'event' => 60 * 5, 'event' => 60 * 5,
'location' => 60 * 60 * 24, 'location' => 60 * 60 * 24,
'taxonomy_term' => 60 * 60 * 24 * 30, 'taxonomy_term' => 60 * 60 * 24 * 30,
'file' => 60 * 60,
); );
return $this->cache->save($entity->apiUri(), $entity, $ttl[$entity->type]); return $this->cache->save($uri, $entity, $ttl[$entity->type]);
} }
public function delete(Entity $entity) { public function delete($uri) {
return $this->cache->delete($entity->apiUri()); return $this->cache->delete($uri);
} }
} }

View file

@ -29,6 +29,11 @@ class Connect {
*/ */
public $debug; public $debug;
/**
* @var string ISO 639-1 code.
*/
public $language;
/** /**
* Constructor. * Constructor.
* *
@ -44,7 +49,7 @@ class Connect {
$this->apiUrl = $configuration['api_url']; $this->apiUrl = $configuration['api_url'];
} }
else { else {
$this->apiUrl = 'https://radar.squat.net/api/1.0/'; $this->apiUrl = 'https://radar.squat.net/api/1.1/';
} }
$this->debug = !empty($configuration['debug']); $this->debug = !empty($configuration['debug']);
} }
@ -65,6 +70,36 @@ class Connect {
$this->cache = $cache; $this->cache = $cache;
} }
/**
* Set, default, language for queries.
*/
public function setLanguage($langcode) {
$this->language = $langcode;
}
/**
* Retrieve language code.
*/
public function getLanguage() {
if (!empty($this->language)) {
return $this->language;
}
else {
return 'und';
}
}
/**
* Compute url for cache storage.
*
* Language is for the language requested, not necessarily the language of
* the entity, as different language requests can return different
* langage entities (not necessarity corresponding) based on fallback.
*/
public function cacheUri($entity) {
return $entity->apiUri() . '?language=' . $this->getLanguage();
}
/** /**
* Retrieve all fields for single entity. * Retrieve all fields for single entity.
* *
@ -80,13 +115,18 @@ class Connect {
* The loaded entity. * The loaded entity.
*/ */
public function retrieveEntity(Entity $entity) { public function retrieveEntity(Entity $entity) {
if (!empty($this->cache) && $this->cache->contains($entity)) { $cacheUri = $this->cacheUri($entity);
return $this->cache->fetch($entity); if (!empty($this->cache) && $this->cache->contains($cacheUri)) {
return $this->cache->fetch($cacheUri);
} }
$request = $this->client->get($entity->apiUri()); $request = $this->client->get($entity->apiUri());
$entity = $this->parseResponse($response); if ($this->getLanguage() != 'und') {
$query = $request->getQuery();
$query->set('language', $this->getLanguage());
}
$entity = $this->retrieve($request);
if (!empty($this->cache)) { if (!empty($this->cache)) {
$this->cache->save($entity); $this->cache->save($cacheUri, $entity);
} }
return $entity; return $entity;
} }
@ -106,8 +146,8 @@ class Connect {
$cached = array(); $cached = array();
if (!empty($this->cache)) { if (!empty($this->cache)) {
foreach($entities as $key => $entity) { foreach($entities as $key => $entity) {
if ($this->cache->contains($entity)) { if ($this->cache->contains($this->cacheUri($entity))) {
$cached[] = $this->cache->fetch($entity); $cached[] = $this->cache->fetch($this->cacheUri($entity));
unset($entities[$key]); unset($entities[$key]);
} }
} }
@ -115,13 +155,18 @@ class Connect {
$requests = array(); $requests = array();
foreach ($entities as $entity) { foreach ($entities as $entity) {
$requests[] = $this->client->get($entity->apiUri()); $request = $this->client->get($entity->apiUri());
if ($this->getLanguage() != 'und') {
$query = $request->getQuery();
$query->set('language', $this->getLanguage());
}
$requests[] = $request;
} }
$retrieved = $this->retrieveMultiple($requests); $retrieved = $this->retrieveMultiple($requests);
if (!empty($this->cache)) { if (!empty($this->cache)) {
foreach ($retrieved as $entity) { foreach ($retrieved as $entity) {
$this->cache->save($entity); $this->cache->save($this->cacheUri($entity), $entity);
} }
} }
@ -136,8 +181,6 @@ class Connect {
} }
/** /**
* Prepare a request to retrieve events. * Prepare a request to retrieve events.
* *
@ -148,14 +191,27 @@ class Connect {
* A list of fields to load. Optional, default is most available fields. * A list of fields to load. Optional, default is most available fields.
* @param int $limit * @param int $limit
* How many events to return. * How many events to return.
* @param array $sort
* Optional array ['field_name' => 'order'], where order is ASC or DESC.
* @param array $keys
* Values for full text search ['search', 'words'] for OR ['search words'] for AND.
* *
* @return \Guzzle\Http\Message\Request * @return \Guzzle\Http\Message\Request
* Request object to retrieve. * Request object to retrieve.
*/ */
public function prepareEventsRequest(Filter $filter, $fields = array(), $limit = 500) { public function prepareEventsRequest(Filter $filter, $fields = array(), $limit = 500, $sort = array(), $keys = array()) {
$request = $this->client->get($this->apiUrl . 'search/events.json'); $request = $this->client->get($this->apiUrl . 'search/events.json');
$query = $request->getQuery(); $query = $request->getQuery();
$query->set('facets', $filter->getQuery()); $query->set('facets', $filter->getQuery());
if ($this->getLanguage() != 'und') {
$query->set('language', $this->getLanguage());
}
if (!empty($sort)) {
$query->set('sort', $sort);
}
if (!empty($keys)) {
$query->set('keys', $keys);
}
if (! empty($fields)) { if (! empty($fields)) {
// Always retrieve type. // Always retrieve type.
$fields = array_merge($fields, array('type')); $fields = array_merge($fields, array('type'));
@ -165,11 +221,13 @@ class Connect {
'title', 'title',
'type', 'type',
'uuid', 'uuid',
'nid',
'og_group_ref', 'og_group_ref',
'date_time', 'date_time',
'offline', 'offline',
'category', 'category',
'topic', 'topic',
'price_category',
'price', 'price',
'link', 'link',
'phone', 'phone',
@ -196,27 +254,42 @@ class Connect {
* A list of fields to load. Optional, default is most available fields. * A list of fields to load. Optional, default is most available fields.
* @param int $limit * @param int $limit
* How many groups to return. * How many groups to return.
* @param array $sort
* Optional array ['field_name' => 'order'], where order is ASC or DESC.
* @param array $keys
* Values for full text search ['search', 'words'] for OR ['search words'] for AND.
* *
* @return \Guzzle\Http\Message\Request * @return \Guzzle\Http\Message\Request
* Request object to retrieve. * Request object to retrieve.
*/ */
public function prepareGroupsRequest(Filter $filter, $fields = array(), $limit = 500) { public function prepareGroupsRequest(Filter $filter, $fields = array(), $limit = 500, $sort = array(), $keys = array()) {
$request = $this->client->get($this->apiUrl . 'search/groups.json'); $request = $this->client->get($this->apiUrl . 'search/groups.json');
$query = $request->getQuery(); $query = $request->getQuery();
if ($this->getLanguage() != 'und') {
$query->set('language', $this->getLanguage());
}
$query->set('facets', $filter->getQuery()); $query->set('facets', $filter->getQuery());
if (!empty($sort)) {
$query->set('sort', $sort);
}
if (!empty($keys)) {
$query->set('keys', $keys);
}
if (! empty($fields)) { if (! empty($fields)) {
$fields += array('type'); $fields += array('type');
} }
else { else {
$fields = array( $fields = array(
'uuid',
'title', 'title',
'type', 'type',
'nid',
'category', 'category',
'offline', 'offline',
'topic', 'topic',
'body', 'body',
'email', 'email',
'weblink', 'link',
'offline', 'offline',
'opening_times', 'opening_times',
'phone', 'phone',
@ -228,6 +301,22 @@ class Connect {
return $request; return $request;
} }
/**
* Retrieve API response from a prepared request.
*
* @param \Guzzle\Http\Message\RequestInterface $request
*
* @return \Guzzle\Http\Message\Response
*/
public function retrieveResponse(RequestInterface $request) {
$response = $this->client->send($request);
if ($this->debug) {
var_export($response->getHeaders());
var_export($response->getBody());
}
return $response;
}
/** /**
* Retrieve entities from a prepared request. * Retrieve entities from a prepared request.
* *
@ -241,7 +330,9 @@ class Connect {
var_export($response->getHeaders()); var_export($response->getHeaders());
var_export($response->getBody()); var_export($response->getBody());
} }
return $this->parseResponse($response); $items = $this->parseResponse($response);
$entity = reset($items);
return $entity;
} }
/** /**
@ -277,24 +368,52 @@ class Connect {
* *
* TODO this doesn't need to be in here. * TODO this doesn't need to be in here.
*/ */
protected function parseResponse(Response $response) { public function parseResponse(Response $response) {
$items = array(); $items = array();
$content = $response->json(); $content = $response->json();
if (isset($content['type'])) { if (isset($content['type'])) {
// Single item response.
$class = __NAMESPACE__ . '\\Entity\\' . Entity::className($content['type']); $class = __NAMESPACE__ . '\\Entity\\' . Entity::className($content['type']);
$content['apiBase'] = $this->apiUrl; $content['apiBase'] = $this->apiUrl;
$items[] = new $class($content); $items[] = new $class($content);
} }
else { else {
foreach ($content as $key => $item) { $result = empty($content['result']) ? array() : $content['result'];
$class = __NAMESPACE__ . '\\Entity\\' . Entity::className($item['type']); $first_content_item = current($result);
$item['apiBase'] = $this->apiUrl; if (!empty($first_content_item)) {
$items[] = new $class($item); // List response, that is non-empty.
foreach ($result as $key => $item) {
$class = __NAMESPACE__ . '\\Entity\\' . Entity::className($item['type']);
$item['apiBase'] = $this->apiUrl;
$items[] = new $class($item);
}
}
else {
// Empty response.
$items = array();
} }
} }
return $items; return $items;
} }
/**
* Parse response metadata.
*/
public function parseResponseMeta(Response $response) {
$output = [];
$content = $response->json();
if (isset($content['count'])) {
$output['count'] = $content['count'];
}
if (isset($content['facets'])) {
$output['facets'] = $content['facets'];
}
return $output;
}
} }

View file

@ -27,6 +27,7 @@ abstract class Entity {
'category' => 'TaxonomyTerm', 'category' => 'TaxonomyTerm',
'topic' => 'TaxonomyTerm', 'topic' => 'TaxonomyTerm',
'price' => 'TaxonomyTerm', 'price' => 'TaxonomyTerm',
'file' => 'RadarFile',
); );
return $classes[$type]; return $classes[$type];
} }

View file

@ -87,11 +87,21 @@ class Event extends Node {
/** /**
* Return image field data. * Return image field data.
*
* TODO API isn't putting the data into the output.
*/ */
public function getImageRaw() { public function getImageRaw() {
return $this->image; return $this->image['file'];
}
/**
* Return image file object.
*
* @return RadarFile|NULL
*/
public function getImage() {
if (!empty($this->image['file'])) {
return new RadarFile($this->image['file']);
}
return NULL;
} }
public function getPriceCategoryRaw() { public function getPriceCategoryRaw() {

View file

@ -17,17 +17,42 @@ class Group extends Node {
} }
/** /**
* TODO not appearing in the API output. * Logo raw data.
*/ */
public function getGroupLogoRaw() { public function getGroupLogoRaw() {
return $this->group_logo; return $this->group_logo;
} }
/** /**
* TODO not appearing in the API output. * Logo file object.
*
* @return File|NULL
*/
public function getGroupLogo() {
if (!empty($this->group_logo)) {
return new RadarFile($this->group_logo);
}
return NULL;
}
/**
* Raw image entity array.
*/ */
public function getImageRaw() { public function getImageRaw() {
return $this->image->file; return $this->image;
}
/**
* Return image entity object.
*
* @return RadarFile|NULL
*/
public function getImage() {
if (!empty($this->image->file)) {
return new RadarFile($this->image);
}
return NULL;
} }
/** /**

View file

@ -65,7 +65,11 @@ class Node extends Entity {
} }
public function getCategoriesRaw() { public function getCategoriesRaw() {
return $this->category; $categories = array();
foreach ($this->category as $category) {
$categories[$category['id']] = $category;
}
return $category;
} }
/** /**
@ -77,14 +81,18 @@ class Node extends Entity {
$categories = array(); $categories = array();
if (is_array($this->category)) { if (is_array($this->category)) {
foreach ($this->category as $category) { foreach ($this->category as $category) {
$categories[] = new TaxonomyTerm($category); $categories[$category['id']] = new TaxonomyTerm($category);
} }
} }
return $categories; return $categories;
} }
public function getTopicsRaw() { public function getTopicsRaw() {
return $this->topics; $topics = array();
foreach ($this->topic as $topic) {
$topics[$topic['id']] = $topic;
}
return $topics;
} }
/** /**
@ -96,7 +104,7 @@ class Node extends Entity {
$topics = array(); $topics = array();
if (is_array($this->topic)) { if (is_array($this->topic)) {
foreach ($this->topic as $topic) { foreach ($this->topic as $topic) {
$topics[] = new TaxonomyTerm($topic); $topics[$topic['id']] = new TaxonomyTerm($topic);
} }
} }
return $topics; return $topics;

View file

@ -0,0 +1,67 @@
<?php
namespace Radar\Connect\Entity;
class RadarFile extends Entity {
public $title;
public $mime;
public $size;
public $url;
function __construct($data = array()) {
$this->set($data);
$this->type = 'file';
}
public function set($data) {
$data = (array) $data;
parent::set($data);
if (isset($data['fid'])) {
$this->drupalId = $data['fid'];
}
}
public function apiUri() {
if (isset($this->apiUri)) {
return $this->apiUri;
}
elseif (isset($this->uuid)) {
return $this->apiBase . 'file/' . $this->uuid;
}
throw new Exception();
}
/**
* Title is usually filename.
*/
public function getTitle() {
return $this->title;
}
/**
* Mimetype, eg image/jpeg
*/
public function getImageRaw() {
return $this->mime;
}
/**
* URL to the file itself.
*
* @return string
*/
public function getUrl() {
return $this->url;
}
/**
* Size, in bytes.
*
* @return int
*/
public function getSize() {
return $this->size;
}
}

View file

@ -9,6 +9,18 @@ class Filter {
*/ */
private $query; private $query;
/**
* Add arbitary filter, knowing key.
*
* If you add something that doesn't work it usually just returns no results.
*
* @param string key
* @param string value
*/
public function add($key, $value) {
$this->query[$key][] = $value;
}
/** /**
* Filter by group. * Filter by group.
* *
@ -43,7 +55,7 @@ class Filter {
/** /**
* Filter by year. * Filter by year.
* *
* @param string $year. * @param string $year
* Optional: year in YYYY format. Default current year. * Optional: year in YYYY format. Default current year.
*/ */
public function addYear($year = 'now') { public function addYear($year = 'now') {
@ -128,4 +140,5 @@ class Filter {
public function getQuery() { public function getQuery() {
return $this->query; return $this->query;
} }
} }

View file

@ -17,22 +17,24 @@ class EventTest extends EntityTestCase {
$this->assertEquals($event->getInternalId(), '9171'); $this->assertEquals($event->getInternalId(), '9171');
$this->assertEquals($event->getInternalVid(), '9680'); $this->assertEquals($event->getInternalVid(), '9680');
// Node level fields // Node level fields
$this->assertEquals($event->apiUri(), 'https://new-radar.squat.net/api/1.0/node/69300100-b104-4c37-b651-48351543e8a6'); $this->assertEquals($event->apiUri(), 'https://radar.squat.net/api/1.1/node/69300100-b104-4c37-b651-48351543e8a6');
$body_text = "<p>This is a handy event that site devs are using.</p>\n"; $body_text = "<p>This is a handy event that site devs are using.</p>\n";
$this->assertEquals($event->getBody(), $body_text); $this->assertEquals($event->getBody(), $body_text);
$this->assertEquals($event->getBodyRaw(), array('value' => $body_text, 'summary' => '', 'format' => 'rich_text_editor')); $this->assertEquals($event->getBodyRaw(), array('value' => $body_text, 'summary' => '', 'format' => 'rich_text_editor'));
$this->assertEquals($event->getUrlView(),'https://new-radar.squat.net/en/event/amsterdam/joes-garage/2014-02-24/test-event'); $this->assertEquals($event->getUrlView(),'https://radar.squat.net/en/event/amsterdam/joes-garage/2014-02-24/test-event');
$this->assertEquals($event->getUrlEdit(),'https://new-radar.squat.net/en/node/9171/edit'); $this->assertEquals($event->getUrlEdit(),'https://radar.squat.net/en/node/9171/edit');
$this->assertEquals($event->getStatus(), TRUE); $this->assertEquals($event->getStatus(), TRUE);
$this->assertEquals($event->getCreated()->getTimestamp(),'1424807163'); $this->assertEquals($event->getCreated()->getTimestamp(),'1424807163');
$this->assertEquals($event->getUpdated()->getTimestamp(),'1424807163'); $this->assertEquals($event->getUpdated()->getTimestamp(),'1424807163');
// Node level references // Node level references
$categories = $event->getCategories(); $categories = $event->getCategories();
$this->assertTrue($categories[0] instanceof \Radar\Connect\Entity\TaxonomyTerm); $category = reset($categories);
$this->assertEquals($categories[0]->apiUri(),'https://new-radar.squat.net/api/1.0/taxonomy_term/e85a688d-03ac-4008-a3cb-1adb7e8f718a'); $this->assertTrue($category instanceof \Radar\Connect\Entity\TaxonomyTerm);
$this->assertEquals($category->apiUri(),'https://radar.squat.net/api/1.1/taxonomy_term/e85a688d-03ac-4008-a3cb-1adb7e8f718a');
$topics = $event->getTopics(); $topics = $event->getTopics();
$this->assertTrue($topics[0] instanceof \Radar\Connect\Entity\TaxonomyTerm); $topic = reset($topics);
$this->assertEquals($topics[0]->apiUri(), 'https://new-radar.squat.net/api/1.0/taxonomy_term/6c73cff2-9dc9-41db-a79e-f54bf4c010f7'); $this->assertTrue($topic instanceof \Radar\Connect\Entity\TaxonomyTerm);
$this->assertEquals($topic->apiUri(), 'https://radar.squat.net/api/1.1/taxonomy_term/6c73cff2-9dc9-41db-a79e-f54bf4c010f7');
// Simple fields. // Simple fields.
$this->assertTrue($event instanceof Event); $this->assertTrue($event instanceof Event);
$this->assertEquals($event->getTitle(), 'Test event'); $this->assertEquals($event->getTitle(), 'Test event');
@ -45,11 +47,11 @@ class EventTest extends EntityTestCase {
// Entity references. // Entity references.
$price = $event->getPriceCategory(); $price = $event->getPriceCategory();
$this->assertTrue($price[0] instanceof \Radar\Connect\Entity\TaxonomyTerm); $this->assertTrue($price[0] instanceof \Radar\Connect\Entity\TaxonomyTerm);
$this->assertEquals($price[0]->apiUri(), 'https://new-radar.squat.net/api/1.0/taxonomy_term/9d943d0c-e2bf-408e-9110-4bfb044f60c0'); $this->assertEquals($price[0]->apiUri(), 'https://radar.squat.net/api/1.1/taxonomy_term/9d943d0c-e2bf-408e-9110-4bfb044f60c0');
$this->assertEquals($price[1]->apiUri(), 'https://new-radar.squat.net/api/1.0/taxonomy_term/6f4101f4-cd9b-49f2-91a3-203d2b47a3ed'); $this->assertEquals($price[1]->apiUri(), 'https://radar.squat.net/api/1.1/taxonomy_term/6f4101f4-cd9b-49f2-91a3-203d2b47a3ed');
$groups = $event->getGroups(); $groups = $event->getGroups();
$this->assertTrue($groups[0] instanceof \Radar\Connect\Entity\Group); $this->assertTrue($groups[0] instanceof \Radar\Connect\Entity\Group);
$this->assertEquals($groups[0]->apiUri(), 'https://new-radar.squat.net/api/1.0/node/0df4bcd7-54b4-4559-a960-60b5042d3d48'); $this->assertEquals($groups[0]->apiUri(), 'https://radar.squat.net/api/1.1/node/0df4bcd7-54b4-4559-a960-60b5042d3d48');
$raw_dates = $event->getDatesRaw(); $raw_dates = $event->getDatesRaw();
$this->assertEquals($raw_dates[0]['value'], '1393271100'); $this->assertEquals($raw_dates[0]['value'], '1393271100');
$this->assertEquals($raw_dates[0]['time_end'], '2014-02-24T21:00:00+01:00'); $this->assertEquals($raw_dates[0]['time_end'], '2014-02-24T21:00:00+01:00');
@ -59,6 +61,6 @@ class EventTest extends EntityTestCase {
$this->assertEquals($dates[0]['end']->getTimezone()->getName(), '+01:00'); $this->assertEquals($dates[0]['end']->getTimezone()->getName(), '+01:00');
$locations = $event->getLocations(); $locations = $event->getLocations();
$this->assertTrue($locations[0] instanceof \Radar\Connect\Entity\Location); $this->assertTrue($locations[0] instanceof \Radar\Connect\Entity\Location);
$this->assertEquals($locations[0]->apiUri(), 'https://new-radar.squat.net/api/1.0/location/3c58abc1-e095-4db5-996d-2a064cebb2d3'); $this->assertEquals($locations[0]->apiUri(), 'https://radar.squat.net/api/1.1/location/3c58abc1-e095-4db5-996d-2a064cebb2d3');
} }
} }

View file

@ -17,23 +17,25 @@ class GroupTest extends EntityTestCase {
$this->assertEquals($group->getInternalId(), '41'); $this->assertEquals($group->getInternalId(), '41');
$this->assertEquals($group->getInternalVid(), '8935'); $this->assertEquals($group->getInternalVid(), '8935');
// Node level fields // Node level fields
$this->assertEquals($group->apiUri(), 'https://new-radar.squat.net/api/1.0/node/0df4bcd7-54b4-4559-a960-60b5042d3d48'); $this->assertEquals($group->apiUri(), 'https://radar.squat.net/api/1.1/node/0df4bcd7-54b4-4559-a960-60b5042d3d48');
$body_text = "<p>Joe's Garage is een ontmoetingsplek voor al dan niet krakers uit de transvaalbuurt en omstreken.</p>\n"; $body_text = "<p>Joe's Garage is een ontmoetingsplek voor al dan niet krakers uit de transvaalbuurt en omstreken.</p>\n";
$this->assertEquals($group->getBody(), $body_text); $this->assertEquals($group->getBody(), $body_text);
$this->assertEquals($group->getBodyRaw(), array('value' => $body_text, 'summary' => '', 'format' => 'rich_text_editor')); $this->assertEquals($group->getBodyRaw(), array('value' => $body_text, 'summary' => '', 'format' => 'rich_text_editor'));
$this->assertEquals($group->getUrlView(),'https://new-radar.squat.net/nl/amsterdam/joes-garage?language=nl'); $this->assertEquals($group->getUrlView(),'https://radar.squat.net/nl/amsterdam/joes-garage?language=nl');
$this->assertEquals($group->getUrlEdit(),'https://new-radar.squat.net/nl/node/41/edit?language=nl'); $this->assertEquals($group->getUrlEdit(),'https://radar.squat.net/nl/node/41/edit?language=nl');
$this->assertEquals($group->getStatus(), TRUE); $this->assertEquals($group->getStatus(), TRUE);
$this->assertEquals($group->getCreated()->getTimestamp(),'1409775185'); $this->assertEquals($group->getCreated()->getTimestamp(),'1409775185');
$this->assertEquals($group->getUpdated()->getTimestamp(),'1424352703'); $this->assertEquals($group->getUpdated()->getTimestamp(),'1424352703');
// Node level references // Node level references
$categories = $group->getCategories(); $categories = $group->getCategories();
$this->assertEquals(count($categories), 6); $this->assertEquals(count($categories), 6);
$this->assertTrue($categories[0] instanceof \Radar\Connect\Entity\TaxonomyTerm); $category = reset($categories);
$this->assertEquals($categories[0]->apiUri(),'https://new-radar.squat.net/api/1.0/taxonomy_term/e97f372b-29bc-460b-bff6-35d2462411ff?language=nl'); $this->assertTrue($category instanceof \Radar\Connect\Entity\TaxonomyTerm);
$this->assertEquals($category->apiUri(),'https://radar.squat.net/api/1.1/taxonomy_term/e97f372b-29bc-460b-bff6-35d2462411ff?language=nl');
$topics = $group->getTopics(); $topics = $group->getTopics();
$this->assertTrue($topics[0] instanceof \Radar\Connect\Entity\TaxonomyTerm); $topic = reset($topics);
$this->assertEquals($topics[0]->apiUri(), 'https://new-radar.squat.net/api/1.0/taxonomy_term/82f00d0a-03df-40ec-a06d-67b875675858?language=nl'); $this->assertTrue($topic instanceof \Radar\Connect\Entity\TaxonomyTerm);
$this->assertEquals($topic->apiUri(), 'https://radar.squat.net/api/1.1/taxonomy_term/82f00d0a-03df-40ec-a06d-67b875675858?language=nl');
// Simple fields. // Simple fields.
$this->assertTrue($group instanceof Group); $this->assertTrue($group instanceof Group);
$this->assertEquals($group->getTitle(), 'Joe\'s Garage'); $this->assertEquals($group->getTitle(), 'Joe\'s Garage');
@ -49,6 +51,6 @@ class GroupTest extends EntityTestCase {
// Entity references. // Entity references.
$locations = $group->getLocations(); $locations = $group->getLocations();
$this->assertTrue($locations[0] instanceof \Radar\Connect\Entity\Location); $this->assertTrue($locations[0] instanceof \Radar\Connect\Entity\Location);
$this->assertEquals($locations[0]->apiUri(), 'https://new-radar.squat.net/api/1.0/location/3c58abc1-e095-4db5-996d-2a064cebb2d3?language=nl'); $this->assertEquals($locations[0]->apiUri(), 'https://radar.squat.net/api/1.1/location/3c58abc1-e095-4db5-996d-2a064cebb2d3?language=nl');
} }
} }

View file

@ -18,12 +18,12 @@ class ListingsGroupTest extends EntityTestCase {
$this->assertEquals($group->getInternalVid(), '8976'); $this->assertEquals($group->getInternalVid(), '8976');
$this->assertEquals($group->getLanguage(), 'de'); $this->assertEquals($group->getLanguage(), 'de');
// Node level fields // Node level fields
$this->assertEquals($group->apiUri(), 'https://new-radar.squat.net/api/1.0/node/9e43dac6-e1da-4f60-8428-de9f32ac9eb0'); $this->assertEquals($group->apiUri(), 'https://radar.squat.net/api/1.1/node/9e43dac6-e1da-4f60-8428-de9f32ac9eb0');
$body_text = "<p>Berliner Terminkalender für linke Subkultur und Politik</p>\n"; $body_text = "<p>Berliner Terminkalender für linke Subkultur und Politik</p>\n";
$this->assertEquals($group->getBody(), $body_text); $this->assertEquals($group->getBody(), $body_text);
$this->assertEquals($group->getBodyRaw(), array('value' => $body_text, 'summary' => '', 'format' => 'rich_text_editor')); $this->assertEquals($group->getBodyRaw(), array('value' => $body_text, 'summary' => '', 'format' => 'rich_text_editor'));
$this->assertEquals($group->getUrlView(),'https://new-radar.squat.net/en/node/1599'); $this->assertEquals($group->getUrlView(),'https://radar.squat.net/en/node/1599');
$this->assertEquals($group->getUrlEdit(),'https://new-radar.squat.net/en/node/1599/edit'); $this->assertEquals($group->getUrlEdit(),'https://radar.squat.net/en/node/1599/edit');
$this->assertEquals($group->getStatus(), TRUE); $this->assertEquals($group->getStatus(), TRUE);
$this->assertEquals($group->getCreated()->getTimestamp(),'1415355772'); $this->assertEquals($group->getCreated()->getTimestamp(),'1415355772');
$this->assertEquals($group->getUpdated()->getTimestamp(),'1424428820'); $this->assertEquals($group->getUpdated()->getTimestamp(),'1424428820');
@ -46,6 +46,6 @@ class ListingsGroupTest extends EntityTestCase {
$this->assertEquals(count($locations), 0); $this->assertEquals(count($locations), 0);
$listed_groups = $group->getGroupsListed(); $listed_groups = $group->getGroupsListed();
$this->assertEquals(count($listed_groups), 76); $this->assertEquals(count($listed_groups), 76);
$this->assertEquals($listed_groups[0]->apiUri(), 'https://new-radar.squat.net/api/1.0/node/da296694-ae72-47a9-9073-e450143b9c58'); $this->assertEquals($listed_groups[0]->apiUri(), 'https://radar.squat.net/api/1.1/node/da296694-ae72-47a9-9073-e450143b9c58');
} }
} }

View file

@ -14,7 +14,7 @@ class TaxonomyTermTest extends EntityTestCase {
$this->assertTrue($term instanceof TaxonomyTerm); $this->assertTrue($term instanceof TaxonomyTerm);
$this->assertEquals($term->getTitle(), 'action/protest/camp'); $this->assertEquals($term->getTitle(), 'action/protest/camp');
$this->assertEquals($term->apiUri(), 'https://new-radar.squat.net/api/1.0/taxonomy_term/e85a688d-03ac-4008-a3cb-1adb7e8f718a'); $this->assertEquals($term->apiUri(), 'https://radar.squat.net/api/1.1/taxonomy_term/e85a688d-03ac-4008-a3cb-1adb7e8f718a');
$this->assertEquals($term->getUuid(), 'e85a688d-03ac-4008-a3cb-1adb7e8f718a'); $this->assertEquals($term->getUuid(), 'e85a688d-03ac-4008-a3cb-1adb7e8f718a');
$this->assertEquals($term->getVuuid(), null); $this->assertEquals($term->getVuuid(), null);
$this->assertEquals($term->getInternalId(), 7); $this->assertEquals($term->getInternalId(), 7);

View file

@ -12,4 +12,4 @@ Content-Length: 2613
Content-Type: application/json Content-Type: application/json
Strict-Transport-Security: max-age=15768000;includeSubDomains Strict-Transport-Security: max-age=15768000;includeSubDomains
{"body":{"value":"<p>This is a handy event that site devs are using.</p>\n","summary":"","format":"rich_text_editor"},"category":[{"uri":"https://new-radar.squat.net/api/1.0/taxonomy_term/e85a688d-03ac-4008-a3cb-1adb7e8f718a","id":"e85a688d-03ac-4008-a3cb-1adb7e8f718a","resource":"taxonomy_term"},{"uri":"https://new-radar.squat.net/api/1.0/taxonomy_term/2a56c4d7-eb98-4f96-9ac6-d383a1af5ce8","id":"2a56c4d7-eb98-4f96-9ac6-d383a1af5ce8","resource":"taxonomy_term"}],"group_content_access":"0","og_group_ref":[{"uri":"https://new-radar.squat.net/api/1.0/node/0df4bcd7-54b4-4559-a960-60b5042d3d48","id":"0df4bcd7-54b4-4559-a960-60b5042d3d48","resource":"node"}],"og_group_request":[],"date_time":[{"value":"1393271100","value2":"1393272000","duration":900,"time_start":"2014-02-24T20:45:00+01:00","time_end":"2014-02-24T21:00:00+01:00","rrule":null}],"image":[],"price":"Suggested donation \u20ac3","email":"joe@squat.net","link":[{"url":"http://www.joesgarage.nl/","attributes":[]}],"offline":[{"uri":"https://new-radar.squat.net/api/1.0/location/3c58abc1-e095-4db5-996d-2a064cebb2d3","id":"3c58abc1-e095-4db5-996d-2a064cebb2d3","resource":"location"}],"phone":"01-12345","topic":[{"uri":"https://new-radar.squat.net/api/1.0/taxonomy_term/6c73cff2-9dc9-41db-a79e-f54bf4c010f7","id":"6c73cff2-9dc9-41db-a79e-f54bf4c010f7","resource":"taxonomy_term"}],"title_field":"Test event","price_category":[{"uri":"https://new-radar.squat.net/api/1.0/taxonomy_term/9d943d0c-e2bf-408e-9110-4bfb044f60c0","id":"9d943d0c-e2bf-408e-9110-4bfb044f60c0","resource":"taxonomy_term"},{"uri":"https://new-radar.squat.net/api/1.0/taxonomy_term/6f4101f4-cd9b-49f2-91a3-203d2b47a3ed","id":"6f4101f4-cd9b-49f2-91a3-203d2b47a3ed","resource":"taxonomy_term"}],"og_membership":[],"og_membership__1":[],"og_membership__2":[],"og_membership__3":[],"og_group_ref__og_membership":[],"og_group_ref__og_membership__1":[],"og_group_ref__og_membership__2":[],"og_group_ref__og_membership__3":[],"og_group_request__og_membership":[],"og_group_request__og_membership__1":[],"og_group_request__og_membership__2":[],"og_group_request__og_membership__3":[],"nid":"9171","vid":"9680","is_new":false,"type":"event","title":"Test event","language":"en","url":"https://new-radar.squat.net/en/event/amsterdam/joes-garage/2014-02-24/test-event","edit_url":"https://new-radar.squat.net/en/node/9171/edit","status":"1","promote":"0","sticky":"0","created":"1424807163","changed":"1424807163","feed_nid":null,"flag_abuse_node_user":[],"flag_abuse_whitelist_node_user":[],"uuid":"69300100-b104-4c37-b651-48351543e8a6","vuuid":"a66a7c7d-5ed4-487e-92b8-ee876b91e2d6"} {"body":{"value":"<p>This is a handy event that site devs are using.</p>\n","summary":"","format":"rich_text_editor"},"category":[{"uri":"https://radar.squat.net/api/1.1/taxonomy_term/e85a688d-03ac-4008-a3cb-1adb7e8f718a","id":"e85a688d-03ac-4008-a3cb-1adb7e8f718a","resource":"taxonomy_term"},{"uri":"https://radar.squat.net/api/1.1/taxonomy_term/2a56c4d7-eb98-4f96-9ac6-d383a1af5ce8","id":"2a56c4d7-eb98-4f96-9ac6-d383a1af5ce8","resource":"taxonomy_term"}],"group_content_access":"0","og_group_ref":[{"uri":"https://radar.squat.net/api/1.1/node/0df4bcd7-54b4-4559-a960-60b5042d3d48","id":"0df4bcd7-54b4-4559-a960-60b5042d3d48","resource":"node"}],"og_group_request":[],"date_time":[{"value":"1393271100","value2":"1393272000","duration":900,"time_start":"2014-02-24T20:45:00+01:00","time_end":"2014-02-24T21:00:00+01:00","rrule":null}],"image":[],"price":"Suggested donation \u20ac3","email":"joe@squat.net","link":[{"url":"http://www.joesgarage.nl/","attributes":[]}],"offline":[{"uri":"https://radar.squat.net/api/1.1/location/3c58abc1-e095-4db5-996d-2a064cebb2d3","id":"3c58abc1-e095-4db5-996d-2a064cebb2d3","resource":"location"}],"phone":"01-12345","topic":[{"uri":"https://radar.squat.net/api/1.1/taxonomy_term/6c73cff2-9dc9-41db-a79e-f54bf4c010f7","id":"6c73cff2-9dc9-41db-a79e-f54bf4c010f7","resource":"taxonomy_term"}],"title_field":"Test event","price_category":[{"uri":"https://radar.squat.net/api/1.1/taxonomy_term/9d943d0c-e2bf-408e-9110-4bfb044f60c0","id":"9d943d0c-e2bf-408e-9110-4bfb044f60c0","resource":"taxonomy_term"},{"uri":"https://radar.squat.net/api/1.1/taxonomy_term/6f4101f4-cd9b-49f2-91a3-203d2b47a3ed","id":"6f4101f4-cd9b-49f2-91a3-203d2b47a3ed","resource":"taxonomy_term"}],"og_membership":[],"og_membership__1":[],"og_membership__2":[],"og_membership__3":[],"og_group_ref__og_membership":[],"og_group_ref__og_membership__1":[],"og_group_ref__og_membership__2":[],"og_group_ref__og_membership__3":[],"og_group_request__og_membership":[],"og_group_request__og_membership__1":[],"og_group_request__og_membership__2":[],"og_group_request__og_membership__3":[],"nid":"9171","vid":"9680","is_new":false,"type":"event","title":"Test event","language":"en","url":"https://radar.squat.net/en/event/amsterdam/joes-garage/2014-02-24/test-event","edit_url":"https://radar.squat.net/en/node/9171/edit","status":"1","promote":"0","sticky":"0","created":"1424807163","changed":"1424807163","feed_nid":null,"flag_abuse_node_user":[],"flag_abuse_whitelist_node_user":[],"uuid":"69300100-b104-4c37-b651-48351543e8a6","vuuid":"a66a7c7d-5ed4-487e-92b8-ee876b91e2d6"}

View file

@ -12,4 +12,4 @@ Content-Length: 2872
Content-Type: application/json Content-Type: application/json
Strict-Transport-Security: max-age=15768000;includeSubDomains Strict-Transport-Security: max-age=15768000;includeSubDomains
{"body":{"value":"<p>Joe's Garage is een ontmoetingsplek voor al dan niet krakers uit de transvaalbuurt en omstreken.</p>\n","summary":"","format":"rich_text_editor"},"category":[{"uri":"https://new-radar.squat.net/api/1.0/taxonomy_term/e97f372b-29bc-460b-bff6-35d2462411ff?language=nl","id":"e97f372b-29bc-460b-bff6-35d2462411ff","resource":"taxonomy_term"},{"uri":"https://new-radar.squat.net/api/1.0/taxonomy_term/2a56c4d7-eb98-4f96-9ac6-d383a1af5ce8?language=nl","id":"2a56c4d7-eb98-4f96-9ac6-d383a1af5ce8","resource":"taxonomy_term"},{"uri":"https://new-radar.squat.net/api/1.0/taxonomy_term/68197b93-2ece-4b0f-9a76-d9e99bda2603?language=nl","id":"68197b93-2ece-4b0f-9a76-d9e99bda2603","resource":"taxonomy_term"},{"uri":"https://new-radar.squat.net/api/1.0/taxonomy_term/8e846372-fa86-4cb2-87d1-f24da784ec6b?language=nl","id":"8e846372-fa86-4cb2-87d1-f24da784ec6b","resource":"taxonomy_term"},{"uri":"https://new-radar.squat.net/api/1.0/taxonomy_term/0b9e8d1f-d51d-4d32-b984-2dba1099e0fa?language=nl","id":"0b9e8d1f-d51d-4d32-b984-2dba1099e0fa","resource":"taxonomy_term"},{"uri":"https://new-radar.squat.net/api/1.0/taxonomy_term/20a888f9-54c1-4767-8af1-40de3d1d2636?language=nl","id":"20a888f9-54c1-4767-8af1-40de3d1d2636","resource":"taxonomy_term"}],"group_group":true,"group_logo":[],"image":[],"email":"joe@squat.net","link":[{"url":"http://www.joesgarage.nl/","attributes":[]}],"offline":[{"uri":"https://new-radar.squat.net/api/1.0/location/3c58abc1-e095-4db5-996d-2a064cebb2d3?language=nl","id":"3c58abc1-e095-4db5-996d-2a064cebb2d3","resource":"location"}],"opening_times":{"value":"<p>Maandag: 19u <strong>Volkseten Vegazulu</strong></p>\n<p>Dinsdag: 11u/15u <strong>Kraakspreekuur, (daarna is er een borrel)</strong></p>\n<p>Dinsdag: 20u/21u30 <strong>Kraakspreekuur Oost</strong></p>\n<p>Woensdag: 15u/18u <strong>Lonely Collective Day Cafe</strong></p>\n<p>Donderdag: 19u <strong>Volkseten Vegazulu</strong></p>\n<p>Zaterdag: 14u/18u <strong>Weggeefwinkel</strong></p>\n<p>Zondag: 20u <strong>Filmavonden/Infoavonden</strong></p>\n","format":"rich_text_editor"},"phone":null,"topic":[{"uri":"https://new-radar.squat.net/api/1.0/taxonomy_term/82f00d0a-03df-40ec-a06d-67b875675858?language=nl","id":"82f00d0a-03df-40ec-a06d-67b875675858","resource":"taxonomy_term"}],"notifications":["joe@squat.net"],"type":"group","members":[],"members__1":[],"members__2":[],"members__3":[],"nid":"41","vid":"8935","is_new":false,"title":"Joe's Garage","language":"en","url":"https://new-radar.squat.net/nl/amsterdam/joes-garage?language=nl","edit_url":"https://new-radar.squat.net/nl/node/41/edit?language=nl","status":"1","promote":"0","sticky":"0","created":"1409775185","changed":"1424352703","feed_nid":null,"flag_abuse_node_user":[],"flag_abuse_whitelist_node_user":[],"uuid":"0df4bcd7-54b4-4559-a960-60b5042d3d48","vuuid":"c6df91b9-58bd-4a5f-a52e-64ec18f267f0"} {"body":{"value":"<p>Joe's Garage is een ontmoetingsplek voor al dan niet krakers uit de transvaalbuurt en omstreken.</p>\n","summary":"","format":"rich_text_editor"},"category":[{"uri":"https://radar.squat.net/api/1.1/taxonomy_term/e97f372b-29bc-460b-bff6-35d2462411ff?language=nl","id":"e97f372b-29bc-460b-bff6-35d2462411ff","resource":"taxonomy_term"},{"uri":"https://radar.squat.net/api/1.1/taxonomy_term/2a56c4d7-eb98-4f96-9ac6-d383a1af5ce8?language=nl","id":"2a56c4d7-eb98-4f96-9ac6-d383a1af5ce8","resource":"taxonomy_term"},{"uri":"https://radar.squat.net/api/1.1/taxonomy_term/68197b93-2ece-4b0f-9a76-d9e99bda2603?language=nl","id":"68197b93-2ece-4b0f-9a76-d9e99bda2603","resource":"taxonomy_term"},{"uri":"https://radar.squat.net/api/1.1/taxonomy_term/8e846372-fa86-4cb2-87d1-f24da784ec6b?language=nl","id":"8e846372-fa86-4cb2-87d1-f24da784ec6b","resource":"taxonomy_term"},{"uri":"https://radar.squat.net/api/1.1/taxonomy_term/0b9e8d1f-d51d-4d32-b984-2dba1099e0fa?language=nl","id":"0b9e8d1f-d51d-4d32-b984-2dba1099e0fa","resource":"taxonomy_term"},{"uri":"https://radar.squat.net/api/1.1/taxonomy_term/20a888f9-54c1-4767-8af1-40de3d1d2636?language=nl","id":"20a888f9-54c1-4767-8af1-40de3d1d2636","resource":"taxonomy_term"}],"group_group":true,"group_logo":[],"image":[],"email":"joe@squat.net","link":[{"url":"http://www.joesgarage.nl/","attributes":[]}],"offline":[{"uri":"https://radar.squat.net/api/1.1/location/3c58abc1-e095-4db5-996d-2a064cebb2d3?language=nl","id":"3c58abc1-e095-4db5-996d-2a064cebb2d3","resource":"location"}],"opening_times":{"value":"<p>Maandag: 19u <strong>Volkseten Vegazulu</strong></p>\n<p>Dinsdag: 11u/15u <strong>Kraakspreekuur, (daarna is er een borrel)</strong></p>\n<p>Dinsdag: 20u/21u30 <strong>Kraakspreekuur Oost</strong></p>\n<p>Woensdag: 15u/18u <strong>Lonely Collective Day Cafe</strong></p>\n<p>Donderdag: 19u <strong>Volkseten Vegazulu</strong></p>\n<p>Zaterdag: 14u/18u <strong>Weggeefwinkel</strong></p>\n<p>Zondag: 20u <strong>Filmavonden/Infoavonden</strong></p>\n","format":"rich_text_editor"},"phone":null,"topic":[{"uri":"https://radar.squat.net/api/1.1/taxonomy_term/82f00d0a-03df-40ec-a06d-67b875675858?language=nl","id":"82f00d0a-03df-40ec-a06d-67b875675858","resource":"taxonomy_term"}],"notifications":["joe@squat.net"],"type":"group","members":[],"members__1":[],"members__2":[],"members__3":[],"nid":"41","vid":"8935","is_new":false,"title":"Joe's Garage","language":"en","url":"https://radar.squat.net/nl/amsterdam/joes-garage?language=nl","edit_url":"https://radar.squat.net/nl/node/41/edit?language=nl","status":"1","promote":"0","sticky":"0","created":"1409775185","changed":"1424352703","feed_nid":null,"flag_abuse_node_user":[],"flag_abuse_whitelist_node_user":[],"uuid":"0df4bcd7-54b4-4559-a960-60b5042d3d48","vuuid":"c6df91b9-58bd-4a5f-a52e-64ec18f267f0"}

File diff suppressed because one or more lines are too long

View file

@ -12,4 +12,4 @@ Content-Length: 360
Content-Type: application/json Content-Type: application/json
Strict-Transport-Security: max-age=15768000;includeSubDomains Strict-Transport-Security: max-age=15768000;includeSubDomains
{"tid":"7","name":"action/protest/camp","description":"","weight":"0","node_count":10,"url":"https://new-radar.squat.net/en/category/action-protest-camp","parent":[],"parents_all":[{"uri":"https://new-radar.squat.net/api/1.0/taxonomy_term/7","id":"7","resource":"taxonomy_term"}],"feed_nid":null,"type":"category","uuid":"e85a688d-03ac-4008-a3cb-1adb7e8f718a"} {"tid":"7","name":"action/protest/camp","description":"","weight":"0","node_count":10,"url":"https://radar.squat.net/en/category/action-protest-camp","parent":[],"parents_all":[{"uri":"https://radar.squat.net/api/1.1/taxonomy_term/7","id":"7","resource":"taxonomy_term"}],"feed_nid":null,"type":"category","uuid":"e85a688d-03ac-4008-a3cb-1adb7e8f718a"}

View file

@ -1,6 +1,20 @@
CHANGELOG CHANGELOG
========= =========
3.3.0
-----
* The ContainerAwareEventDispatcher class has been deprecated. Use EventDispatcher with closure factories instead.
3.0.0
-----
* The method `getListenerPriority($eventName, $listener)` has been added to the
`EventDispatcherInterface`.
* The methods `Event::setDispatcher()`, `Event::getDispatcher()`, `Event::setName()`
and `Event::getName()` have been removed.
The event dispatcher and the event name are passed to the listener call.
2.5.0 2.5.0
----- -----

View file

@ -20,6 +20,8 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
* @author Fabien Potencier <fabien@symfony.com> * @author Fabien Potencier <fabien@symfony.com>
* @author Bernhard Schussek <bschussek@gmail.com> * @author Bernhard Schussek <bschussek@gmail.com>
* @author Jordan Alliot <jordan.alliot@gmail.com> * @author Jordan Alliot <jordan.alliot@gmail.com>
*
* @deprecated since 3.3, to be removed in 4.0. Use EventDispatcher with closure factories instead.
*/ */
class ContainerAwareEventDispatcher extends EventDispatcher class ContainerAwareEventDispatcher extends EventDispatcher
{ {
@ -52,6 +54,14 @@ class ContainerAwareEventDispatcher extends EventDispatcher
public function __construct(ContainerInterface $container) public function __construct(ContainerInterface $container)
{ {
$this->container = $container; $this->container = $container;
$class = get_class($this);
if ($this instanceof \PHPUnit_Framework_MockObject_MockObject || $this instanceof \Prophecy\Doubler\DoubleInterface) {
$class = get_parent_class($class);
}
if (__CLASS__ !== $class) {
@trigger_error(sprintf('The %s class is deprecated since version 3.3 and will be removed in 4.0. Use EventDispatcher with closure factories instead.', __CLASS__), E_USER_DEPRECATED);
}
} }
/** /**
@ -68,6 +78,8 @@ class ContainerAwareEventDispatcher extends EventDispatcher
*/ */
public function addListenerService($eventName, $callback, $priority = 0) public function addListenerService($eventName, $callback, $priority = 0)
{ {
@trigger_error(sprintf('The %s class is deprecated since version 3.3 and will be removed in 4.0. Use EventDispatcher with closure factories instead.', __CLASS__), E_USER_DEPRECATED);
if (!is_array($callback) || 2 !== count($callback)) { if (!is_array($callback) || 2 !== count($callback)) {
throw new \InvalidArgumentException('Expected an array("service", "method") argument'); throw new \InvalidArgumentException('Expected an array("service", "method") argument');
} }
@ -80,8 +92,7 @@ class ContainerAwareEventDispatcher extends EventDispatcher
$this->lazyLoad($eventName); $this->lazyLoad($eventName);
if (isset($this->listenerIds[$eventName])) { if (isset($this->listenerIds[$eventName])) {
foreach ($this->listenerIds[$eventName] as $i => $args) { foreach ($this->listenerIds[$eventName] as $i => list($serviceId, $method, $priority)) {
list($serviceId, $method, $priority) = $args;
$key = $serviceId.'.'.$method; $key = $serviceId.'.'.$method;
if (isset($this->listeners[$eventName][$key]) && $listener === array($this->listeners[$eventName][$key], $method)) { if (isset($this->listeners[$eventName][$key]) && $listener === array($this->listeners[$eventName][$key], $method)) {
unset($this->listeners[$eventName][$key]); unset($this->listeners[$eventName][$key]);
@ -100,12 +111,12 @@ class ContainerAwareEventDispatcher extends EventDispatcher
} }
/** /**
* @see EventDispatcherInterface::hasListeners() * {@inheritdoc}
*/ */
public function hasListeners($eventName = null) public function hasListeners($eventName = null)
{ {
if (null === $eventName) { if (null === $eventName) {
return (bool) count($this->listenerIds) || (bool) count($this->listeners); return $this->listenerIds || $this->listeners || parent::hasListeners();
} }
if (isset($this->listenerIds[$eventName])) { if (isset($this->listenerIds[$eventName])) {
@ -116,12 +127,12 @@ class ContainerAwareEventDispatcher extends EventDispatcher
} }
/** /**
* @see EventDispatcherInterface::getListeners() * {@inheritdoc}
*/ */
public function getListeners($eventName = null) public function getListeners($eventName = null)
{ {
if (null === $eventName) { if (null === $eventName) {
foreach (array_keys($this->listenerIds) as $serviceEventName) { foreach ($this->listenerIds as $serviceEventName => $args) {
$this->lazyLoad($serviceEventName); $this->lazyLoad($serviceEventName);
} }
} else { } else {
@ -131,6 +142,16 @@ class ContainerAwareEventDispatcher extends EventDispatcher
return parent::getListeners($eventName); return parent::getListeners($eventName);
} }
/**
* {@inheritdoc}
*/
public function getListenerPriority($eventName, $listener)
{
$this->lazyLoad($eventName);
return parent::getListenerPriority($eventName, $listener);
}
/** /**
* Adds a service as event subscriber. * Adds a service as event subscriber.
* *
@ -139,6 +160,8 @@ class ContainerAwareEventDispatcher extends EventDispatcher
*/ */
public function addSubscriberService($serviceId, $class) public function addSubscriberService($serviceId, $class)
{ {
@trigger_error(sprintf('The %s class is deprecated since version 3.3 and will be removed in 4.0. Use EventDispatcher with closure factories instead.', __CLASS__), E_USER_DEPRECATED);
foreach ($class::getSubscribedEvents() as $eventName => $params) { foreach ($class::getSubscribedEvents() as $eventName => $params) {
if (is_string($params)) { if (is_string($params)) {
$this->listenerIds[$eventName][] = array($serviceId, $params, 0); $this->listenerIds[$eventName][] = array($serviceId, $params, 0);
@ -152,23 +175,10 @@ class ContainerAwareEventDispatcher extends EventDispatcher
} }
} }
/**
* {@inheritdoc}
*
* Lazily loads listeners for this event from the dependency injection
* container.
*
* @throws \InvalidArgumentException if the service is not defined
*/
public function dispatch($eventName, Event $event = null)
{
$this->lazyLoad($eventName);
return parent::dispatch($eventName, $event);
}
public function getContainer() public function getContainer()
{ {
@trigger_error('The '.__METHOD__.'() method is deprecated since version 3.3 as its class will be removed in 4.0. Inject the container or the services you need in your listeners/subscribers instead.', E_USER_DEPRECATED);
return $this->container; return $this->container;
} }
@ -183,8 +193,7 @@ class ContainerAwareEventDispatcher extends EventDispatcher
protected function lazyLoad($eventName) protected function lazyLoad($eventName)
{ {
if (isset($this->listenerIds[$eventName])) { if (isset($this->listenerIds[$eventName])) {
foreach ($this->listenerIds[$eventName] as $args) { foreach ($this->listenerIds[$eventName] as list($serviceId, $method, $priority)) {
list($serviceId, $method, $priority) = $args;
$listener = $this->container->get($serviceId); $listener = $this->container->get($serviceId);
$key = $serviceId.'.'.$method; $key = $serviceId.'.'.$method;

View file

@ -31,6 +31,7 @@ class TraceableEventDispatcher implements TraceableEventDispatcherInterface
private $called; private $called;
private $dispatcher; private $dispatcher;
private $wrappedListeners;
/** /**
* Constructor. * Constructor.
@ -45,6 +46,7 @@ class TraceableEventDispatcher implements TraceableEventDispatcherInterface
$this->stopwatch = $stopwatch; $this->stopwatch = $stopwatch;
$this->logger = $logger; $this->logger = $logger;
$this->called = array(); $this->called = array();
$this->wrappedListeners = array();
} }
/** /**
@ -68,6 +70,16 @@ class TraceableEventDispatcher implements TraceableEventDispatcherInterface
*/ */
public function removeListener($eventName, $listener) public function removeListener($eventName, $listener)
{ {
if (isset($this->wrappedListeners[$eventName])) {
foreach ($this->wrappedListeners[$eventName] as $index => $wrappedListener) {
if ($wrappedListener->getWrappedListener() === $listener) {
$listener = $wrappedListener;
unset($this->wrappedListeners[$eventName][$index]);
break;
}
}
}
return $this->dispatcher->removeListener($eventName, $listener); return $this->dispatcher->removeListener($eventName, $listener);
} }
@ -87,6 +99,24 @@ class TraceableEventDispatcher implements TraceableEventDispatcherInterface
return $this->dispatcher->getListeners($eventName); return $this->dispatcher->getListeners($eventName);
} }
/**
* {@inheritdoc}
*/
public function getListenerPriority($eventName, $listener)
{
// we might have wrapped listeners for the event (if called while dispatching)
// in that case get the priority by wrapper
if (isset($this->wrappedListeners[$eventName])) {
foreach ($this->wrappedListeners[$eventName] as $index => $wrappedListener) {
if ($wrappedListener->getWrappedListener() === $listener) {
return $this->dispatcher->getListenerPriority($eventName, $wrappedListener);
}
}
}
return $this->dispatcher->getListenerPriority($eventName, $listener);
}
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
@ -104,6 +134,10 @@ class TraceableEventDispatcher implements TraceableEventDispatcherInterface
$event = new Event(); $event = new Event();
} }
if (null !== $this->logger && $event->isPropagationStopped()) {
$this->logger->debug(sprintf('The "%s" event is already stopped. No listeners have been called.', $eventName));
}
$this->preProcess($eventName); $this->preProcess($eventName);
$this->preDispatch($eventName, $event); $this->preDispatch($eventName, $event);
@ -129,8 +163,7 @@ class TraceableEventDispatcher implements TraceableEventDispatcherInterface
$called = array(); $called = array();
foreach ($this->called as $eventName => $listeners) { foreach ($this->called as $eventName => $listeners) {
foreach ($listeners as $listener) { foreach ($listeners as $listener) {
$info = $this->getListenerInfo($listener->getWrappedListener(), $eventName); $called[$eventName.'.'.$listener->getPretty()] = $listener->getInfo($eventName);
$called[$eventName.'.'.$info['pretty']] = $info;
} }
} }
@ -146,7 +179,7 @@ class TraceableEventDispatcher implements TraceableEventDispatcherInterface
$allListeners = $this->getListeners(); $allListeners = $this->getListeners();
} catch (\Exception $e) { } catch (\Exception $e) {
if (null !== $this->logger) { if (null !== $this->logger) {
$this->logger->info(sprintf('An exception was thrown while getting the uncalled listeners (%s)', $e->getMessage()), array('exception' => $e)); $this->logger->info('An exception was thrown while getting the uncalled listeners.', array('exception' => $e));
} }
// unable to retrieve the uncalled listeners // unable to retrieve the uncalled listeners
@ -168,12 +201,16 @@ class TraceableEventDispatcher implements TraceableEventDispatcherInterface
} }
if (!$called) { if (!$called) {
$info = $this->getListenerInfo($listener, $eventName); if (!$listener instanceof WrappedListener) {
$notCalled[$eventName.'.'.$info['pretty']] = $info; $listener = new WrappedListener($listener, null, $this->stopwatch, $this);
}
$notCalled[$eventName.'.'.$listener->getPretty()] = $listener->getInfo($eventName);
} }
} }
} }
uasort($notCalled, array($this, 'sortListenersByPriority'));
return $notCalled; return $notCalled;
} }
@ -213,28 +250,34 @@ class TraceableEventDispatcher implements TraceableEventDispatcherInterface
private function preProcess($eventName) private function preProcess($eventName)
{ {
foreach ($this->dispatcher->getListeners($eventName) as $listener) { foreach ($this->dispatcher->getListeners($eventName) as $listener) {
$priority = $this->getListenerPriority($eventName, $listener);
$wrappedListener = new WrappedListener($listener, null, $this->stopwatch, $this);
$this->wrappedListeners[$eventName][] = $wrappedListener;
$this->dispatcher->removeListener($eventName, $listener); $this->dispatcher->removeListener($eventName, $listener);
$info = $this->getListenerInfo($listener, $eventName); $this->dispatcher->addListener($eventName, $wrappedListener, $priority);
$name = isset($info['class']) ? $info['class'] : $info['type'];
$this->dispatcher->addListener($eventName, new WrappedListener($listener, $name, $this->stopwatch, $this));
} }
} }
private function postProcess($eventName) private function postProcess($eventName)
{ {
unset($this->wrappedListeners[$eventName]);
$skipped = false; $skipped = false;
foreach ($this->dispatcher->getListeners($eventName) as $listener) { foreach ($this->dispatcher->getListeners($eventName) as $listener) {
if (!$listener instanceof WrappedListener) { // #12845: a new listener was added during dispatch. if (!$listener instanceof WrappedListener) { // #12845: a new listener was added during dispatch.
continue; continue;
} }
// Unwrap listener // Unwrap listener
$priority = $this->getListenerPriority($eventName, $listener);
$this->dispatcher->removeListener($eventName, $listener); $this->dispatcher->removeListener($eventName, $listener);
$this->dispatcher->addListener($eventName, $listener->getWrappedListener()); $this->dispatcher->addListener($eventName, $listener->getWrappedListener(), $priority);
if (null !== $this->logger) {
$context = array('event' => $eventName, 'listener' => $listener->getPretty());
}
$info = $this->getListenerInfo($listener->getWrappedListener(), $eventName);
if ($listener->wasCalled()) { if ($listener->wasCalled()) {
if (null !== $this->logger) { if (null !== $this->logger) {
$this->logger->debug(sprintf('Notified event "%s" to listener "%s".', $eventName, $info['pretty'])); $this->logger->debug('Notified event "{event}" to listener "{listener}".', $context);
} }
if (!isset($this->called[$eventName])) { if (!isset($this->called[$eventName])) {
@ -245,12 +288,12 @@ class TraceableEventDispatcher implements TraceableEventDispatcherInterface
} }
if (null !== $this->logger && $skipped) { if (null !== $this->logger && $skipped) {
$this->logger->debug(sprintf('Listener "%s" was not called for event "%s".', $info['pretty'], $eventName)); $this->logger->debug('Listener "{listener}" was not called for event "{event}".', $context);
} }
if ($listener->stoppedPropagation()) { if ($listener->stoppedPropagation()) {
if (null !== $this->logger) { if (null !== $this->logger) {
$this->logger->debug(sprintf('Listener "%s" stopped propagation of the event "%s".', $info['pretty'], $eventName)); $this->logger->debug('Listener "{listener}" stopped propagation of the event "{event}".', $context);
} }
$skipped = true; $skipped = true;
@ -258,63 +301,24 @@ class TraceableEventDispatcher implements TraceableEventDispatcherInterface
} }
} }
/** private function sortListenersByPriority($a, $b)
* Returns information about the listener
*
* @param object $listener The listener
* @param string $eventName The event name
*
* @return array Information about the listener
*/
private function getListenerInfo($listener, $eventName)
{ {
$info = array( if (is_int($a['priority']) && !is_int($b['priority'])) {
'event' => $eventName, return 1;
);
if ($listener instanceof \Closure) {
$info += array(
'type' => 'Closure',
'pretty' => 'closure',
);
} elseif (is_string($listener)) {
try {
$r = new \ReflectionFunction($listener);
$file = $r->getFileName();
$line = $r->getStartLine();
} catch (\ReflectionException $e) {
$file = null;
$line = null;
}
$info += array(
'type' => 'Function',
'function' => $listener,
'file' => $file,
'line' => $line,
'pretty' => $listener,
);
} elseif (is_array($listener) || (is_object($listener) && is_callable($listener))) {
if (!is_array($listener)) {
$listener = array($listener, '__invoke');
}
$class = is_object($listener[0]) ? get_class($listener[0]) : $listener[0];
try {
$r = new \ReflectionMethod($class, $listener[1]);
$file = $r->getFileName();
$line = $r->getStartLine();
} catch (\ReflectionException $e) {
$file = null;
$line = null;
}
$info += array(
'type' => 'Method',
'class' => $class,
'method' => $listener[1],
'file' => $file,
'line' => $line,
'pretty' => $class.'::'.$listener[1],
);
} }
return $info; if (!is_int($a['priority']) && is_int($b['priority'])) {
return -1;
}
if ($a['priority'] === $b['priority']) {
return 0;
}
if ($a['priority'] > $b['priority']) {
return -1;
}
return 1;
} }
} }

View file

@ -14,6 +14,8 @@ namespace Symfony\Component\EventDispatcher\Debug;
use Symfony\Component\Stopwatch\Stopwatch; use Symfony\Component\Stopwatch\Stopwatch;
use Symfony\Component\EventDispatcher\Event; use Symfony\Component\EventDispatcher\Event;
use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\VarDumper\Caster\ClassStub;
use Symfony\Component\VarDumper\Cloner\VarCloner;
/** /**
* @author Fabien Potencier <fabien@symfony.com> * @author Fabien Potencier <fabien@symfony.com>
@ -26,6 +28,10 @@ class WrappedListener
private $stoppedPropagation; private $stoppedPropagation;
private $stopwatch; private $stopwatch;
private $dispatcher; private $dispatcher;
private $pretty;
private $stub;
private static $cloner;
public function __construct($listener, $name, Stopwatch $stopwatch, EventDispatcherInterface $dispatcher = null) public function __construct($listener, $name, Stopwatch $stopwatch, EventDispatcherInterface $dispatcher = null)
{ {
@ -35,6 +41,26 @@ class WrappedListener
$this->dispatcher = $dispatcher; $this->dispatcher = $dispatcher;
$this->called = false; $this->called = false;
$this->stoppedPropagation = false; $this->stoppedPropagation = false;
if (is_array($listener)) {
$this->name = is_object($listener[0]) ? get_class($listener[0]) : $listener[0];
$this->pretty = $this->name.'::'.$listener[1];
} elseif ($listener instanceof \Closure) {
$this->pretty = $this->name = 'closure';
} elseif (is_string($listener)) {
$this->pretty = $this->name = $listener;
} else {
$this->name = get_class($listener);
$this->pretty = $this->name.'::__invoke';
}
if (null !== $name) {
$this->name = $name;
}
if (null === self::$cloner) {
self::$cloner = class_exists(ClassStub::class) ? new VarCloner() : false;
}
} }
public function getWrappedListener() public function getWrappedListener()
@ -52,6 +78,25 @@ class WrappedListener
return $this->stoppedPropagation; return $this->stoppedPropagation;
} }
public function getPretty()
{
return $this->pretty;
}
public function getInfo($eventName)
{
if (null === $this->stub) {
$this->stub = false === self::$cloner ? $this->pretty.'()' : new ClassStub($this->pretty.'()', $this->listener);
}
return array(
'event' => $eventName,
'priority' => null !== $this->dispatcher ? $this->dispatcher->getListenerPriority($eventName, $this->listener) : null,
'pretty' => $this->pretty,
'stub' => $this->stub,
);
}
public function __invoke(Event $event, $eventName, EventDispatcherInterface $dispatcher) public function __invoke(Event $event, $eventName, EventDispatcherInterface $dispatcher)
{ {
$this->called = true; $this->called = true;

View file

@ -11,8 +11,13 @@
namespace Symfony\Component\EventDispatcher\DependencyInjection; namespace Symfony\Component\EventDispatcher\DependencyInjection;
use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument;
use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
/** /**
* Compiler pass to register tagged services for an event dispatcher. * Compiler pass to register tagged services for an event dispatcher.
@ -56,21 +61,14 @@ class RegisterListenersPass implements CompilerPassInterface
$definition = $container->findDefinition($this->dispatcherService); $definition = $container->findDefinition($this->dispatcherService);
foreach ($container->findTaggedServiceIds($this->listenerTag) as $id => $events) { foreach ($container->findTaggedServiceIds($this->listenerTag, true) as $id => $events) {
$def = $container->getDefinition($id); $def = $container->getDefinition($id);
if (!$def->isPublic()) {
throw new \InvalidArgumentException(sprintf('The service "%s" must be public as event listeners are lazy-loaded.', $id));
}
if ($def->isAbstract()) {
throw new \InvalidArgumentException(sprintf('The service "%s" must not be abstract as event listeners are lazy-loaded.', $id));
}
foreach ($events as $event) { foreach ($events as $event) {
$priority = isset($event['priority']) ? $event['priority'] : 0; $priority = isset($event['priority']) ? $event['priority'] : 0;
if (!isset($event['event'])) { if (!isset($event['event'])) {
throw new \InvalidArgumentException(sprintf('Service "%s" must define the "event" attribute on "%s" tags.', $id, $this->listenerTag)); throw new InvalidArgumentException(sprintf('Service "%s" must define the "event" attribute on "%s" tags.', $id, $this->listenerTag));
} }
if (!isset($event['method'])) { if (!isset($event['method'])) {
@ -81,30 +79,57 @@ class RegisterListenersPass implements CompilerPassInterface
$event['method'] = preg_replace('/[^a-z0-9]/i', '', $event['method']); $event['method'] = preg_replace('/[^a-z0-9]/i', '', $event['method']);
} }
$definition->addMethodCall('addListenerService', array($event['event'], array($id, $event['method']), $priority)); $definition->addMethodCall('addListener', array($event['event'], array(new ServiceClosureArgument(new Reference($id)), $event['method']), $priority));
} }
} }
foreach ($container->findTaggedServiceIds($this->subscriberTag) as $id => $attributes) { $extractingDispatcher = new ExtractingEventDispatcher();
$def = $container->getDefinition($id);
if (!$def->isPublic()) {
throw new \InvalidArgumentException(sprintf('The service "%s" must be public as event subscribers are lazy-loaded.', $id));
}
if ($def->isAbstract()) { foreach ($container->findTaggedServiceIds($this->subscriberTag, true) as $id => $attributes) {
throw new \InvalidArgumentException(sprintf('The service "%s" must not be abstract as event subscribers are lazy-loaded.', $id)); $def = $container->getDefinition($id);
}
// We must assume that the class value has been correctly filled, even if the service is created by a factory // We must assume that the class value has been correctly filled, even if the service is created by a factory
$class = $container->getParameterBag()->resolveValue($def->getClass()); $class = $container->getParameterBag()->resolveValue($def->getClass());
$refClass = new \ReflectionClass($class);
$interface = 'Symfony\Component\EventDispatcher\EventSubscriberInterface'; $interface = 'Symfony\Component\EventDispatcher\EventSubscriberInterface';
if (!$refClass->implementsInterface($interface)) {
throw new \InvalidArgumentException(sprintf('Service "%s" must implement interface "%s".', $id, $interface));
}
$definition->addMethodCall('addSubscriberService', array($id, $class)); if (!is_subclass_of($class, $interface)) {
if (!class_exists($class, false)) {
throw new InvalidArgumentException(sprintf('Class "%s" used for service "%s" cannot be found.', $class, $id));
}
throw new InvalidArgumentException(sprintf('Service "%s" must implement interface "%s".', $id, $interface));
}
$container->addObjectResource($class);
ExtractingEventDispatcher::$subscriber = $class;
$extractingDispatcher->addSubscriber($extractingDispatcher);
foreach ($extractingDispatcher->listeners as $args) {
$args[1] = array(new ServiceClosureArgument(new Reference($id)), $args[1]);
$definition->addMethodCall('addListener', $args);
}
$extractingDispatcher->listeners = array();
} }
} }
} }
/**
* @internal
*/
class ExtractingEventDispatcher extends EventDispatcher implements EventSubscriberInterface
{
public $listeners = array();
public static $subscriber;
public function addListener($eventName, $listener, $priority = 0)
{
$this->listeners[] = array($eventName, $listener[1], $priority);
}
public static function getSubscribedEvents()
{
$callback = array(self::$subscriber, 'getSubscribedEvents');
return $callback();
}
}

View file

@ -24,8 +24,6 @@ namespace Symfony\Component\EventDispatcher;
* @author Jonathan Wage <jonwage@gmail.com> * @author Jonathan Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org> * @author Roman Borschel <roman@code-factory.org>
* @author Bernhard Schussek <bschussek@gmail.com> * @author Bernhard Schussek <bschussek@gmail.com>
*
* @api
*/ */
class Event class Event
{ {
@ -34,24 +32,12 @@ class Event
*/ */
private $propagationStopped = false; private $propagationStopped = false;
/**
* @var EventDispatcher Dispatcher that dispatched this event
*/
private $dispatcher;
/**
* @var string This event's name
*/
private $name;
/** /**
* Returns whether further event listeners should be triggered. * Returns whether further event listeners should be triggered.
* *
* @see Event::stopPropagation() * @see Event::stopPropagation()
* *
* @return bool Whether propagation was already stopped for this event. * @return bool Whether propagation was already stopped for this event
*
* @api
*/ */
public function isPropagationStopped() public function isPropagationStopped()
{ {
@ -64,67 +50,9 @@ class Event
* If multiple event listeners are connected to the same event, no * If multiple event listeners are connected to the same event, no
* further event listener will be triggered once any trigger calls * further event listener will be triggered once any trigger calls
* stopPropagation(). * stopPropagation().
*
* @api
*/ */
public function stopPropagation() public function stopPropagation()
{ {
$this->propagationStopped = true; $this->propagationStopped = true;
} }
/**
* Stores the EventDispatcher that dispatches this Event.
*
* @param EventDispatcherInterface $dispatcher
*
* @deprecated Deprecated in 2.4, to be removed in 3.0. The event dispatcher is passed to the listener call.
*
* @api
*/
public function setDispatcher(EventDispatcherInterface $dispatcher)
{
$this->dispatcher = $dispatcher;
}
/**
* Returns the EventDispatcher that dispatches this Event.
*
* @return EventDispatcherInterface
*
* @deprecated Deprecated in 2.4, to be removed in 3.0. The event dispatcher is passed to the listener call.
*
* @api
*/
public function getDispatcher()
{
return $this->dispatcher;
}
/**
* Gets the event's name.
*
* @return string
*
* @deprecated Deprecated in 2.4, to be removed in 3.0. The event name is passed to the listener call.
*
* @api
*/
public function getName()
{
return $this->name;
}
/**
* Sets the event's name property.
*
* @param string $name The event name.
*
* @deprecated Deprecated in 2.4, to be removed in 3.0. The event name is passed to the listener call.
*
* @api
*/
public function setName($name)
{
$this->name = $name;
}
} }

View file

@ -24,8 +24,7 @@ namespace Symfony\Component\EventDispatcher;
* @author Fabien Potencier <fabien@symfony.com> * @author Fabien Potencier <fabien@symfony.com>
* @author Jordi Boggiano <j.boggiano@seld.be> * @author Jordi Boggiano <j.boggiano@seld.be>
* @author Jordan Alliot <jordan.alliot@gmail.com> * @author Jordan Alliot <jordan.alliot@gmail.com>
* * @author Nicolas Grekas <p@tchwork.com>
* @api
*/ */
class EventDispatcher implements EventDispatcherInterface class EventDispatcher implements EventDispatcherInterface
{ {
@ -33,9 +32,7 @@ class EventDispatcher implements EventDispatcherInterface
private $sorted = array(); private $sorted = array();
/** /**
* @see EventDispatcherInterface::dispatch() * {@inheritdoc}
*
* @api
*/ */
public function dispatch($eventName, Event $event = null) public function dispatch($eventName, Event $event = null)
{ {
@ -43,24 +40,23 @@ class EventDispatcher implements EventDispatcherInterface
$event = new Event(); $event = new Event();
} }
$event->setDispatcher($this); if ($listeners = $this->getListeners($eventName)) {
$event->setName($eventName); $this->doDispatch($listeners, $eventName, $event);
if (!isset($this->listeners[$eventName])) {
return $event;
} }
$this->doDispatch($this->getListeners($eventName), $eventName, $event);
return $event; return $event;
} }
/** /**
* @see EventDispatcherInterface::getListeners() * {@inheritdoc}
*/ */
public function getListeners($eventName = null) public function getListeners($eventName = null)
{ {
if (null !== $eventName) { if (null !== $eventName) {
if (empty($this->listeners[$eventName])) {
return array();
}
if (!isset($this->sorted[$eventName])) { if (!isset($this->sorted[$eventName])) {
$this->sortListeners($eventName); $this->sortListeners($eventName);
} }
@ -68,7 +64,7 @@ class EventDispatcher implements EventDispatcherInterface
return $this->sorted[$eventName]; return $this->sorted[$eventName];
} }
foreach (array_keys($this->listeners) as $eventName) { foreach ($this->listeners as $eventName => $eventListeners) {
if (!isset($this->sorted[$eventName])) { if (!isset($this->sorted[$eventName])) {
$this->sortListeners($eventName); $this->sortListeners($eventName);
} }
@ -78,17 +74,51 @@ class EventDispatcher implements EventDispatcherInterface
} }
/** /**
* @see EventDispatcherInterface::hasListeners() * {@inheritdoc}
*/ */
public function hasListeners($eventName = null) public function getListenerPriority($eventName, $listener)
{ {
return (bool) count($this->getListeners($eventName)); if (empty($this->listeners[$eventName])) {
return;
}
if (is_array($listener) && isset($listener[0]) && $listener[0] instanceof \Closure) {
$listener[0] = $listener[0]();
}
foreach ($this->listeners[$eventName] as $priority => $listeners) {
foreach ($listeners as $k => $v) {
if ($v !== $listener && is_array($v) && isset($v[0]) && $v[0] instanceof \Closure) {
$v[0] = $v[0]();
$this->listeners[$eventName][$priority][$k] = $v;
}
if ($v === $listener) {
return $priority;
}
}
}
} }
/** /**
* @see EventDispatcherInterface::addListener() * {@inheritdoc}
* */
* @api public function hasListeners($eventName = null)
{
if (null !== $eventName) {
return !empty($this->listeners[$eventName]);
}
foreach ($this->listeners as $eventListeners) {
if ($eventListeners) {
return true;
}
}
return false;
}
/**
* {@inheritdoc}
*/ */
public function addListener($eventName, $listener, $priority = 0) public function addListener($eventName, $listener, $priority = 0)
{ {
@ -97,25 +127,40 @@ class EventDispatcher implements EventDispatcherInterface
} }
/** /**
* @see EventDispatcherInterface::removeListener() * {@inheritdoc}
*/ */
public function removeListener($eventName, $listener) public function removeListener($eventName, $listener)
{ {
if (!isset($this->listeners[$eventName])) { if (empty($this->listeners[$eventName])) {
return; return;
} }
if (is_array($listener) && isset($listener[0]) && $listener[0] instanceof \Closure) {
$listener[0] = $listener[0]();
}
foreach ($this->listeners[$eventName] as $priority => $listeners) { foreach ($this->listeners[$eventName] as $priority => $listeners) {
if (false !== ($key = array_search($listener, $listeners, true))) { foreach ($listeners as $k => $v) {
unset($this->listeners[$eventName][$priority][$key], $this->sorted[$eventName]); if ($v !== $listener && is_array($v) && isset($v[0]) && $v[0] instanceof \Closure) {
$v[0] = $v[0]();
}
if ($v === $listener) {
unset($listeners[$k], $this->sorted[$eventName]);
} else {
$listeners[$k] = $v;
}
}
if ($listeners) {
$this->listeners[$eventName][$priority] = $listeners;
} else {
unset($this->listeners[$eventName][$priority]);
} }
} }
} }
/** /**
* @see EventDispatcherInterface::addSubscriber() * {@inheritdoc}
*
* @api
*/ */
public function addSubscriber(EventSubscriberInterface $subscriber) public function addSubscriber(EventSubscriberInterface $subscriber)
{ {
@ -133,7 +178,7 @@ class EventDispatcher implements EventDispatcherInterface
} }
/** /**
* @see EventDispatcherInterface::removeSubscriber() * {@inheritdoc}
*/ */
public function removeSubscriber(EventSubscriberInterface $subscriber) public function removeSubscriber(EventSubscriberInterface $subscriber)
{ {
@ -154,32 +199,38 @@ class EventDispatcher implements EventDispatcherInterface
* This method can be overridden to add functionality that is executed * This method can be overridden to add functionality that is executed
* for each listener. * for each listener.
* *
* @param callable[] $listeners The event listeners. * @param callable[] $listeners The event listeners
* @param string $eventName The name of the event to dispatch. * @param string $eventName The name of the event to dispatch
* @param Event $event The event object to pass to the event handlers/listeners. * @param Event $event The event object to pass to the event handlers/listeners
*/ */
protected function doDispatch($listeners, $eventName, Event $event) protected function doDispatch($listeners, $eventName, Event $event)
{ {
foreach ($listeners as $listener) { foreach ($listeners as $listener) {
call_user_func($listener, $event, $eventName, $this);
if ($event->isPropagationStopped()) { if ($event->isPropagationStopped()) {
break; break;
} }
call_user_func($listener, $event, $eventName, $this);
} }
} }
/** /**
* Sorts the internal list of listeners for the given event by priority. * Sorts the internal list of listeners for the given event by priority.
* *
* @param string $eventName The name of the event. * @param string $eventName The name of the event
*/ */
private function sortListeners($eventName) private function sortListeners($eventName)
{ {
krsort($this->listeners[$eventName]);
$this->sorted[$eventName] = array(); $this->sorted[$eventName] = array();
if (isset($this->listeners[$eventName])) { foreach ($this->listeners[$eventName] as $priority => $listeners) {
krsort($this->listeners[$eventName]); foreach ($listeners as $k => $listener) {
$this->sorted[$eventName] = call_user_func_array('array_merge', $this->listeners[$eventName]); if (is_array($listener) && isset($listener[0]) && $listener[0] instanceof \Closure) {
$listener[0] = $listener[0]();
$this->listeners[$eventName][$priority][$k] = $listener;
}
$this->sorted[$eventName][] = $listener;
}
} }
} }
} }

View file

@ -17,8 +17,6 @@ namespace Symfony\Component\EventDispatcher;
* manager. * manager.
* *
* @author Bernhard Schussek <bschussek@gmail.com> * @author Bernhard Schussek <bschussek@gmail.com>
*
* @api
*/ */
interface EventDispatcherInterface interface EventDispatcherInterface
{ {
@ -28,12 +26,10 @@ interface EventDispatcherInterface
* @param string $eventName The name of the event to dispatch. The name of * @param string $eventName The name of the event to dispatch. The name of
* the event is the name of the method that is * the event is the name of the method that is
* invoked on listeners. * invoked on listeners.
* @param Event $event The event to pass to the event handlers/listeners. * @param Event $event The event to pass to the event handlers/listeners
* If not supplied, an empty Event instance is created. * If not supplied, an empty Event instance is created.
* *
* @return Event * @return Event
*
* @api
*/ */
public function dispatch($eventName, Event $event = null); public function dispatch($eventName, Event $event = null);
@ -44,8 +40,6 @@ interface EventDispatcherInterface
* @param callable $listener The listener * @param callable $listener The listener
* @param int $priority The higher this value, the earlier an event * @param int $priority The higher this value, the earlier an event
* listener will be triggered in the chain (defaults to 0) * listener will be triggered in the chain (defaults to 0)
*
* @api
*/ */
public function addListener($eventName, $listener, $priority = 0); public function addListener($eventName, $listener, $priority = 0);
@ -55,9 +49,7 @@ interface EventDispatcherInterface
* The subscriber is asked for all the events he is * The subscriber is asked for all the events he is
* interested in and added as a listener for these events. * interested in and added as a listener for these events.
* *
* @param EventSubscriberInterface $subscriber The subscriber. * @param EventSubscriberInterface $subscriber The subscriber
*
* @api
*/ */
public function addSubscriber(EventSubscriberInterface $subscriber); public function addSubscriber(EventSubscriberInterface $subscriber);
@ -77,7 +69,7 @@ interface EventDispatcherInterface
public function removeSubscriber(EventSubscriberInterface $subscriber); public function removeSubscriber(EventSubscriberInterface $subscriber);
/** /**
* Gets the listeners of a specific event or all listeners. * Gets the listeners of a specific event or all listeners sorted by descending priority.
* *
* @param string $eventName The name of the event * @param string $eventName The name of the event
* *
@ -85,6 +77,18 @@ interface EventDispatcherInterface
*/ */
public function getListeners($eventName = null); public function getListeners($eventName = null);
/**
* Gets the listener priority for a specific event.
*
* Returns null if the event or the listener does not exist.
*
* @param string $eventName The name of the event
* @param callable $listener The listener
*
* @return int|null The event listener priority
*/
public function getListenerPriority($eventName, $listener);
/** /**
* Checks whether an event has any registered listeners. * Checks whether an event has any registered listeners.
* *

View file

@ -21,8 +21,6 @@ namespace Symfony\Component\EventDispatcher;
* @author Jonathan Wage <jonwage@gmail.com> * @author Jonathan Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org> * @author Roman Borschel <roman@code-factory.org>
* @author Bernhard Schussek <bschussek@gmail.com> * @author Bernhard Schussek <bschussek@gmail.com>
*
* @api
*/ */
interface EventSubscriberInterface interface EventSubscriberInterface
{ {
@ -40,11 +38,9 @@ interface EventSubscriberInterface
* *
* * array('eventName' => 'methodName') * * array('eventName' => 'methodName')
* * array('eventName' => array('methodName', $priority)) * * array('eventName' => array('methodName', $priority))
* * array('eventName' => array(array('methodName1', $priority), array('methodName2')) * * array('eventName' => array(array('methodName1', $priority), array('methodName2')))
* *
* @return array The event names to listen to * @return array The event names to listen to
*
* @api
*/ */
public static function getSubscribedEvents(); public static function getSubscribedEvents();
} }

View file

@ -37,8 +37,8 @@ class GenericEvent extends Event implements \ArrayAccess, \IteratorAggregate
/** /**
* Encapsulate an event with $subject and $args. * Encapsulate an event with $subject and $args.
* *
* @param mixed $subject The subject of the event, usually an object. * @param mixed $subject The subject of the event, usually an object
* @param array $arguments Arguments to store in the event. * @param array $arguments Arguments to store in the event
*/ */
public function __construct($subject = null, array $arguments = array()) public function __construct($subject = null, array $arguments = array())
{ {
@ -49,7 +49,7 @@ class GenericEvent extends Event implements \ArrayAccess, \IteratorAggregate
/** /**
* Getter for subject property. * Getter for subject property.
* *
* @return mixed $subject The observer subject. * @return mixed $subject The observer subject
*/ */
public function getSubject() public function getSubject()
{ {
@ -59,11 +59,11 @@ class GenericEvent extends Event implements \ArrayAccess, \IteratorAggregate
/** /**
* Get argument by key. * Get argument by key.
* *
* @param string $key Key. * @param string $key Key
*
* @return mixed Contents of array key
* *
* @throws \InvalidArgumentException If key is not found. * @throws \InvalidArgumentException If key is not found.
*
* @return mixed Contents of array key.
*/ */
public function getArgument($key) public function getArgument($key)
{ {
@ -71,16 +71,16 @@ class GenericEvent extends Event implements \ArrayAccess, \IteratorAggregate
return $this->arguments[$key]; return $this->arguments[$key];
} }
throw new \InvalidArgumentException(sprintf('%s not found in %s', $key, $this->getName())); throw new \InvalidArgumentException(sprintf('Argument "%s" not found.', $key));
} }
/** /**
* Add argument to event. * Add argument to event.
* *
* @param string $key Argument name. * @param string $key Argument name
* @param mixed $value Value. * @param mixed $value Value
* *
* @return GenericEvent * @return $this
*/ */
public function setArgument($key, $value) public function setArgument($key, $value)
{ {
@ -102,9 +102,9 @@ class GenericEvent extends Event implements \ArrayAccess, \IteratorAggregate
/** /**
* Set args property. * Set args property.
* *
* @param array $args Arguments. * @param array $args Arguments
* *
* @return GenericEvent * @return $this
*/ */
public function setArguments(array $args = array()) public function setArguments(array $args = array())
{ {
@ -116,7 +116,7 @@ class GenericEvent extends Event implements \ArrayAccess, \IteratorAggregate
/** /**
* Has argument. * Has argument.
* *
* @param string $key Key of arguments array. * @param string $key Key of arguments array
* *
* @return bool * @return bool
*/ */
@ -128,11 +128,11 @@ class GenericEvent extends Event implements \ArrayAccess, \IteratorAggregate
/** /**
* ArrayAccess for argument getter. * ArrayAccess for argument getter.
* *
* @param string $key Array key. * @param string $key Array key
*
* @throws \InvalidArgumentException If key does not exist in $this->args.
* *
* @return mixed * @return mixed
*
* @throws \InvalidArgumentException If key does not exist in $this->args.
*/ */
public function offsetGet($key) public function offsetGet($key)
{ {
@ -142,8 +142,8 @@ class GenericEvent extends Event implements \ArrayAccess, \IteratorAggregate
/** /**
* ArrayAccess for argument setter. * ArrayAccess for argument setter.
* *
* @param string $key Array key to set. * @param string $key Array key to set
* @param mixed $value Value. * @param mixed $value Value
*/ */
public function offsetSet($key, $value) public function offsetSet($key, $value)
{ {
@ -153,7 +153,7 @@ class GenericEvent extends Event implements \ArrayAccess, \IteratorAggregate
/** /**
* ArrayAccess for unset argument. * ArrayAccess for unset argument.
* *
* @param string $key Array key. * @param string $key Array key
*/ */
public function offsetUnset($key) public function offsetUnset($key)
{ {
@ -165,7 +165,7 @@ class GenericEvent extends Event implements \ArrayAccess, \IteratorAggregate
/** /**
* ArrayAccess has argument. * ArrayAccess has argument.
* *
* @param string $key Array key. * @param string $key Array key
* *
* @return bool * @return bool
*/ */

View file

@ -28,7 +28,7 @@ class ImmutableEventDispatcher implements EventDispatcherInterface
/** /**
* Creates an unmodifiable proxy for an event dispatcher. * Creates an unmodifiable proxy for an event dispatcher.
* *
* @param EventDispatcherInterface $dispatcher The proxied event dispatcher. * @param EventDispatcherInterface $dispatcher The proxied event dispatcher
*/ */
public function __construct(EventDispatcherInterface $dispatcher) public function __construct(EventDispatcherInterface $dispatcher)
{ {
@ -83,6 +83,14 @@ class ImmutableEventDispatcher implements EventDispatcherInterface
return $this->dispatcher->getListeners($eventName); return $this->dispatcher->getListeners($eventName);
} }
/**
* {@inheritdoc}
*/
public function getListenerPriority($eventName, $listener)
{
return $this->dispatcher->getListenerPriority($eventName, $listener);
}
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */

View file

@ -1,4 +1,4 @@
Copyright (c) 2004-2015 Fabien Potencier Copyright (c) 2004-2017 Fabien Potencier
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View file

@ -0,0 +1,15 @@
EventDispatcher Component
=========================
The EventDispatcher component provides tools that allow your application
components to communicate with each other by dispatching events and listening to
them.
Resources
---------
* [Documentation](https://symfony.com/doc/current/components/event_dispatcher/index.html)
* [Contributing](https://symfony.com/doc/current/contributing/index.html)
* [Report issues](https://github.com/symfony/symfony/issues) and
[send Pull Requests](https://github.com/symfony/symfony/pulls)
in the [main Symfony repository](https://github.com/symfony/symfony)

View file

@ -1,27 +0,0 @@
EventDispatcher Component
=========================
The Symfony EventDispatcher component implements the Mediator pattern in a
simple and effective way to make your projects truly extensible.
```php
use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\EventDispatcher\Event;
$dispatcher = new EventDispatcher();
$dispatcher->addListener('event_name', function (Event $event) {
// ...
});
$dispatcher->dispatch('event_name');
```
Resources
---------
You can run the unit tests with the following command:
$ cd path/to/Symfony/Component/EventDispatcher/
$ composer install
$ phpunit

View file

@ -1,100 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\EventDispatcher\Tests;
use Symfony\Component\EventDispatcher\Event;
use Symfony\Component\EventDispatcher\EventDispatcher;
/**
* Test class for Event.
*/
class EventTest extends \PHPUnit_Framework_TestCase
{
/**
* @var \Symfony\Component\EventDispatcher\Event
*/
protected $event;
/**
* @var \Symfony\Component\EventDispatcher\EventDispatcher
*/
protected $dispatcher;
/**
* Sets up the fixture, for example, opens a network connection.
* This method is called before a test is executed.
*/
protected function setUp()
{
$this->event = new Event();
$this->dispatcher = new EventDispatcher();
}
/**
* Tears down the fixture, for example, closes a network connection.
* This method is called after a test is executed.
*/
protected function tearDown()
{
$this->event = null;
$this->dispatcher = null;
}
public function testIsPropagationStopped()
{
$this->assertFalse($this->event->isPropagationStopped());
}
public function testStopPropagationAndIsPropagationStopped()
{
$this->event->stopPropagation();
$this->assertTrue($this->event->isPropagationStopped());
}
/**
* @group legacy
*/
public function testLegacySetDispatcher()
{
$this->iniSet('error_reporting', -1 & ~E_USER_DEPRECATED);
$this->event->setDispatcher($this->dispatcher);
$this->assertSame($this->dispatcher, $this->event->getDispatcher());
}
/**
* @group legacy
*/
public function testLegacyGetDispatcher()
{
$this->iniSet('error_reporting', -1 & ~E_USER_DEPRECATED);
$this->assertNull($this->event->getDispatcher());
}
/**
* @group legacy
*/
public function testLegacyGetName()
{
$this->iniSet('error_reporting', -1 & ~E_USER_DEPRECATED);
$this->assertNull($this->event->getName());
}
/**
* @group legacy
*/
public function testLegacySetName()
{
$this->iniSet('error_reporting', -1 & ~E_USER_DEPRECATED);
$this->event->setName('foo');
$this->assertEquals('foo', $this->event->getName());
}
}

View file

@ -11,10 +11,12 @@
namespace Symfony\Component\EventDispatcher\Tests; namespace Symfony\Component\EventDispatcher\Tests;
use PHPUnit\Framework\TestCase;
use Symfony\Component\EventDispatcher\Event; use Symfony\Component\EventDispatcher\Event;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\EventDispatcher\EventSubscriberInterface;
abstract class AbstractEventDispatcherTest extends \PHPUnit_Framework_TestCase abstract class AbstractEventDispatcherTest extends TestCase
{ {
/* Some pseudo events */ /* Some pseudo events */
const preFoo = 'pre.foo'; const preFoo = 'pre.foo';
@ -54,6 +56,7 @@ abstract class AbstractEventDispatcherTest extends \PHPUnit_Framework_TestCase
{ {
$this->dispatcher->addListener('pre.foo', array($this->listener, 'preFoo')); $this->dispatcher->addListener('pre.foo', array($this->listener, 'preFoo'));
$this->dispatcher->addListener('post.foo', array($this->listener, 'postFoo')); $this->dispatcher->addListener('post.foo', array($this->listener, 'postFoo'));
$this->assertTrue($this->dispatcher->hasListeners());
$this->assertTrue($this->dispatcher->hasListeners(self::preFoo)); $this->assertTrue($this->dispatcher->hasListeners(self::preFoo));
$this->assertTrue($this->dispatcher->hasListeners(self::postFoo)); $this->assertTrue($this->dispatcher->hasListeners(self::postFoo));
$this->assertCount(1, $this->dispatcher->getListeners(self::preFoo)); $this->assertCount(1, $this->dispatcher->getListeners(self::preFoo));
@ -107,6 +110,20 @@ abstract class AbstractEventDispatcherTest extends \PHPUnit_Framework_TestCase
$this->assertSame($expected, $this->dispatcher->getListeners()); $this->assertSame($expected, $this->dispatcher->getListeners());
} }
public function testGetListenerPriority()
{
$listener1 = new TestEventListener();
$listener2 = new TestEventListener();
$this->dispatcher->addListener('pre.foo', $listener1, -10);
$this->dispatcher->addListener('pre.foo', $listener2);
$this->assertSame(-10, $this->dispatcher->getListenerPriority('pre.foo', $listener1));
$this->assertSame(0, $this->dispatcher->getListenerPriority('pre.foo', $listener2));
$this->assertNull($this->dispatcher->getListenerPriority('pre.bar', $listener2));
$this->assertNull($this->dispatcher->getListenerPriority('pre.foo', function () {}));
}
public function testDispatch() public function testDispatch()
{ {
$this->dispatcher->addListener('pre.foo', array($this->listener, 'preFoo')); $this->dispatcher->addListener('pre.foo', array($this->listener, 'preFoo'));
@ -118,7 +135,6 @@ abstract class AbstractEventDispatcherTest extends \PHPUnit_Framework_TestCase
$this->assertInstanceOf('Symfony\Component\EventDispatcher\Event', $this->dispatcher->dispatch(self::preFoo)); $this->assertInstanceOf('Symfony\Component\EventDispatcher\Event', $this->dispatcher->dispatch(self::preFoo));
$event = new Event(); $event = new Event();
$return = $this->dispatcher->dispatch(self::preFoo, $event); $return = $this->dispatcher->dispatch(self::preFoo, $event);
$this->assertEquals('pre.foo', $event->getName());
$this->assertSame($event, $return); $this->assertSame($event, $return);
} }
@ -126,7 +142,7 @@ abstract class AbstractEventDispatcherTest extends \PHPUnit_Framework_TestCase
{ {
$invoked = 0; $invoked = 0;
$listener = function () use (&$invoked) { $listener = function () use (&$invoked) {
$invoked++; ++$invoked;
}; };
$this->dispatcher->addListener('pre.foo', $listener); $this->dispatcher->addListener('pre.foo', $listener);
$this->dispatcher->addListener('post.foo', $listener); $this->dispatcher->addListener('post.foo', $listener);
@ -239,16 +255,6 @@ abstract class AbstractEventDispatcherTest extends \PHPUnit_Framework_TestCase
$this->assertFalse($this->dispatcher->hasListeners(self::preFoo)); $this->assertFalse($this->dispatcher->hasListeners(self::preFoo));
} }
public function testEventReceivesTheDispatcherInstance()
{
$dispatcher = null;
$this->dispatcher->addListener('test', function ($event) use (&$dispatcher) {
$dispatcher = $event->getDispatcher();
});
$this->dispatcher->dispatch('test');
$this->assertSame($this->dispatcher, $dispatcher);
}
public function testEventReceivesTheDispatcherInstanceAsArgument() public function testEventReceivesTheDispatcherInstanceAsArgument()
{ {
$listener = new TestWithDispatcher(); $listener = new TestWithDispatcher();
@ -297,6 +303,73 @@ abstract class AbstractEventDispatcherTest extends \PHPUnit_Framework_TestCase
$this->assertFalse($this->dispatcher->hasListeners('foo')); $this->assertFalse($this->dispatcher->hasListeners('foo'));
$this->assertFalse($this->dispatcher->hasListeners()); $this->assertFalse($this->dispatcher->hasListeners());
} }
public function testHasListenersIsLazy()
{
$called = 0;
$listener = array(function () use (&$called) { ++$called; }, 'onFoo');
$this->dispatcher->addListener('foo', $listener);
$this->assertTrue($this->dispatcher->hasListeners());
$this->assertTrue($this->dispatcher->hasListeners('foo'));
$this->assertSame(0, $called);
}
public function testDispatchLazyListener()
{
$called = 0;
$factory = function () use (&$called) {
++$called;
return new TestWithDispatcher();
};
$this->dispatcher->addListener('foo', array($factory, 'foo'));
$this->assertSame(0, $called);
$this->dispatcher->dispatch('foo', new Event());
$this->dispatcher->dispatch('foo', new Event());
$this->assertSame(1, $called);
}
public function testRemoveFindsLazyListeners()
{
$test = new TestWithDispatcher();
$factory = function () use ($test) { return $test; };
$this->dispatcher->addListener('foo', array($factory, 'foo'));
$this->assertTrue($this->dispatcher->hasListeners('foo'));
$this->dispatcher->removeListener('foo', array($test, 'foo'));
$this->assertFalse($this->dispatcher->hasListeners('foo'));
$this->dispatcher->addListener('foo', array($test, 'foo'));
$this->assertTrue($this->dispatcher->hasListeners('foo'));
$this->dispatcher->removeListener('foo', array($factory, 'foo'));
$this->assertFalse($this->dispatcher->hasListeners('foo'));
}
public function testPriorityFindsLazyListeners()
{
$test = new TestWithDispatcher();
$factory = function () use ($test) { return $test; };
$this->dispatcher->addListener('foo', array($factory, 'foo'), 3);
$this->assertSame(3, $this->dispatcher->getListenerPriority('foo', array($test, 'foo')));
$this->dispatcher->removeListener('foo', array($factory, 'foo'));
$this->dispatcher->addListener('foo', array($test, 'foo'), 5);
$this->assertSame(5, $this->dispatcher->getListenerPriority('foo', array($factory, 'foo')));
}
public function testGetLazyListeners()
{
$test = new TestWithDispatcher();
$factory = function () use ($test) { return $test; };
$this->dispatcher->addListener('foo', array($factory, 'foo'), 3);
$this->assertSame(array(array($test, 'foo')), $this->dispatcher->getListeners('foo'));
$this->dispatcher->removeListener('foo', array($test, 'foo'));
$this->dispatcher->addListener('bar', array($factory, 'foo'), 3);
$this->assertSame(array('bar' => array(array($test, 'foo'))), $this->dispatcher->getListeners());
}
} }
class CallableClass class CallableClass

View file

@ -12,11 +12,13 @@
namespace Symfony\Component\EventDispatcher\Tests; namespace Symfony\Component\EventDispatcher\Tests;
use Symfony\Component\DependencyInjection\Container; use Symfony\Component\DependencyInjection\Container;
use Symfony\Component\DependencyInjection\Scope;
use Symfony\Component\EventDispatcher\ContainerAwareEventDispatcher; use Symfony\Component\EventDispatcher\ContainerAwareEventDispatcher;
use Symfony\Component\EventDispatcher\Event; use Symfony\Component\EventDispatcher\Event;
use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\EventDispatcher\EventSubscriberInterface;
/**
* @group legacy
*/
class ContainerAwareEventDispatcherTest extends AbstractEventDispatcherTest class ContainerAwareEventDispatcherTest extends AbstractEventDispatcherTest
{ {
protected function createEventDispatcher() protected function createEventDispatcher()
@ -30,7 +32,7 @@ class ContainerAwareEventDispatcherTest extends AbstractEventDispatcherTest
{ {
$event = new Event(); $event = new Event();
$service = $this->getMock('Symfony\Component\EventDispatcher\Tests\Service'); $service = $this->getMockBuilder('Symfony\Component\EventDispatcher\Tests\Service')->getMock();
$service $service
->expects($this->once()) ->expects($this->once())
@ -51,7 +53,7 @@ class ContainerAwareEventDispatcherTest extends AbstractEventDispatcherTest
{ {
$event = new Event(); $event = new Event();
$service = $this->getMock('Symfony\Component\EventDispatcher\Tests\SubscriberService'); $service = $this->getMockBuilder('Symfony\Component\EventDispatcher\Tests\SubscriberService')->getMock();
$service $service
->expects($this->once()) ->expects($this->once())
@ -59,6 +61,18 @@ class ContainerAwareEventDispatcherTest extends AbstractEventDispatcherTest
->with($event) ->with($event)
; ;
$service
->expects($this->once())
->method('onEventWithPriority')
->with($event)
;
$service
->expects($this->once())
->method('onEventNested')
->with($event)
;
$container = new Container(); $container = new Container();
$container->set('service.subscriber', $service); $container->set('service.subscriber', $service);
@ -66,13 +80,15 @@ class ContainerAwareEventDispatcherTest extends AbstractEventDispatcherTest
$dispatcher->addSubscriberService('service.subscriber', 'Symfony\Component\EventDispatcher\Tests\SubscriberService'); $dispatcher->addSubscriberService('service.subscriber', 'Symfony\Component\EventDispatcher\Tests\SubscriberService');
$dispatcher->dispatch('onEvent', $event); $dispatcher->dispatch('onEvent', $event);
$dispatcher->dispatch('onEventWithPriority', $event);
$dispatcher->dispatch('onEventNested', $event);
} }
public function testPreventDuplicateListenerService() public function testPreventDuplicateListenerService()
{ {
$event = new Event(); $event = new Event();
$service = $this->getMock('Symfony\Component\EventDispatcher\Tests\Service'); $service = $this->getMockBuilder('Symfony\Component\EventDispatcher\Tests\Service')->getMock();
$service $service
->expects($this->once()) ->expects($this->once())
@ -90,73 +106,11 @@ class ContainerAwareEventDispatcherTest extends AbstractEventDispatcherTest
$dispatcher->dispatch('onEvent', $event); $dispatcher->dispatch('onEvent', $event);
} }
/**
* @expectedException \InvalidArgumentException
*/
public function testTriggerAListenerServiceOutOfScope()
{
$service = $this->getMock('Symfony\Component\EventDispatcher\Tests\Service');
$scope = new Scope('scope');
$container = new Container();
$container->addScope($scope);
$container->enterScope('scope');
$container->set('service.listener', $service, 'scope');
$dispatcher = new ContainerAwareEventDispatcher($container);
$dispatcher->addListenerService('onEvent', array('service.listener', 'onEvent'));
$container->leaveScope('scope');
$dispatcher->dispatch('onEvent');
}
public function testReEnteringAScope()
{
$event = new Event();
$service1 = $this->getMock('Symfony\Component\EventDispatcher\Tests\Service');
$service1
->expects($this->exactly(2))
->method('onEvent')
->with($event)
;
$scope = new Scope('scope');
$container = new Container();
$container->addScope($scope);
$container->enterScope('scope');
$container->set('service.listener', $service1, 'scope');
$dispatcher = new ContainerAwareEventDispatcher($container);
$dispatcher->addListenerService('onEvent', array('service.listener', 'onEvent'));
$dispatcher->dispatch('onEvent', $event);
$service2 = $this->getMock('Symfony\Component\EventDispatcher\Tests\Service');
$service2
->expects($this->once())
->method('onEvent')
->with($event)
;
$container->enterScope('scope');
$container->set('service.listener', $service2, 'scope');
$dispatcher->dispatch('onEvent', $event);
$container->leaveScope('scope');
$dispatcher->dispatch('onEvent');
}
public function testHasListenersOnLazyLoad() public function testHasListenersOnLazyLoad()
{ {
$event = new Event(); $event = new Event();
$service = $this->getMock('Symfony\Component\EventDispatcher\Tests\Service'); $service = $this->getMockBuilder('Symfony\Component\EventDispatcher\Tests\Service')->getMock();
$container = new Container(); $container = new Container();
$container->set('service.listener', $service); $container->set('service.listener', $service);
@ -164,9 +118,6 @@ class ContainerAwareEventDispatcherTest extends AbstractEventDispatcherTest
$dispatcher = new ContainerAwareEventDispatcher($container); $dispatcher = new ContainerAwareEventDispatcher($container);
$dispatcher->addListenerService('onEvent', array('service.listener', 'onEvent')); $dispatcher->addListenerService('onEvent', array('service.listener', 'onEvent'));
$event->setDispatcher($dispatcher);
$event->setName('onEvent');
$service $service
->expects($this->once()) ->expects($this->once())
->method('onEvent') ->method('onEvent')
@ -182,7 +133,7 @@ class ContainerAwareEventDispatcherTest extends AbstractEventDispatcherTest
public function testGetListenersOnLazyLoad() public function testGetListenersOnLazyLoad()
{ {
$service = $this->getMock('Symfony\Component\EventDispatcher\Tests\Service'); $service = $this->getMockBuilder('Symfony\Component\EventDispatcher\Tests\Service')->getMock();
$container = new Container(); $container = new Container();
$container->set('service.listener', $service); $container->set('service.listener', $service);
@ -199,7 +150,7 @@ class ContainerAwareEventDispatcherTest extends AbstractEventDispatcherTest
public function testRemoveAfterDispatch() public function testRemoveAfterDispatch()
{ {
$service = $this->getMock('Symfony\Component\EventDispatcher\Tests\Service'); $service = $this->getMockBuilder('Symfony\Component\EventDispatcher\Tests\Service')->getMock();
$container = new Container(); $container = new Container();
$container->set('service.listener', $service); $container->set('service.listener', $service);
@ -214,7 +165,7 @@ class ContainerAwareEventDispatcherTest extends AbstractEventDispatcherTest
public function testRemoveBeforeDispatch() public function testRemoveBeforeDispatch()
{ {
$service = $this->getMock('Symfony\Component\EventDispatcher\Tests\Service'); $service = $this->getMockBuilder('Symfony\Component\EventDispatcher\Tests\Service')->getMock();
$container = new Container(); $container = new Container();
$container->set('service.listener', $service); $container->set('service.listener', $service);
@ -239,11 +190,21 @@ class SubscriberService implements EventSubscriberInterface
public static function getSubscribedEvents() public static function getSubscribedEvents()
{ {
return array( return array(
'onEvent' => array('onEvent'), 'onEvent' => 'onEvent',
'onEventWithPriority' => array('onEventWithPriority', 10),
'onEventNested' => array(array('onEventNested')),
); );
} }
public function onEvent(Event $e) public function onEvent(Event $e)
{ {
} }
public function onEventWithPriority(Event $e)
{
}
public function onEventNested(Event $e)
{
}
} }

View file

@ -11,20 +11,22 @@
namespace Symfony\Component\EventDispatcher\Tests\Debug; namespace Symfony\Component\EventDispatcher\Tests\Debug;
use PHPUnit\Framework\TestCase;
use Symfony\Component\EventDispatcher\Debug\TraceableEventDispatcher; use Symfony\Component\EventDispatcher\Debug\TraceableEventDispatcher;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\EventDispatcher\EventDispatcher; use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\EventDispatcher\Event; use Symfony\Component\EventDispatcher\Event;
use Symfony\Component\Stopwatch\Stopwatch; use Symfony\Component\Stopwatch\Stopwatch;
class TraceableEventDispatcherTest extends \PHPUnit_Framework_TestCase class TraceableEventDispatcherTest extends TestCase
{ {
public function testAddRemoveListener() public function testAddRemoveListener()
{ {
$dispatcher = new EventDispatcher(); $dispatcher = new EventDispatcher();
$tdispatcher = new TraceableEventDispatcher($dispatcher, new Stopwatch()); $tdispatcher = new TraceableEventDispatcher($dispatcher, new Stopwatch());
$tdispatcher->addListener('foo', $listener = function () {; }); $tdispatcher->addListener('foo', $listener = function () {});
$listeners = $dispatcher->getListeners('foo'); $listeners = $dispatcher->getListeners('foo');
$this->assertCount(1, $listeners); $this->assertCount(1, $listeners);
$this->assertSame($listener, $listeners[0]); $this->assertSame($listener, $listeners[0]);
@ -38,7 +40,7 @@ class TraceableEventDispatcherTest extends \PHPUnit_Framework_TestCase
$dispatcher = new EventDispatcher(); $dispatcher = new EventDispatcher();
$tdispatcher = new TraceableEventDispatcher($dispatcher, new Stopwatch()); $tdispatcher = new TraceableEventDispatcher($dispatcher, new Stopwatch());
$tdispatcher->addListener('foo', $listener = function () {; }); $tdispatcher->addListener('foo', $listener = function () {});
$this->assertSame($dispatcher->getListeners('foo'), $tdispatcher->getListeners('foo')); $this->assertSame($dispatcher->getListeners('foo'), $tdispatcher->getListeners('foo'));
} }
@ -50,11 +52,42 @@ class TraceableEventDispatcherTest extends \PHPUnit_Framework_TestCase
$this->assertFalse($dispatcher->hasListeners('foo')); $this->assertFalse($dispatcher->hasListeners('foo'));
$this->assertFalse($tdispatcher->hasListeners('foo')); $this->assertFalse($tdispatcher->hasListeners('foo'));
$tdispatcher->addListener('foo', $listener = function () {; }); $tdispatcher->addListener('foo', $listener = function () {});
$this->assertTrue($dispatcher->hasListeners('foo')); $this->assertTrue($dispatcher->hasListeners('foo'));
$this->assertTrue($tdispatcher->hasListeners('foo')); $this->assertTrue($tdispatcher->hasListeners('foo'));
} }
public function testGetListenerPriority()
{
$dispatcher = new EventDispatcher();
$tdispatcher = new TraceableEventDispatcher($dispatcher, new Stopwatch());
$tdispatcher->addListener('foo', function () {}, 123);
$listeners = $dispatcher->getListeners('foo');
$this->assertSame(123, $tdispatcher->getListenerPriority('foo', $listeners[0]));
// Verify that priority is preserved when listener is removed and re-added
// in preProcess() and postProcess().
$tdispatcher->dispatch('foo', new Event());
$listeners = $dispatcher->getListeners('foo');
$this->assertSame(123, $tdispatcher->getListenerPriority('foo', $listeners[0]));
}
public function testGetListenerPriorityWhileDispatching()
{
$tdispatcher = new TraceableEventDispatcher(new EventDispatcher(), new Stopwatch());
$priorityWhileDispatching = null;
$listener = function () use ($tdispatcher, &$priorityWhileDispatching, &$listener) {
$priorityWhileDispatching = $tdispatcher->getListenerPriority('bar', $listener);
};
$tdispatcher->addListener('bar', $listener, 5);
$tdispatcher->dispatch('bar');
$this->assertSame(5, $priorityWhileDispatching);
}
public function testAddRemoveSubscriber() public function testAddRemoveSubscriber()
{ {
$dispatcher = new EventDispatcher(); $dispatcher = new EventDispatcher();
@ -73,16 +106,21 @@ class TraceableEventDispatcherTest extends \PHPUnit_Framework_TestCase
public function testGetCalledListeners() public function testGetCalledListeners()
{ {
$dispatcher = new EventDispatcher(); $tdispatcher = new TraceableEventDispatcher(new EventDispatcher(), new Stopwatch());
$tdispatcher = new TraceableEventDispatcher($dispatcher, new Stopwatch()); $tdispatcher->addListener('foo', function () {}, 5);
$tdispatcher->addListener('foo', $listener = function () {; });
$listeners = $tdispatcher->getNotCalledListeners();
$this->assertArrayHasKey('stub', $listeners['foo.closure']);
unset($listeners['foo.closure']['stub']);
$this->assertEquals(array(), $tdispatcher->getCalledListeners()); $this->assertEquals(array(), $tdispatcher->getCalledListeners());
$this->assertEquals(array('foo.closure' => array('event' => 'foo', 'type' => 'Closure', 'pretty' => 'closure')), $tdispatcher->getNotCalledListeners()); $this->assertEquals(array('foo.closure' => array('event' => 'foo', 'pretty' => 'closure', 'priority' => 5)), $listeners);
$tdispatcher->dispatch('foo'); $tdispatcher->dispatch('foo');
$this->assertEquals(array('foo.closure' => array('event' => 'foo', 'type' => 'Closure', 'pretty' => 'closure')), $tdispatcher->getCalledListeners()); $listeners = $tdispatcher->getCalledListeners();
$this->assertArrayHasKey('stub', $listeners['foo.closure']);
unset($listeners['foo.closure']['stub']);
$this->assertEquals(array('foo.closure' => array('event' => 'foo', 'pretty' => 'closure', 'priority' => 5)), $listeners);
$this->assertEquals(array(), $tdispatcher->getNotCalledListeners()); $this->assertEquals(array(), $tdispatcher->getNotCalledListeners());
} }
@ -102,31 +140,31 @@ class TraceableEventDispatcherTest extends \PHPUnit_Framework_TestCase
public function testLogger() public function testLogger()
{ {
$logger = $this->getMock('Psr\Log\LoggerInterface'); $logger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock();
$dispatcher = new EventDispatcher(); $dispatcher = new EventDispatcher();
$tdispatcher = new TraceableEventDispatcher($dispatcher, new Stopwatch(), $logger); $tdispatcher = new TraceableEventDispatcher($dispatcher, new Stopwatch(), $logger);
$tdispatcher->addListener('foo', $listener1 = function () {; }); $tdispatcher->addListener('foo', $listener1 = function () {});
$tdispatcher->addListener('foo', $listener2 = function () {; }); $tdispatcher->addListener('foo', $listener2 = function () {});
$logger->expects($this->at(0))->method('debug')->with("Notified event \"foo\" to listener \"closure\"."); $logger->expects($this->at(0))->method('debug')->with('Notified event "{event}" to listener "{listener}".', array('event' => 'foo', 'listener' => 'closure'));
$logger->expects($this->at(1))->method('debug')->with("Notified event \"foo\" to listener \"closure\"."); $logger->expects($this->at(1))->method('debug')->with('Notified event "{event}" to listener "{listener}".', array('event' => 'foo', 'listener' => 'closure'));
$tdispatcher->dispatch('foo'); $tdispatcher->dispatch('foo');
} }
public function testLoggerWithStoppedEvent() public function testLoggerWithStoppedEvent()
{ {
$logger = $this->getMock('Psr\Log\LoggerInterface'); $logger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock();
$dispatcher = new EventDispatcher(); $dispatcher = new EventDispatcher();
$tdispatcher = new TraceableEventDispatcher($dispatcher, new Stopwatch(), $logger); $tdispatcher = new TraceableEventDispatcher($dispatcher, new Stopwatch(), $logger);
$tdispatcher->addListener('foo', $listener1 = function (Event $event) { $event->stopPropagation(); }); $tdispatcher->addListener('foo', $listener1 = function (Event $event) { $event->stopPropagation(); });
$tdispatcher->addListener('foo', $listener2 = function () {; }); $tdispatcher->addListener('foo', $listener2 = function () {});
$logger->expects($this->at(0))->method('debug')->with("Notified event \"foo\" to listener \"closure\"."); $logger->expects($this->at(0))->method('debug')->with('Notified event "{event}" to listener "{listener}".', array('event' => 'foo', 'listener' => 'closure'));
$logger->expects($this->at(1))->method('debug')->with("Listener \"closure\" stopped propagation of the event \"foo\"."); $logger->expects($this->at(1))->method('debug')->with('Listener "{listener}" stopped propagation of the event "{event}".', array('event' => 'foo', 'listener' => 'closure'));
$logger->expects($this->at(2))->method('debug')->with("Listener \"closure\" was not called for event \"foo\"."); $logger->expects($this->at(2))->method('debug')->with('Listener "{listener}" was not called for event "{event}".', array('event' => 'foo', 'listener' => 'closure'));
$tdispatcher->dispatch('foo'); $tdispatcher->dispatch('foo');
} }
@ -137,26 +175,32 @@ class TraceableEventDispatcherTest extends \PHPUnit_Framework_TestCase
$dispatcher = new EventDispatcher(); $dispatcher = new EventDispatcher();
$tdispatcher = new TraceableEventDispatcher($dispatcher, new Stopwatch()); $tdispatcher = new TraceableEventDispatcher($dispatcher, new Stopwatch());
$tdispatcher->addListener('foo', $listener1 = function () use (&$called) { $called[] = 'foo1'; }); $tdispatcher->addListener('foo', function () use (&$called) { $called[] = 'foo1'; }, 10);
$tdispatcher->addListener('foo', $listener2 = function () use (&$called) { $called[] = 'foo2'; }); $tdispatcher->addListener('foo', function () use (&$called) { $called[] = 'foo2'; }, 20);
$tdispatcher->dispatch('foo'); $tdispatcher->dispatch('foo');
$this->assertEquals(array('foo1', 'foo2'), $called); $this->assertSame(array('foo2', 'foo1'), $called);
} }
public function testDispatchNested() public function testDispatchNested()
{ {
$dispatcher = new TraceableEventDispatcher(new EventDispatcher(), new Stopwatch()); $dispatcher = new TraceableEventDispatcher(new EventDispatcher(), new Stopwatch());
$loop = 1; $loop = 1;
$dispatchedEvents = 0;
$dispatcher->addListener('foo', $listener1 = function () use ($dispatcher, &$loop) { $dispatcher->addListener('foo', $listener1 = function () use ($dispatcher, &$loop) {
++$loop; ++$loop;
if (2 == $loop) { if (2 == $loop) {
$dispatcher->dispatch('foo'); $dispatcher->dispatch('foo');
} }
}); });
$dispatcher->addListener('foo', function () use (&$dispatchedEvents) {
++$dispatchedEvents;
});
$dispatcher->dispatch('foo'); $dispatcher->dispatch('foo');
$this->assertSame(2, $dispatchedEvents);
} }
public function testDispatchReusedEventNested() public function testDispatchReusedEventNested()
@ -174,6 +218,19 @@ class TraceableEventDispatcherTest extends \PHPUnit_Framework_TestCase
$dispatcher->dispatch('foo'); $dispatcher->dispatch('foo');
$this->assertTrue($nestedCall); $this->assertTrue($nestedCall);
} }
public function testListenerCanRemoveItselfWhenExecuted()
{
$eventDispatcher = new TraceableEventDispatcher(new EventDispatcher(), new Stopwatch());
$listener1 = function ($event, $eventName, EventDispatcherInterface $dispatcher) use (&$listener1) {
$dispatcher->removeListener('foo', $listener1);
};
$eventDispatcher->addListener('foo', $listener1);
$eventDispatcher->addListener('foo', function () {});
$eventDispatcher->dispatch('foo');
$this->assertCount(1, $eventDispatcher->getListeners('foo'), 'expected listener1 to be removed');
}
} }
class EventSubscriber implements EventSubscriberInterface class EventSubscriber implements EventSubscriberInterface

View file

@ -11,10 +11,13 @@
namespace Symfony\Component\EventDispatcher\Tests\DependencyInjection; namespace Symfony\Component\EventDispatcher\Tests\DependencyInjection;
use PHPUnit\Framework\TestCase;
use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument;
use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\EventDispatcher\DependencyInjection\RegisterListenersPass; use Symfony\Component\EventDispatcher\DependencyInjection\RegisterListenersPass;
class RegisterListenersPassTest extends \PHPUnit_Framework_TestCase class RegisterListenersPassTest extends TestCase
{ {
/** /**
* Tests that event subscribers not implementing EventSubscriberInterface * Tests that event subscribers not implementing EventSubscriberInterface
@ -29,18 +32,12 @@ class RegisterListenersPassTest extends \PHPUnit_Framework_TestCase
'my_event_subscriber' => array(0 => array()), 'my_event_subscriber' => array(0 => array()),
); );
$definition = $this->getMock('Symfony\Component\DependencyInjection\Definition'); $definition = $this->getMockBuilder('Symfony\Component\DependencyInjection\Definition')->getMock();
$definition->expects($this->atLeastOnce())
->method('isPublic')
->will($this->returnValue(true));
$definition->expects($this->atLeastOnce()) $definition->expects($this->atLeastOnce())
->method('getClass') ->method('getClass')
->will($this->returnValue('stdClass')); ->will($this->returnValue('stdClass'));
$builder = $this->getMock( $builder = $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerBuilder')->setMethods(array('hasDefinition', 'findTaggedServiceIds', 'getDefinition'))->getMock();
'Symfony\Component\DependencyInjection\ContainerBuilder',
array('hasDefinition', 'findTaggedServiceIds', 'getDefinition')
);
$builder->expects($this->any()) $builder->expects($this->any())
->method('hasDefinition') ->method('hasDefinition')
->will($this->returnValue(true)); ->will($this->returnValue(true));
@ -64,18 +61,12 @@ class RegisterListenersPassTest extends \PHPUnit_Framework_TestCase
'my_event_subscriber' => array(0 => array()), 'my_event_subscriber' => array(0 => array()),
); );
$definition = $this->getMock('Symfony\Component\DependencyInjection\Definition'); $definition = $this->getMockBuilder('Symfony\Component\DependencyInjection\Definition')->getMock();
$definition->expects($this->atLeastOnce())
->method('isPublic')
->will($this->returnValue(true));
$definition->expects($this->atLeastOnce()) $definition->expects($this->atLeastOnce())
->method('getClass') ->method('getClass')
->will($this->returnValue('Symfony\Component\EventDispatcher\Tests\DependencyInjection\SubscriberService')); ->will($this->returnValue('Symfony\Component\EventDispatcher\Tests\DependencyInjection\SubscriberService'));
$builder = $this->getMock( $builder = $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerBuilder')->setMethods(array('hasDefinition', 'findTaggedServiceIds', 'getDefinition', 'findDefinition'))->getMock();
'Symfony\Component\DependencyInjection\ContainerBuilder',
array('hasDefinition', 'findTaggedServiceIds', 'getDefinition', 'findDefinition')
);
$builder->expects($this->any()) $builder->expects($this->any())
->method('hasDefinition') ->method('hasDefinition')
->will($this->returnValue(true)); ->will($this->returnValue(true));
@ -99,35 +90,7 @@ class RegisterListenersPassTest extends \PHPUnit_Framework_TestCase
/** /**
* @expectedException \InvalidArgumentException * @expectedException \InvalidArgumentException
* @expectedExceptionMessage The service "foo" must be public as event listeners are lazy-loaded. * @expectedExceptionMessage The service "foo" tagged "kernel.event_listener" must not be abstract.
*/
public function testPrivateEventListener()
{
$container = new ContainerBuilder();
$container->register('foo', 'stdClass')->setPublic(false)->addTag('kernel.event_listener', array());
$container->register('event_dispatcher', 'stdClass');
$registerListenersPass = new RegisterListenersPass();
$registerListenersPass->process($container);
}
/**
* @expectedException \InvalidArgumentException
* @expectedExceptionMessage The service "foo" must be public as event subscribers are lazy-loaded.
*/
public function testPrivateEventSubscriber()
{
$container = new ContainerBuilder();
$container->register('foo', 'stdClass')->setPublic(false)->addTag('kernel.event_subscriber', array());
$container->register('event_dispatcher', 'stdClass');
$registerListenersPass = new RegisterListenersPass();
$registerListenersPass->process($container);
}
/**
* @expectedException \InvalidArgumentException
* @expectedExceptionMessage The service "foo" must not be abstract as event listeners are lazy-loaded.
*/ */
public function testAbstractEventListener() public function testAbstractEventListener()
{ {
@ -141,7 +104,7 @@ class RegisterListenersPassTest extends \PHPUnit_Framework_TestCase
/** /**
* @expectedException \InvalidArgumentException * @expectedException \InvalidArgumentException
* @expectedExceptionMessage The service "foo" must not be abstract as event subscribers are lazy-loaded. * @expectedExceptionMessage The service "foo" tagged "kernel.event_subscriber" must not be abstract.
*/ */
public function testAbstractEventSubscriber() public function testAbstractEventSubscriber()
{ {
@ -165,16 +128,17 @@ class RegisterListenersPassTest extends \PHPUnit_Framework_TestCase
$registerListenersPass->process($container); $registerListenersPass->process($container);
$definition = $container->getDefinition('event_dispatcher'); $definition = $container->getDefinition('event_dispatcher');
$expected_calls = array( $expectedCalls = array(
array( array(
'addSubscriberService', 'addListener',
array( array(
'foo', 'event',
'Symfony\Component\EventDispatcher\Tests\DependencyInjection\SubscriberService', array(new ServiceClosureArgument(new Reference('foo')), 'onEvent'),
0,
), ),
), ),
); );
$this->assertSame($expected_calls, $definition->getMethodCalls()); $this->assertEquals($expectedCalls, $definition->getMethodCalls());
} }
/** /**
@ -196,5 +160,8 @@ class SubscriberService implements \Symfony\Component\EventDispatcher\EventSubsc
{ {
public static function getSubscribedEvents() public static function getSubscribedEvents()
{ {
return array(
'event' => 'onEvent',
);
} }
} }

View file

@ -0,0 +1,55 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\EventDispatcher\Tests;
use PHPUnit\Framework\TestCase;
use Symfony\Component\EventDispatcher\Event;
/**
* Test class for Event.
*/
class EventTest extends TestCase
{
/**
* @var \Symfony\Component\EventDispatcher\Event
*/
protected $event;
/**
* Sets up the fixture, for example, opens a network connection.
* This method is called before a test is executed.
*/
protected function setUp()
{
$this->event = new Event();
}
/**
* Tears down the fixture, for example, closes a network connection.
* This method is called after a test is executed.
*/
protected function tearDown()
{
$this->event = null;
}
public function testIsPropagationStopped()
{
$this->assertFalse($this->event->isPropagationStopped());
}
public function testStopPropagationAndIsPropagationStopped()
{
$this->event->stopPropagation();
$this->assertTrue($this->event->isPropagationStopped());
}
}

View file

@ -11,12 +11,13 @@
namespace Symfony\Component\EventDispatcher\Tests; namespace Symfony\Component\EventDispatcher\Tests;
use PHPUnit\Framework\TestCase;
use Symfony\Component\EventDispatcher\GenericEvent; use Symfony\Component\EventDispatcher\GenericEvent;
/** /**
* Test class for Event. * Test class for Event.
*/ */
class GenericEventTest extends \PHPUnit_Framework_TestCase class GenericEventTest extends TestCase
{ {
/** /**
* @var GenericEvent * @var GenericEvent
@ -95,7 +96,7 @@ class GenericEventTest extends \PHPUnit_Framework_TestCase
$this->assertEquals('Event', $this->event['name']); $this->assertEquals('Event', $this->event['name']);
// test getting invalid arg // test getting invalid arg
$this->setExpectedException('InvalidArgumentException'); $this->{method_exists($this, $_ = 'expectException') ? $_ : 'setExpectedException'}('InvalidArgumentException');
$this->assertFalse($this->event['nameNotExist']); $this->assertFalse($this->event['nameNotExist']);
} }

View file

@ -11,13 +11,14 @@
namespace Symfony\Component\EventDispatcher\Tests; namespace Symfony\Component\EventDispatcher\Tests;
use PHPUnit\Framework\TestCase;
use Symfony\Component\EventDispatcher\Event; use Symfony\Component\EventDispatcher\Event;
use Symfony\Component\EventDispatcher\ImmutableEventDispatcher; use Symfony\Component\EventDispatcher\ImmutableEventDispatcher;
/** /**
* @author Bernhard Schussek <bschussek@gmail.com> * @author Bernhard Schussek <bschussek@gmail.com>
*/ */
class ImmutableEventDispatcherTest extends \PHPUnit_Framework_TestCase class ImmutableEventDispatcherTest extends TestCase
{ {
/** /**
* @var \PHPUnit_Framework_MockObject_MockObject * @var \PHPUnit_Framework_MockObject_MockObject
@ -31,7 +32,7 @@ class ImmutableEventDispatcherTest extends \PHPUnit_Framework_TestCase
protected function setUp() protected function setUp()
{ {
$this->innerDispatcher = $this->getMock('Symfony\Component\EventDispatcher\EventDispatcherInterface'); $this->innerDispatcher = $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcherInterface')->getMock();
$this->dispatcher = new ImmutableEventDispatcher($this->innerDispatcher); $this->dispatcher = new ImmutableEventDispatcher($this->innerDispatcher);
} }
@ -80,7 +81,7 @@ class ImmutableEventDispatcherTest extends \PHPUnit_Framework_TestCase
*/ */
public function testAddSubscriberDisallowed() public function testAddSubscriberDisallowed()
{ {
$subscriber = $this->getMock('Symfony\Component\EventDispatcher\EventSubscriberInterface'); $subscriber = $this->getMockBuilder('Symfony\Component\EventDispatcher\EventSubscriberInterface')->getMock();
$this->dispatcher->addSubscriber($subscriber); $this->dispatcher->addSubscriber($subscriber);
} }
@ -98,7 +99,7 @@ class ImmutableEventDispatcherTest extends \PHPUnit_Framework_TestCase
*/ */
public function testRemoveSubscriberDisallowed() public function testRemoveSubscriberDisallowed()
{ {
$subscriber = $this->getMock('Symfony\Component\EventDispatcher\EventSubscriberInterface'); $subscriber = $this->getMockBuilder('Symfony\Component\EventDispatcher\EventSubscriberInterface')->getMock();
$this->dispatcher->removeSubscriber($subscriber); $this->dispatcher->removeSubscriber($subscriber);
} }

View file

@ -3,7 +3,7 @@
"type": "library", "type": "library",
"description": "Symfony EventDispatcher Component", "description": "Symfony EventDispatcher Component",
"keywords": [], "keywords": [],
"homepage": "http://symfony.com", "homepage": "https://symfony.com",
"license": "MIT", "license": "MIT",
"authors": [ "authors": [
{ {
@ -12,32 +12,36 @@
}, },
{ {
"name": "Symfony Community", "name": "Symfony Community",
"homepage": "http://symfony.com/contributors" "homepage": "https://symfony.com/contributors"
} }
], ],
"require": { "require": {
"php": ">=5.3.3" "php": ">=5.5.9"
}, },
"require-dev": { "require-dev": {
"symfony/phpunit-bridge": "~2.7", "symfony/dependency-injection": "~3.3",
"symfony/dependency-injection": "~2.6", "symfony/expression-language": "~2.8|~3.0",
"symfony/expression-language": "~2.6", "symfony/config": "~2.8|~3.0",
"symfony/config": "~2.0,>=2.0.5", "symfony/stopwatch": "~2.8|~3.0",
"symfony/stopwatch": "~2.3",
"psr/log": "~1.0" "psr/log": "~1.0"
}, },
"conflict": {
"symfony/dependency-injection": "<3.3"
},
"suggest": { "suggest": {
"symfony/dependency-injection": "", "symfony/dependency-injection": "",
"symfony/http-kernel": "" "symfony/http-kernel": ""
}, },
"autoload": { "autoload": {
"psr-0": { "Symfony\\Component\\EventDispatcher\\": "" } "psr-4": { "Symfony\\Component\\EventDispatcher\\": "" },
"exclude-from-classmap": [
"/Tests/"
]
}, },
"target-dir": "Symfony/Component/EventDispatcher",
"minimum-stability": "dev", "minimum-stability": "dev",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-master": "2.6-dev" "dev-master": "3.3-dev"
} }
} }
} }

View file

@ -5,10 +5,13 @@
backupGlobals="false" backupGlobals="false"
colors="true" colors="true"
bootstrap="vendor/autoload.php" bootstrap="vendor/autoload.php"
failOnRisky="true"
failOnWarning="true"
> >
<php> <php>
<ini name="error_reporting" value="-1" /> <ini name="error_reporting" value="-1" />
</php> </php>
<testsuites> <testsuites>
<testsuite name="Symfony EventDispatcher Component Test Suite"> <testsuite name="Symfony EventDispatcher Component Test Suite">
<directory>./Tests/</directory> <directory>./Tests/</directory>