From 905d02f458e969cb77a7345425be2ab604a50d9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Mudr=C3=A1k?= Date: Tue, 10 Jul 2018 13:18:38 +0200 Subject: [PATCH 1/2] MDL-62891 core: Introduce new get_callable_name() function --- lib/moodlelib.php | 19 +++++++++++++ lib/tests/moodlelib_test.php | 53 ++++++++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+) 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', + ], + ]; + } } From 75ab4d2eb7bb2f0dd89026862719160c32b1c087 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Mudr=C3=A1k?= Date: Tue, 10 Jul 2018 13:26:44 +0200 Subject: [PATCH 2/2] MDL-62891 core: Stop using var_export() to describe callables Make use of the newly added function get_callable_name() when reporting that an exception happened during shutdown. --- lib/classes/shutdown_manager.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/classes/shutdown_manager.php b/lib/classes/shutdown_manager.php index 2a11ae2d090..b1c71ad7acc 100644 --- a/lib/classes/shutdown_manager.php +++ b/lib/classes/shutdown_manager.php @@ -80,10 +80,10 @@ class core_shutdown_manager { call_user_func_array($callback, $params); } } catch (Exception $e) { - error_log('Exception ignored in shutdown function '.var_export($callback, true).':'.$e->getMessage()); + error_log('Exception ignored in shutdown function '.get_callable_name($callback).': '.$e->getMessage()); } catch (Throwable $e) { // Engine errors in PHP7 throw exceptions of type Throwable (this "catch" will be ignored in PHP5). - error_log('Exception ignored in shutdown function '.var_export($callback, true).':'.$e->getMessage()); + error_log('Exception ignored in shutdown function '.get_callable_name($callback).': '.$e->getMessage()); } }