');
// Add top-level menu with custom SVG icon
$menu_slug = 'patternswp-plugin-menu';
add_menu_page(
'PatternsWP',
'PatternsWP',
'manage_options',
$menu_slug,
array($this, 'render_main_page'),
$custom_icon,
60
);
// Add subpages
$this->add_subpage($menu_slug, 'Dashboard', 'Dashboard', 'patternswp-plugin-menu', array($this, 'render_main_page'));
$this->add_subpage($menu_slug, 'Settings', 'Settings', 'patternswp-settings', array($this, 'render_pattern_visibility_page'));
$this->add_subpage($menu_slug, 'Support', 'Support', 'patternswp-plugin-page-1', array($this, 'patternswp_support'));
}
/**
* Add subpage
*/
private function add_subpage($parent_slug, $page_title, $menu_title, $menu_slug, $callback) {
// Add subpage
add_submenu_page($parent_slug, $page_title, $menu_title, 'manage_options', $menu_slug, $callback);
}
/**
* Render tabs
*/
public function patterswp_tab( $tab ) {
$tabs = array(
'Dashboard' => 'patternswp-plugin-menu',
'Settings' => 'patternswp-settings',
'Support' => 'patternswp-plugin-page-1',
'License' => 'patternswp-license_section'
);
// Get the current page from URL parameter
$current_page = isset($_GET['page']) ? sanitize_text_field($_GET['page']) : 'patternswp-plugin-menu';
// Map page slugs to tab names
$page_to_tab = array(
'patternswp-plugin-menu' => 'Dashboard',
'patternswp-settings' => 'Settings',
'patternswp-plugin-page-1' => 'Support',
'patternswp-license_section' => 'License'
);
// Determine current tab
$current_tab = isset($page_to_tab[$current_page]) ? $page_to_tab[$current_page] : 'Dashboard';
foreach ($tabs as $name => $slug) {
$class = ( $current_tab === $name ) ? 'nav-tab-active' : '';
echo '' . esc_html($name) . '';
}
}
/**
* Render main page
*/
public function render_main_page() { ?>
patterswp_tab( 'Dashboard' ); ?>
display_name . ' 👋'); ?>
patterswp_tab( 'Support' ); ?>
'.esc_attr('contact us via the support form →', 'patternswp').''
);
?>
patterswp_tab( 'Clear Cache' ); ?>
clear_pattern_cache(false, false);
}
/**
* Handle remote pattern loading based on settings
*/
public function maybe_disable_remote_patterns($should_load) {
if (get_option('patternswp_hide_core_patterns', false)) {
return false;
}
return $should_load;
}
/**
* Filter block editor settings to handle pattern visibility
*/
public function filter_block_editor_settings($settings, $context) {
if (get_option('patternswp_hide_core_patterns', false)) {
$settings['__experimentalBlockPatterns'] = array();
$settings['__experimentalBlockPatternCategories'] = array();
$settings['__experimentalBlockPatterns'] = array();
}
return $settings;
}
/**
* Clear Cache
*/
public function patternswp_clear_cache() {
global $wpdb;
if (isset($_POST['patternswp_clear_cache'])) {
if (!isset($_POST['patternswp_clear_cache_nonce'])) {
wp_die(esc_attr__('Security check failed. Please try again.', 'patternswp'));
}
$nonce = sanitize_text_field(wp_unslash($_POST['patternswp_clear_cache_nonce']));
if (!wp_verify_nonce($nonce, 'patternswp_clear_cache_action')) {
wp_die(esc_attr__('Security check failed. Please try again.', 'patternswp'));
}
if (!current_user_can('manage_options')) {
wp_die(esc_attr('You do not have sufficient permissions to perform this action.', 'patternswp'));
}
// Delete category type transient
delete_transient('patternswp_category_type');
// Delete all API-related transients
$pattern = '_transient_patternswp_';
// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
$results = $wpdb->get_col($wpdb->prepare("SELECT option_name FROM $wpdb->options WHERE option_name LIKE %s", $wpdb->esc_like($pattern) . '%'));
// Delete all patterns cache
$patterns = 'patterns_cache_';
// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
$wpdb->query(
$wpdb->prepare(
"DELETE FROM $wpdb->options WHERE option_name LIKE %s",
$wpdb->esc_like($patterns) . '%'
)
);
foreach ($results as $transient) {
delete_option($transient);
delete_option(str_replace('_transient_', '_transient_timeout_', $transient));
}
// Load patterns in background
$this->patternswp_load_patterns_by_remote_ajax();
// Set a transient for the success message
set_transient('patternswp_cache_cleared', 'Cache cleared successfully', 5);
// Redirect to Settings page
wp_safe_redirect(admin_url('admin.php?page=patternswp-settings'));
exit;
}
}
/**
* Ensure hourly cron job is scheduled
*/
public function patternswp_ensure_hourly_cron() {
if ( ! wp_next_scheduled( 'patternswp_hourly_transient_load' ) ) {
wp_schedule_event( time(), 'hourly', 'patternswp_hourly_transient_load' );
}
}
/**
* AJAX handler to load transient data
*/
public function patternswp_background_transient_load_ajaxcc() {
do_action( 'patternswp_hourly_transient_load' );
wp_die();
}
/**
* Load patterns via AJAX
*/
public function patternswp_load_patterns_by_remote_ajax() {
$ajax_url = admin_url('admin-ajax.php');
wp_remote_post( $ajax_url , array(
'body' => array( 'action' => 'patternswp_background_transient_load_ajax' ),
'timeout' => 1,
'blocking' => false,
'sslverify' => false,
));
}
/**
* Set transient on plugin activation
*/
public function patternswp_on_activation() {
set_transient('patternswp_activation_redirect', true, 30);
}
/**
* Clear pattern cache when visibility settings change
*/
public function clear_pattern_cache($old_value, $new_value) {
// Clear object cache first
if (function_exists('wp_cache_flush')) {
wp_cache_flush();
}
// Clear known transients
$transients = [
'patternswp_all_patterns',
'patternswp_categorized_patterns',
'patternswp_patterns_data',
'patternswp_categories'
];
foreach ($transients as $transient) {
delete_transient($transient);
}
// Clear any remaining transients with our prefix
if (!function_exists('delete_expired_transients')) {
require_once ABSPATH . 'wp-admin/includes/plugin.php';
}
// This is a core function that will clean up expired transients
delete_expired_transients(true);
// Clear specific pattern caches
if (function_exists('wp_cache_delete')) {
wp_cache_delete('all_patterns', 'patternswp');
wp_cache_delete('categorized_patterns', 'patternswp');
}
}
/**
* Attempt to deregister any patterns from the active or child theme.
*/
public function maybe_deregister_theme_patterns() {
$hide_theme_patterns = get_option('patternswp_hide_theme_patterns', false);
error_log('[PatternsWP] maybe_deregister_theme_patterns called - hide_theme_patterns: ' . ($hide_theme_patterns ? 'true' : 'false'));
if (!$hide_theme_patterns) {
error_log('[PatternsWP] Theme pattern hiding is disabled');
return;
}
// Get the active theme.
$theme = wp_get_theme();
// Let's get some theme data.
$paths_to_search = array(
$theme->stylesheet,
);
// Check if this is a child theme.
if ($theme->parent()) {
$parent_theme = wp_get_theme($theme->parent()->template);
$paths_to_search[] = $parent_theme->template;
}
$paths_to_search = array_unique($paths_to_search);
error_log('[PatternsWP] Theme paths to search: ' . implode(', ', $paths_to_search));
// Get all registered patterns.
$patterns = \WP_Block_Patterns_Registry::get_instance();
$all_patterns = $patterns->get_all_registered();
error_log('[PatternsWP] Total registered patterns: ' . count($all_patterns));
// Loop through all patterns and deregister any that are from the active or child theme.
foreach ($all_patterns as $index => $pattern) {
$file_path = $pattern['filePath'] ?? '';
if (empty($file_path)) {
continue;
}
// Check if the pattern is from the active or child theme.
foreach ($paths_to_search as $path) {
if (false !== strpos($file_path, 'themes/' . $path)) {
unregister_block_pattern($pattern['name']);
error_log('[PatternsWP] Deregistered theme pattern: ' . $pattern['name'] . ' from path: ' . $file_path);
}
}
}
}
/**
* Deregister any uncategorized patterns.
*/
public function maybe_deregister_uncategorized_patterns() {
$hide_uncategorized_enabled = get_option('patternswp_hide_uncategorized_patterns', false);
error_log('[PatternsWP] maybe_deregister_uncategorized_patterns called - hide_uncategorized: ' . ($hide_uncategorized_enabled ? 'true' : 'false'));
// Exit early if not enabled.
if (!$hide_uncategorized_enabled) {
error_log('[PatternsWP] Uncategorized pattern hiding is disabled');
return;
}
// Retrieve all patterns.
$patterns = \WP_Block_Patterns_Registry::get_instance();
$all_patterns = $patterns->get_all_registered();
error_log('[PatternsWP] Checking ' . count($all_patterns) . ' patterns for uncategorized ones');
// Loop through all patterns and deregister any that are uncategorized.
foreach ($all_patterns as $index => $pattern) {
if (!isset($pattern['categories']) || empty($pattern['categories'])) {
unregister_block_pattern($pattern['name']);
error_log('[PatternsWP] Deregistered uncategorized pattern: ' . $pattern['name']);
} else {
$found = false;
$block_categories = $pattern['categories'] ?? array();
foreach ($block_categories as $block_category) {
$categories = \WP_Block_Pattern_Categories_Registry::get_instance();
if ($categories->is_registered($block_category)) {
$found = true;
}
}
if (!$found) {
unregister_block_pattern($pattern['name']);
error_log('[PatternsWP] Deregistered uncategorized pattern (invalid category): ' . $pattern['name']);
}
}
}
}
/**
* Deregister core patterns.
*/
public function maybe_deregister_core_patterns() {
$hide_core_patterns = get_option('patternswp_hide_core_patterns', false);
error_log('[PatternsWP] maybe_deregister_core_patterns called - hide_core_patterns: ' . ($hide_core_patterns ? 'true' : 'false'));
// Exit early if not enabled.
if (!$hide_core_patterns) {
error_log('[PatternsWP] Core pattern hiding is disabled');
return;
}
// Retrieve all patterns.
$patterns = \WP_Block_Patterns_Registry::get_instance();
$all_patterns = $patterns->get_all_registered();
error_log('[PatternsWP] Checking ' . count($all_patterns) . ' patterns for core ones');
// Loop through all patterns and deregister any that are core patterns.
foreach ($all_patterns as $index => $pattern) {
// Core patterns typically have names starting with 'core/' or no file path
$pattern_name = $pattern['name'] ?? '';
$file_path = $pattern['filePath'] ?? '';
// Check if it's a core pattern
$is_core_pattern = false;
$reason = '';
// Method 1: Check if pattern name starts with 'core/'
if (strpos($pattern_name, 'core/') === 0) {
$is_core_pattern = true;
$reason = 'name starts with core/';
}
// Method 2: Check if file path contains wp-includes
if (!$is_core_pattern && !empty($file_path) && strpos($file_path, 'wp-includes') !== false) {
$is_core_pattern = true;
$reason = 'file path contains wp-includes';
}
// Method 3: Check if no file path (likely core pattern)
if (!$is_core_pattern && empty($file_path)) {
$is_core_pattern = true;
$reason = 'no file path';
}
if ($is_core_pattern) {
unregister_block_pattern($pattern['name']);
error_log('[PatternsWP] Deregistered core pattern: ' . $pattern['name'] . ' (' . $reason . ')');
}
}
}
/**
* Filter the block patterns list in the editor
*/
public function filter_block_patterns_list($patterns) {
error_log('[PatternsWP] filter_block_patterns_list called with ' . count($patterns) . ' patterns');
$hide_theme_patterns = get_option('patternswp_hide_theme_patterns', false);
$hide_uncategorized = get_option('patternswp_hide_uncategorized_patterns', false);
$hide_core_patterns = get_option('patternswp_hide_core_patterns', false);
error_log('[PatternsWP] Block patterns filter - Theme: ' . ($hide_theme_patterns ? 'true' : 'false') . ', Uncategorized: ' . ($hide_uncategorized ? 'true' : 'false') . ', Core: ' . ($hide_core_patterns ? 'true' : 'false'));
// If no filters are enabled, return original patterns
if (!$hide_theme_patterns && !$hide_uncategorized && !$hide_core_patterns) {
return $patterns;
}
$filtered_patterns = array();
foreach ($patterns as $pattern) {
$should_include = true;
// Check theme patterns
if ($hide_theme_patterns && $should_include) {
// Check if pattern name starts with theme prefix
if (isset($pattern['name']) && strpos($pattern['name'], 'theme-') === 0) {
$should_include = false;
error_log('[PatternsWP] Excluding theme pattern by name: ' . $pattern['name']);
}
// Check if pattern has theme file path
if (isset($pattern['filePath']) && strpos($pattern['filePath'], 'themes/') !== false) {
$should_include = false;
error_log('[PatternsWP] Excluding theme pattern by path: ' . $pattern['name']);
}
}
// Check uncategorized patterns
if ($hide_uncategorized && $should_include) {
if (!isset($pattern['categories']) || empty($pattern['categories'])) {
$should_include = false;
error_log('[PatternsWP] Excluding uncategorized pattern: ' . $pattern['name']);
}
}
// Check core patterns
if ($hide_core_patterns && $should_include) {
if (isset($pattern['name']) && strpos($pattern['name'], 'core/') === 0) {
$should_include = false;
error_log('[PatternsWP] Excluding core pattern: ' . $pattern['name']);
}
}
if ($should_include) {
$filtered_patterns[] = $pattern;
}
}
error_log('[PatternsWP] Filtered from ' . count($patterns) . ' to ' . count($filtered_patterns) . ' patterns');
return $filtered_patterns;
}
/**
* Filter REST API response for individual blocks
*/
public function filter_rest_block_response($response, $post, $request) {
// Only filter in the block editor context
if (!isset($request['context']) || $request['context'] !== 'edit') {
return $response;
}
$hide_theme_patterns = get_option('patternswp_hide_theme_patterns', false);
$hide_uncategorized = get_option('patternswp_hide_uncategorized_patterns', false);
$hide_core_patterns = get_option('patternswp_hide_core_patterns', false);
// If no filters are enabled, return original response
if (!$hide_theme_patterns && !$hide_uncategorized && !$hide_core_patterns) {
return $response;
}
// Get the pattern data
$pattern_data = $response->data;
// Check if this should be hidden
$should_hide = false;
// Check theme patterns
if ($hide_theme_patterns) {
// Check if pattern has theme-specific metadata
if (isset($pattern_data['patternswp_source']) && $pattern_data['patternswp_source'] === 'theme') {
$should_hide = true;
}
}
// Check uncategorized patterns
if (!$should_hide && $hide_uncategorized) {
if (empty($pattern_data['pattern_categories'])) {
$should_hide = true;
}
}
// Check core patterns
if (!$should_hide && $hide_core_patterns) {
if (isset($pattern_data['name']) && strpos($pattern_data['name'], 'core/') === 0) {
$should_hide = true;
}
}
if ($should_hide) {
error_log('[PatternsWP] Filtering REST response for pattern: ' . ($pattern_data['title'] ?? 'Unknown'));
// Return an error response to hide this pattern
return new WP_Error(
'rest_pattern_hidden',
'Pattern is hidden by visibility settings',
array('status' => 404)
);
}
return $response;
}
/**
* Filter REST API patterns
*/
public function filter_rest_patterns($args, $request) {
// Only filter if we're in the block editor context
if (!isset($request['context']) || $request['context'] !== 'edit') {
return $args;
}
// Get the current registered patterns
$patterns = \WP_Block_Patterns_Registry::get_instance();
$all_patterns = $patterns->get_all_registered();
$hide_theme_patterns = get_option('patternswp_hide_theme_patterns', false);
$hide_uncategorized = get_option('patternswp_hide_uncategorized_patterns', false);
$hide_core_patterns = get_option('patternswp_hide_core_patterns', false);
// If no filters are enabled, return original args
if (!$hide_theme_patterns && !$hide_uncategorized && !$hide_core_patterns) {
return $args;
}
// Get theme info for theme pattern detection
$theme = wp_get_theme();
$paths_to_search = array($theme->stylesheet);
if ($theme->parent()) {
$parent_theme = wp_get_theme($theme->parent()->template);
$paths_to_search[] = $parent_theme->template;
}
$paths_to_search = array_unique($paths_to_search);
// Build list of pattern names to exclude
$exclude_patterns = array();
foreach ($all_patterns as $pattern) {
$should_exclude = false;
// Check if it's a theme pattern
if ($hide_theme_patterns) {
$file_path = $pattern['filePath'] ?? '';
if (!empty($file_path)) {
foreach ($paths_to_search as $path) {
if (false !== strpos($file_path, 'themes/' . $path)) {
$should_exclude = true;
break;
}
}
}
}
// Check if it's a core pattern
if (!$should_exclude && $hide_core_patterns) {
$pattern_name = $pattern['name'] ?? '';
$file_path = $pattern['filePath'] ?? '';
// Method 1: Check if pattern name starts with 'core/'
if (strpos($pattern_name, 'core/') === 0) {
$should_exclude = true;
}
// Method 2: Check if file path contains wp-includes
if (!$should_exclude && !empty($file_path) && strpos($file_path, 'wp-includes') !== false) {
$should_exclude = true;
}
// Method 3: Check if no file path (likely core pattern)
if (!$should_exclude && empty($file_path)) {
$should_exclude = true;
}
}
// Check if it's uncategorized
if (!$should_exclude && $hide_uncategorized) {
if (!isset($pattern['categories']) || empty($pattern['categories'])) {
$should_exclude = true;
} else {
$found = false;
$block_categories = $pattern['categories'] ?? array();
foreach ($block_categories as $block_category) {
$categories = \WP_Block_Pattern_Categories_Registry::get_instance();
if ($categories->is_registered($block_category)) {
$found = true;
break;
}
}
if (!$found) {
$should_exclude = true;
}
}
}
if ($should_exclude) {
$exclude_patterns[] = $pattern['name'];
}
}
// Add exclude filter using direct SQL for better performance
if (!empty($exclude_patterns)) {
add_filter('posts_where', function($where) use ($exclude_patterns) {
global $wpdb;
// Prepare placeholders for the IN clause
$placeholders = array_fill(0, count($exclude_patterns), '%s');
$placeholders = implode(',', $placeholders);
// Prepare the exclusion subquery
$exclude_sql = $wpdb->prepare(
"SELECT post_id
FROM {$wpdb->postmeta}
WHERE meta_key = 'pattern_id'
AND meta_value IN ($placeholders)",
$exclude_patterns
);
// Add the exclusion to the WHERE clause
$where .= " AND {$wpdb->posts}.ID NOT IN ($exclude_sql)";
return $where;
});
// Ensure we don't use post__not_in or meta_query
unset($args['post__not_in']);
unset($args['meta_query']);
}
return $args;
}
/**
* Filter patterns based on visibility settings
*/
/**
* Check if a pattern is a theme pattern
*/
private function is_theme_pattern($pattern) {
// Check source
if (!empty($pattern['source']) && $pattern['source'] === 'theme') {
return true;
}
// Check name prefix
if (!empty($pattern['name']) && (strpos($pattern['name'], 'theme-') === 0 ||
strpos($pattern['name'], 'tw/') === 0)) {
return true;
}
// Check categories
if (!empty($pattern['categories'])) {
$categories = is_array($pattern['categories']) ?
$pattern['categories'] :
array_map('trim', explode(',', $pattern['categories']));
foreach ($categories as $category) {
if (is_string($category) &&
(stripos($category, 'theme') !== false ||
stripos($category, 'template') !== false)) {
return true;
}
}
}
return false;
}
/**
* Check if a pattern is a core pattern
*/
private function is_core_pattern($pattern) {
// Check source
if (!empty($pattern['source']) && $pattern['source'] === 'core') {
return true;
}
// Check name prefix
if (!empty($pattern['name']) && strpos($pattern['name'], 'core/') === 0) {
return true;
}
return false;
}
/**
* Check if a pattern is uncategorized
*/
private function is_uncategorized_pattern($pattern) {
if (empty($pattern['categories'])) {
return true;
}
$categories = is_array($pattern['categories']) ?
$pattern['categories'] :
array_filter(array_map('trim', explode(',', $pattern['categories'])));
return empty($categories);
}
/**
* Filter patterns based on visibility settings
*/
public function filter_patterns_by_visibility($patterns) {
// Debug logging
error_log('[PatternsWP] Filter applied with ' . count((array)$patterns) . ' patterns');
// If no patterns or not an array, return early
if (empty($patterns) || !is_array($patterns)) {
error_log('[PatternsWP] No patterns to filter');
return $patterns;
}
$filtered_patterns = array();
$hide_theme_patterns = get_option('patternswp_hide_theme_patterns', false);
$hide_uncategorized = get_option('patternswp_hide_uncategorized_patterns', false);
$hide_core_patterns = get_option('patternswp_hide_core_patterns', false);
error_log('[PatternsWP] Settings - Hide Theme: ' . ($hide_theme_patterns ? 'true' : 'false') .
', Hide Uncategorized: ' . ($hide_uncategorized ? 'true' : 'false') .
', Hide Core: ' . ($hide_core_patterns ? 'true' : 'false'));
foreach ($patterns as $pattern) {
// Skip if pattern is not an array
if (!is_array($pattern)) {
$filtered_patterns[] = $pattern;
continue;
}
// Skip theme patterns if enabled
if ($hide_theme_patterns && $this->is_theme_pattern($pattern)) {
error_log('[PatternsWP] Skipping theme pattern: ' . ($pattern['title'] ?? 'Unknown'));
continue;
}
// Skip core patterns if enabled
if ($hide_core_patterns && $this->is_core_pattern($pattern)) {
error_log('[PatternsWP] Skipping core pattern: ' . ($pattern['title'] ?? 'Unknown'));
continue;
}
// Skip uncategorized patterns if enabled
if ($hide_uncategorized && $this->is_uncategorized_pattern($pattern)) {
error_log('[PatternsWP] Skipping uncategorized pattern: ' . ($pattern['title'] ?? 'Unknown'));
continue;
}
$filtered_patterns[] = $pattern;
}
error_log('[PatternsWP] Filtered to ' . count($filtered_patterns) . ' patterns');
return $filtered_patterns;
}
/**
* Register Pattern Visibility settings
*/
public function register_pattern_visibility_settings() {
// Register settings
register_setting('patternswp_visibility_settings', 'patternswp_hide_theme_patterns', array(
'type' => 'boolean',
'default' => false,
'sanitize_callback' => 'rest_sanitize_boolean',
));
register_setting('patternswp_visibility_settings', 'patternswp_hide_uncategorized_patterns', array(
'type' => 'boolean',
'default' => false,
'sanitize_callback' => 'rest_sanitize_boolean',
));
register_setting('patternswp_visibility_settings', 'patternswp_hide_core_patterns', array(
'type' => 'boolean',
'default' => false,
'sanitize_callback' => 'rest_sanitize_boolean',
));
// Clear cache when settings are updated
add_action('update_option_patternswp_hide_theme_patterns', array($this, 'clear_pattern_cache'), 10, 2);
add_action('update_option_patternswp_hide_uncategorized_patterns', array($this, 'clear_pattern_cache'), 10, 2);
add_action('update_option_patternswp_hide_core_patterns', array($this, 'clear_pattern_cache'), 10, 2);
// Add settings section
add_settings_section(
'patternswp_visibility_section',
__('Pattern Visibility', 'patternswp'),
array($this, 'pattern_visibility_section_callback'),
'patternswp-settings'
);
// Add settings fields
add_settings_field(
'patternswp_hide_theme_patterns',
__('Hide Theme Patterns', 'patternswp'),
array($this, 'render_checkbox_field'),
'patternswp-settings',
'patternswp_visibility_section',
array(
'label_for' => 'patternswp_hide_theme_patterns',
'description' => __('Prevent patterns registered by the active theme from displaying in the patterns list.', 'patternswp')
)
);
add_settings_field(
'patternswp_hide_uncategorized_patterns',
__('Hide Uncategorized Patterns', 'patternswp'),
array($this, 'render_checkbox_field'),
'patternswp-settings',
'patternswp_visibility_section',
array(
'label_for' => 'patternswp_hide_uncategorized_patterns',
'description' => __('Prevent any patterns not in any registered categories from displaying.', 'patternswp')
)
);
add_settings_field(
'patternswp_hide_core_patterns',
__('Hide Core Patterns', 'patternswp'),
array($this, 'render_checkbox_field'),
'patternswp-settings',
'patternswp_visibility_section',
array(
'label_for' => 'patternswp_hide_core_patterns',
'description' => __('Remove all core patterns from the pattern selector by disabling core patterns.', 'patternswp')
)
);
}
/**
* Pattern Visibility section callback
*/
public function pattern_visibility_section_callback() {
echo '' . esc_html__('Control which patterns are visible in the block editor.', 'patternswp') . '
';
}
/**
* Render checkbox field
*/
public function render_checkbox_field($args) {
$option = get_option($args['label_for']);
?>