diff --git a/lib/moodlelib.php b/lib/moodlelib.php index 2e921e7c7d6..aadcb330a3c 100644 --- a/lib/moodlelib.php +++ b/lib/moodlelib.php @@ -10149,3 +10149,22 @@ class lang_string { return $this->component; } } + +/** + * Get human readable name describing the given callable. + * + * This performs syntax check only to see if the given param looks like a valid function, method or closure. + * It does not check if the callable actually exists. + * + * @param callable|string|array $callable + * @return string|bool Human readable name of callable, or false if not a valid callable. + */ +function get_callable_name($callable) { + + if (!is_callable($callable, true, $name)) { + return false; + + } else { + return $name; + } +} diff --git a/lib/tests/moodlelib_test.php b/lib/tests/moodlelib_test.php index c429fb8f34d..163d795de10 100644 --- a/lib/tests/moodlelib_test.php +++ b/lib/tests/moodlelib_test.php @@ -4065,4 +4065,57 @@ class core_moodlelib_testcase extends advanced_testcase { ], ]; } + + /** + * Test that {@link get_callable_name()} describes the callable as expected. + * + * @dataProvider callable_names_provider + * @param callable $callable + * @param string $expectedname + */ + public function test_get_callable_name($callable, $expectedname) { + $this->assertSame($expectedname, get_callable_name($callable)); + } + + /** + * Provides a set of callables and their human readable names. + * + * @return array of (string)case => [(mixed)callable, (string|bool)expected description] + */ + public function callable_names_provider() { + return [ + 'integer' => [ + 386, + false, + ], + 'boolean' => [ + true, + false, + ], + 'static_method_as_literal' => [ + 'my_foobar_class::my_foobar_method', + 'my_foobar_class::my_foobar_method', + ], + 'static_method_of_literal_class' => [ + ['my_foobar_class', 'my_foobar_method'], + 'my_foobar_class::my_foobar_method', + ], + 'static_method_of_object' => [ + [$this, 'my_foobar_method'], + 'core_moodlelib_testcase::my_foobar_method', + ], + 'method_of_object' => [ + [new lang_string('parentlanguage', 'core_langconfig'), 'my_foobar_method'], + 'lang_string::my_foobar_method', + ], + 'function_as_literal' => [ + 'my_foobar_callback', + 'my_foobar_callback', + ], + 'function_as_closure' => [ + function($a) { return $a; }, + 'Closure::__invoke', + ], + ]; + } }