Fix Hook_Formatter::format to accept WP_Hook object as argument
This commit is contained in:
1 parent
a30722c751
commit
fad92f739c
2 files changed
+83
-35
No files matched your search
@@ -3,38 +3,56 @@ declare( strict_types=1 );
|
|||||||
|
|
||||||
namespace Rarst\Laps\Formatter;
|
namespace Rarst\Laps\Formatter;
|
||||||
|
|
||||||
|
use WP_Hook;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Formatter for WordPress hook callbacks.
|
* Formatter to process callbacks from a hook instance.
|
||||||
*/
|
*/
|
||||||
class Hook_Formatter {
|
class Hook_Formatter {
|
||||||
|
|
||||||
/** @var array $truncate_paths List of base paths to strip for readability. */
|
/** @var array $truncate_paths Paths to truncate from includes. */
|
||||||
protected $truncate_paths;
|
protected $truncate_paths = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set up truncate paths.
|
* Set up object properties.
|
||||||
*/
|
*/
|
||||||
public function __construct() {
|
public function __construct() {
|
||||||
|
|
||||||
$this->truncate_paths = array_filter( [
|
// TODO inject paths instead of reaching for global constants.
|
||||||
wp_normalize_path( ABSPATH ),
|
$this->truncate_paths = [
|
||||||
wp_normalize_path( WP_CONTENT_DIR ),
|
wp_normalize_path( WP_CONTENT_DIR ),
|
||||||
] );
|
wp_normalize_path( ABSPATH ),
|
||||||
|
'wp-admin/',
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert hook callbacks array to a list of readable names.
|
* @psalm-type Callback = string|object|array
|
||||||
|
* @psalm-type AcceptedArgs = int
|
||||||
|
* @psalm-type Hook = array{function: Callback, accepted_args: AcceptedArgs}
|
||||||
|
* @psalm-type Priority = array-key
|
||||||
|
* @psalm-type Hooks = array<Priority, array<Hook>>
|
||||||
*
|
*
|
||||||
* @param array $hook Array of callbacks, registered for the hook.
|
* @param WP_Hook|array $hook Hook instance or callbacks array.
|
||||||
|
* @psalm-param WP_Hook|Hooks $hook
|
||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function format( array $hook ): array {
|
public function format( $hook ): array {
|
||||||
|
|
||||||
|
$callbacks = [];
|
||||||
|
|
||||||
|
if ( $hook instanceof WP_Hook ) {
|
||||||
|
/** @psalm-var Hooks $hook->callbacks */
|
||||||
|
$hook = $hook->callbacks;
|
||||||
|
}
|
||||||
|
|
||||||
if ( empty( $hook ) ) {
|
if ( empty( $hook ) ) {
|
||||||
return [];
|
return $callbacks;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ksort( $hook );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Empty priorities produce empty arrays in PHP 7.2 and unpack operator doesn't accept empty array in 7.3.
|
* Empty priorities produce empty arrays in PHP 7.2 and unpack operator doesn't accept empty array in 7.3.
|
||||||
*
|
*
|
||||||
@@ -44,36 +62,48 @@ class Hook_Formatter {
|
|||||||
$hook = array_filter( $hook );
|
$hook = array_filter( $hook );
|
||||||
|
|
||||||
if ( empty( $hook ) ) {
|
if ( empty( $hook ) ) {
|
||||||
return [];
|
return $callbacks;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @var array $functions */
|
/** @psalm-suppress InvalidArgument */
|
||||||
$functions = array_merge( ...$hook );
|
$functions = array_merge( ...$hook );
|
||||||
|
|
||||||
return array_map( [ $this, 'format_callback' ], $functions );
|
/** @psalm-var Hook[] $functions */
|
||||||
|
foreach ( $functions as $function ) {
|
||||||
|
/** @psalm-var Hook $function */
|
||||||
|
$callback = $this->get_callback_name( $function['function'], $function['accepted_args'] );
|
||||||
|
|
||||||
|
if ( false !== strpos( $callback, 'Hook_Collector' ) ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$callbacks[] = $callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $callbacks;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert callback data array to a readable name.
|
* @param string|object|array $callback Hook callback.
|
||||||
*
|
* @param int $args Number of accepted arguments.
|
||||||
* @param array $callback_data Callback data, registered for the hook.
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
protected function format_callback( array $callback_data ): string {
|
protected function get_callback_name( $callback, int $args ): string {
|
||||||
|
|
||||||
$callback = $callback_data['function'];
|
switch ( gettype( $callback ) ) {
|
||||||
$args = $callback_data['accepted_args'];
|
case 'object':
|
||||||
|
|
||||||
if ( is_string( $callback ) ) {
|
|
||||||
$name = $callback;
|
|
||||||
} elseif ( is_array( $callback ) ) {
|
|
||||||
$class = is_object( $callback[0] ) ? $this->get_class_name( $callback[0] ) : $callback[0];
|
|
||||||
$name = $class . '::' . $callback[1];
|
|
||||||
} elseif ( is_object( $callback ) ) {
|
|
||||||
$name = $this->get_class_name( $callback );
|
$name = $this->get_class_name( $callback );
|
||||||
} else {
|
break;
|
||||||
$name = 'unknown';
|
|
||||||
|
case 'array':
|
||||||
|
/** @psalm-var array{0: object|string, 1: string} $callback */
|
||||||
|
$class = is_string( $callback[0] )
|
||||||
|
? $callback[0] . '::'
|
||||||
|
: $this->get_class_name( $callback[0] ) . '->';
|
||||||
|
$name = $class . $callback[1];
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
$name = $callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $name . ( ( 1 === $args ) ? '' : "({$args})" );
|
return $name . ( ( 1 === $args ) ? '' : "({$args})" );
|
||||||
@@ -118,14 +148,11 @@ class Hook_Formatter {
|
|||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
protected function shorten_path( string $path ): string {
|
protected function shorten_path( string $path ): string {
|
||||||
|
|
||||||
$path = wp_normalize_path( $path );
|
$path = wp_normalize_path( $path );
|
||||||
$path = str_replace( $this->truncate_paths, '', $path );
|
$path = str_replace( $this->truncate_paths, '', $path );
|
||||||
|
if ( isset( $path[1] ) && ':' === $path[1] ) {
|
||||||
if ( 0 === strpos( $path, './' ) ) {
|
|
||||||
$path = substr( $path, 2 );
|
$path = substr( $path, 2 );
|
||||||
}
|
}
|
||||||
|
|
||||||
$path = ltrim( $path, '/' );
|
$path = ltrim( $path, '/' );
|
||||||
|
|
||||||
return $path;
|
return $path;
|
||||||
|
|||||||
@@ -58,5 +58,26 @@ class HookTest extends LapsTestCase {
|
|||||||
|
|
||||||
$this->assertEquals( [], $formatter->format( [] ) );
|
$this->assertEquals( [], $formatter->format( [] ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @depends test__construct
|
||||||
|
*/
|
||||||
|
public function testFormatWpHook( Hook_Formatter $formatter ) {
|
||||||
|
|
||||||
|
if ( ! class_exists( 'WP_Hook' ) ) {
|
||||||
|
eval( 'class WP_Hook { public $callbacks = []; }' );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$wp_hook = new \WP_Hook();
|
||||||
|
$wp_hook->callbacks = [
|
||||||
|
10 => [
|
||||||
|
[ 'function' => 'trim', 'accepted_args' => 1 ],
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
$result = $formatter->format( $wp_hook );
|
||||||
|
|
||||||
|
$this->assertIsArray( $result );
|
||||||
|
$this->assertEquals( [ 'trim' ], $result );
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in new issue
Block a user