From 36781411c95f794b2ff52ce33563df2e8e0b8ace Mon Sep 17 00:00:00 2001 From: Tim Otten Date: Fri, 24 Jul 2015 20:40:14 -0700 Subject: [PATCH] Civi\Core\Resolver - Add "global://" support --- Civi/Core/Resolver.php | 40 ++++++++++++++++++++++++ tests/phpunit/Civi/Core/ResolverTest.php | 19 +++++++++++ 2 files changed, 59 insertions(+) diff --git a/Civi/Core/Resolver.php b/Civi/Core/Resolver.php index d35b512f5d..d76b512164 100644 --- a/Civi/Core/Resolver.php +++ b/Civi/Core/Resolver.php @@ -19,6 +19,8 @@ namespace Civi\Core; * - 'api3://EntityName/action?first=@1&second=@2' - Call an API method, mapping the * first & second args to named parameters. * (Performance note: Requires parsing/interpolating arguments). + * - 'global://Variable/Key2/Key3?getter' - A dummy which looks up a global variable. + * - 'global://Variable/Key2/Key3?setter' - A dummy which updates a global variable. * - '0' or '1' - A dummy which returns the constant '0' or '1'. * * Note: To differentiate classes and functions, there is a hard requirement that @@ -81,6 +83,10 @@ class Resolver { // Callback: API. return new ResolverApi($url); + case 'global': + // Lookup in a global variable. + return new ResolverGlobalCallback($url['query'], $url['host'] . (isset($url['path']) ? rtrim($url['path'], '/') : '')); + default: throw new \RuntimeException("Unsupported callback scheme: " . $url['scheme']); } @@ -242,3 +248,37 @@ class ResolverApi { } } + +class ResolverGlobalCallback { + private $mode, $path; + + /** + * Class constructor. + * + * @param string $mode + * 'getter' or 'setter'. + * @param string $path + */ + public function __construct($mode, $path) { + $this->mode = $mode; + $this->path = $path; + } + + /** + * Invoke function. + * + * @return mixed + */ + public function __invoke($arg1 = NULL) { + if ($this->mode === 'getter') { + return \CRM_Utils_Array::pathGet($GLOBALS, explode('/', $this->path)); + } + elseif ($this->mode === 'setter') { + \CRM_Utils_Array::pathSet($GLOBALS, explode('/', $this->path), $arg1); + } + else { + throw new \RuntimeException("Resolver failed: global:// must specify getter or setter mode."); + } + } + +} diff --git a/tests/phpunit/Civi/Core/ResolverTest.php b/tests/phpunit/Civi/Core/ResolverTest.php index de5388fa72..2e63dfe04e 100644 --- a/tests/phpunit/Civi/Core/ResolverTest.php +++ b/tests/phpunit/Civi/Core/ResolverTest.php @@ -92,6 +92,25 @@ namespace Civi\Core { $this->resolver->get('call://totallyNonexistentService/ping'); } + /** + * Test callback which returns a global variable. + */ + public function testGlobalGetter() { + $_GET['resolverTest'] = 123; + $cb = $this->resolver->get('global://_GET/resolverTest?getter'); + $_GET['resolverTest'] = 456; + $this->assertEquals(456, call_user_func($cb, 'side-effect-free')); + $this->assertEquals(456, $_GET['resolverTest']); + unset($_GET['resolverTest']); + } + + public function testGlobalSetter() { + $GLOBALS['resolverTest2'] = 78; + $cb = $this->resolver->get('global://resolverTest2?setter'); + call_user_func($cb, 90); + $this->assertEquals(90, $GLOBALS['resolverTest2']); + } + /** * Test object-lookup in the container. */ -- 2.25.1