refactor(widgets): remove shared redundant settings

This commit is contained in:
2026-08-16 15:03:49 +08:00
parent 30b08282f5
commit d97174dadb
31 changed files with 199 additions and 1321 deletions
+1 -319
View File
@@ -7,7 +7,7 @@
defined('ABSPATH') || exit;
require_once AKSRT_DIR . '/inc/modules/widget-common.php';
require_once AKSRT_DIR . '/inc/modules/widget-areas.php';
/**
* Register custom widgets.
@@ -71,324 +71,6 @@ function aksrt_register_widgets() {
}
add_action('widgets_init', 'aksrt_register_widgets');
if (!function_exists('aksrt_widget_sidebar_area_ids')) {
/**
* Sidebars intended for sidebar-only widgets.
*
* @return array<int, string>
*/
function aksrt_widget_sidebar_area_ids(): array {
return [
'home_sidebar',
'sidebar-article',
'all_sidebar_top',
'all_sidebar_bottom',
'cat_sidebar',
'tag_sidebar',
'search_sidebar',
];
}
}
if (!function_exists('aksrt_widget_archive_area_ids')) {
/**
* Widget zones for archive pages (cat/tag/search).
*
* @return array<int, string>
*/
function aksrt_widget_archive_area_ids(): array {
return [
'cat_top_fluid',
'cat_top_content',
'cat_bottom_content',
'cat_bottom_fluid',
'cat_sidebar',
'tag_top_fluid',
'tag_top_content',
'tag_bottom_content',
'tag_bottom_fluid',
'tag_sidebar',
'search_top_fluid',
'search_top_content',
'search_bottom_content',
'search_bottom_fluid',
'search_sidebar',
];
}
}
if (!function_exists('aksrt_widget_homepage_area_ids')) {
/**
* Homepage widget zones for homepage-only widgets.
*
* @return array<int, string>
*/
function aksrt_widget_homepage_area_ids(): array {
return [
'home_top_fluid',
'home_top_content',
'home_bottom_content',
'home_bottom_fluid',
];
}
}
if (!function_exists('aksrt_widget_single_area_ids')) {
/**
* Single post/page widget zones.
*
* @return array<int, string>
*/
function aksrt_widget_single_area_ids(): array {
return [
'single_top_fluid',
'single_top_content',
'single_bottom_content',
'single_bottom_fluid',
];
}
}
if (!function_exists('aksrt_widget_base_from_id')) {
/**
* Get widget base id from a stored widget instance id.
*/
function aksrt_widget_base_from_id(string $widget_id): string {
return preg_replace('/-\d+$/', '', $widget_id) ?: $widget_id;
}
}
if (!function_exists('aksrt_widget_allowed_sidebars')) {
/**
* Allowed sidebar ids for a widget base id.
*
* @return array<int, string>
*/
function aksrt_widget_allowed_sidebars(string $widget_base_id): array {
$sidebar_only = [
'aksrt_categories',
'aksrt_tag_cloud',
'aksrt_hot_posts',
];
$homepage_only = [
'aksrt_category_recommend',
];
$hybrid = [
'aksrt_tab_posts',
'aksrt_category_block',
'aksrt_category_tabs',
];
if (in_array($widget_base_id, $sidebar_only, true)) {
return aksrt_widget_sidebar_area_ids();
}
if (in_array($widget_base_id, $homepage_only, true)) {
return aksrt_widget_homepage_area_ids();
}
if (in_array($widget_base_id, $hybrid, true)) {
return array_values(array_unique(array_merge(
aksrt_widget_sidebar_area_ids(),
aksrt_widget_homepage_area_ids()
)));
}
if ($widget_base_id === 'aksrt_post_pay_box') {
return ['sidebar-article'];
}
return [];
}
}
if (!function_exists('aksrt_widget_is_allowed_in_sidebar')) {
/**
* Whether a widget base id can be assigned to the given sidebar id.
*/
function aksrt_widget_is_allowed_in_sidebar(string $widget_base_id, string $sidebar_id): bool {
if ($widget_base_id === '' || $sidebar_id === '') {
return true;
}
if ($sidebar_id === 'wp_inactive_widgets' || strpos($sidebar_id, 'orphaned_widgets') === 0) {
return true;
}
$allowed = aksrt_widget_allowed_sidebars($widget_base_id);
if (empty($allowed)) {
return true;
}
return in_array($sidebar_id, $allowed, true);
}
}
if (!function_exists('aksrt_widget_get_area_context')) {
/**
* Resolve widget area context from sidebar args.
*/
function aksrt_widget_get_area_context(array $args): string {
$sidebar_id = isset($args['id']) ? (string) $args['id'] : '';
if (in_array($sidebar_id, aksrt_widget_sidebar_area_ids(), true)) {
return 'sidebar';
}
if (in_array($sidebar_id, aksrt_widget_homepage_area_ids(), true)) {
return 'homepage';
}
if (in_array($sidebar_id, aksrt_widget_archive_area_ids(), true)) {
return 'archive';
}
if (in_array($sidebar_id, aksrt_widget_single_area_ids(), true)) {
return 'single';
}
return 'other';
}
}
if (!function_exists('aksrt_widget_render_location_help')) {
/**
* Render placement hint inside widget admin forms.
*/
function aksrt_widget_render_location_help(string $scope): void {
$messages = [
'sidebar' => __('仅限侧栏区域:首页侧栏、文章页侧边栏、全站侧栏、分类/标签/搜索侧栏。', 'aksrt'),
'homepage' => __('仅限首页挂载区域:首页顶部/底部全宽、首页内容上方/下方。', 'aksrt'),
'hybrid' => __('支持侧栏、首页和归档页挂载区域。', 'aksrt'),
'archive' => __('仅限归档页挂载区域:分类页、标签页、搜索页的顶部/底部/侧栏。', 'aksrt'),
];
if (empty($messages[$scope])) {
return;
}
printf(
'<p style="margin-top:10px;font-size:12px;color:#666;">%s</p>',
esc_html($messages[$scope])
);
}
}
if (!function_exists('aksrt_filter_widget_display_by_area')) {
/**
* Prevent widgets from rendering outside their allowed areas,
* and apply per-widget display rules (show_type, show_id_type/show_ids).
*
* @param array|false $instance Widget instance.
* @param WP_Widget $widget Widget object.
* @param array $args Sidebar args.
* @return array|false
*/
function aksrt_filter_widget_display_by_area($instance, WP_Widget $widget, array $args) {
$sidebar_id = isset($args['id']) ? (string) $args['id'] : '';
$widget_base_id = isset($widget->id_base) ? (string) $widget->id_base : '';
if ($instance === false) {
return false;
}
// Layer 1: Area legality check
if (!aksrt_widget_is_allowed_in_sidebar($widget_base_id, $sidebar_id)) {
return false;
}
// Layer 2: Display rule check (show_type for PC/mobile)
if (is_array($instance) && function_exists('aksrt_widget_normalize_common')) {
$normalized = aksrt_widget_normalize_common($instance);
// Show type: PC / mobile filter (Zibll only_pc / only_sm).
if ($normalized['show_type'] === 'only_pc' && wp_is_mobile()) {
return false;
}
if ($normalized['show_type'] === 'only_sm' && !wp_is_mobile()) {
return false;
}
// Show IDs: whitelist / blacklist filter
if (!aksrt_widget_should_display_by_ids($normalized)) {
return false;
}
}
return $instance;
}
}
add_filter('widget_display_callback', 'aksrt_filter_widget_display_by_area', 10, 3);
if (!function_exists('aksrt_filter_widget_sidebar_assignments')) {
/**
* Move disallowed widget assignments back to the inactive widgets bucket.
*
* @param mixed $new_value New sidebars_widgets option value.
* @param mixed $old_value Previous option value.
* @return mixed
*/
function aksrt_filter_widget_sidebar_assignments($new_value, $old_value) {
if (!is_array($new_value)) {
return $new_value;
}
$removed = [];
foreach ($new_value as $sidebar_id => $widget_ids) {
if (!is_array($widget_ids) || $sidebar_id === 'wp_inactive_widgets') {
continue;
}
$filtered = [];
foreach ($widget_ids as $widget_id) {
if (!is_string($widget_id) || $widget_id === '') {
continue;
}
$widget_base_id = aksrt_widget_base_from_id($widget_id);
if (aksrt_widget_is_allowed_in_sidebar($widget_base_id, (string) $sidebar_id)) {
$filtered[] = $widget_id;
} else {
$removed[] = $widget_id;
}
}
$new_value[$sidebar_id] = array_values($filtered);
}
if (empty($removed)) {
return $new_value;
}
if (!isset($new_value['wp_inactive_widgets']) || !is_array($new_value['wp_inactive_widgets'])) {
$new_value['wp_inactive_widgets'] = [];
}
$assigned = [];
foreach ($new_value as $widget_ids) {
if (!is_array($widget_ids)) {
continue;
}
foreach ($widget_ids as $widget_id) {
if (is_string($widget_id) && $widget_id !== '') {
$assigned[$widget_id] = true;
}
}
}
foreach (array_values(array_unique($removed)) as $widget_id) {
if (!isset($assigned[$widget_id]) && !in_array($widget_id, $new_value['wp_inactive_widgets'], true)) {
$new_value['wp_inactive_widgets'][] = $widget_id;
}
}
return $new_value;
}
}
add_filter('pre_update_option_sidebars_widgets', 'aksrt_filter_widget_sidebar_assignments', 10, 2);
/**
* Register a block editor collection for AKSRT widgets.
*/