Skip to content
This repository has been archived by the owner on Mar 9, 2024. It is now read-only.

Add block compatibility debug info to Site Health #169

Merged
merged 6 commits into from
Oct 5, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/wp-admin/includes/admin.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@
/** ClassicPress Support URL changes */
require_once ABSPATH . WPINC . '/classicpress/class-cp-customization.php';

/** ClassicPress Site Health block compatibility debug */
require_once ABSPATH . WPINC . '/classicpress/class-cp-debug-compat.php';

/** ClassicPress Administration Hooks */
require_once ABSPATH . 'wp-admin/includes/admin-filters.php';

Expand Down
227 changes: 227 additions & 0 deletions src/wp-includes/classicpress/class-cp-debug-compat.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,227 @@
<?php
/**
* ClassicPress Site Health block compatibility debug class
*
* @package ClassicPress
* @subpackage admin
* @since CP-2.0.0
*/

class CP_Debug_Compat {

public function __construct() {
add_action( 'update_option_blocks_compatibility_level', array( $this, 'clean_options' ), 10, 2 );

$blocks_compatibility_level = (int) get_option( 'blocks_compatibility_level', 1 );
if ( $blocks_compatibility_level !== 2 ) {
return;
}

add_action( 'using_block_function', array( $this, 'log' ) );
add_filter( 'site_status_tests', array( $this, 'add_site_status_tests' ) );
add_filter( 'debug_information', array( $this, 'add_debug_information' ) );
}

public function add_debug_information( $args ) {
$options = $this->get_options();

$item_types = array(
'plugins' => 'Plugin',
'themes' => 'Theme',
'parent_themes' => 'Parent Theme',
);

$fields = array();
foreach ( $item_types as $key => $description ) {
foreach ( $options['data'][ $key ] as $item => $value ) {
$functions = wp_kses( $this->implode( $value ) . '.', array() );
$fields[ $item ] = array(
'label' => $description . ': ' . $item,
'value' => $functions,
'debug' => 'Plugin uses ' . $functions,
);
}
}

$args['dc-blocks'] = array(
'label' => esc_html__( 'Block Compatibility' ),
'description' => esc_html__( 'Plugins and themes using block functions.' ),
'show_count' => true,
'fields' => $fields,
);

return $args;
}

public function add_site_status_tests( $tests ) {
$tests['direct']['dc_plugins_blocks'] = array(
'label' => esc_html__( 'Plugins using block functions' ),
'test' => array( $this, 'test_plugin' ),
);
$tests['direct']['dc_themes_blocks'] = array(
'label' => esc_html__( 'Themes using block functions' ),
'test' => array( $this, 'test_theme' ),
);
return $tests;
}

public function test_plugin() {
$options = $this->get_options();
$result = array(
'label' => esc_html__( 'Plugins using block functions' ),
'status' => 'good',
'badge' => array(
'label' => 'Compatibility',
'color' => 'blue',
),
'description' => sprintf(
'<p>%s</p>',
esc_html__( 'No plugins are using block functions.' ),
),
'actions' => '',
'test' => 'dc_plugins_blocks',
);
if ( $options['data']['plugins'] === array() ) {
return $result;
}
$action = esc_html__( 'Plugins in this list may have issues. ' );
xxsimoxx marked this conversation as resolved.
Show resolved Hide resolved
$action .= ' <a href="https://docs.classicpress.net/user-guides/using-classicpress/site-health-screen/#block-compatibility">' . esc_html__( 'Learn more.' ) . '</a>';
$result = array(
'label' => esc_html__( 'Plugins using block functions' ),
'status' => 'recommended',
'badge' => array(
'label' => 'Compatibility',
'color' => 'orange',
),
'description' => $this->list_items( $options, 'plugins' ),
'actions' => $action,
'test' => 'dc_plugins_blocks',
);
return $result;
}

public function test_theme() {
$options = $this->get_options();
$result = array(
'label' => esc_html__( 'Themes using block functions' ),
'status' => 'good',
'badge' => array(
'label' => 'Compatibility',
'color' => 'blue',
),
'description' => sprintf(
'<p>%s</p>',
esc_html__( 'No themes are using block functions.' ),
),
'actions' => '',
'test' => 'dc_themes_blocks',
);
$themes = array_merge( $options['data']['themes'], $options['data']['parent_themes'] );
if ( $themes === array() ) {
return $result;
}
$action = esc_html__( 'Themes in this list may have issues. ' );
xxsimoxx marked this conversation as resolved.
Show resolved Hide resolved
$action .= ' <a href="https://docs.classicpress.net/user-guides/using-classicpress/site-health-screen/#block-compatibility">' . esc_html__( 'Learn more.' ) . '</a>';
$result = array(
'label' => esc_html__( 'Themes using block functions' ),
'status' => 'recommended',
'badge' => array(
'label' => 'Compatibility',
'color' => 'orange',
),
'description' => $this->list_items( $options, 'themes' ) . $this->list_items( $options, 'parent_themes' ),
'actions' => $action,
'test' => 'dc_themes_blocks',
);
return $result;
}

private function list_items( $options, $type ) {
$response = '';
foreach ( $options['data'][ $type ] as $who => $what ) {
$response .= sprintf(
wp_kses(
/* translators: %1$s is the plugin/theme name, %b$s is a comma separated list of functions */
'<p><b>%1$s</b> is using: %2$s.</p>',
array(
'b' => array(),
'p' => array(),
)
),
esc_html( $who ),
wp_kses(
$this->implode( $what ),
array(
'code' => array(),
)
)
);
}
return $response;
}

private function implode( $list ) {
$result = '';
foreach ( $list as $element ) {
$result .= '<code>' . $element . '</code>, ';
}
return rtrim( $result, ', ' );
}

private function get_options() {
$default = array(
'db_version' => '2',
'data' => array(
'themes' => array(),
'parent_themes' => array(),
'plugins' => array(),
'misc' => array(),
),
);
$options = get_option( 'cp_dc_options', $default );
return $options;
}

public function log( $trace ) {
$options = $this->get_options();
$func = $trace[1]['function'];

if ( 0 === strpos( $trace[1]['file'], realpath( get_stylesheet_directory() ) ) ) {
// Theme
if ( ! isset( $options['data']['themes'][ wp_get_theme()->get( 'Name' ) ] ) || ! in_array( $func, $options['data']['themes'][ wp_get_theme()->get( 'Name' ) ] ) ) {
$options['data']['themes'][ wp_get_theme()->get( 'Name' ) ][] = $func;
}
} elseif ( 0 === strpos( $trace[1]['file'], realpath( get_template_directory() ) ) ) {
// Child theme
if ( ! isset( $options['data']['parent_themes'][ wp_get_theme()->parent()->get( 'Name' ) ] ) || ! in_array( $func, $options['data']['parent_themes'][ wp_get_theme()->parent()->get( 'Name' ) ] ) ) {
$options['data']['parent_themes'][ wp_get_theme()->parent()->get( 'Name' ) ][] = $func;
}
} else {
$files = array_column( $trace, 'file' );
$active = wp_get_active_and_valid_plugins();
$plugin = array_intersect( $files, $active );
if ( count( $plugin ) !== 1 ) {
// Hooked somewhere
if ( ! in_array( $func, $options['data']['misc'] ) ) {
$options['data']['misc'][] = $func;
}
} else {
// Plugin
$plugin_data = get_plugin_data( array_pop( $plugin ) );
$plugin_name = $plugin_data['Name'];
if ( ! isset( $options['data']['plugins'][ $plugin_name ] ) || ! in_array( $func, $options['data']['plugins'][ $plugin_name ] ) ) {
$options['data']['plugins'][ $plugin_name ][] = $func;
}
}
}

update_option( 'cp_dc_options', $options );
}

public static function clean_options() {
delete_option( 'cp_dc_options' );
}

}

new CP_Debug_Compat;