diff --git a/inc/modules/widget-areas.php b/inc/modules/widget-areas.php new file mode 100644 index 00000000..a1743864 --- /dev/null +++ b/inc/modules/widget-areas.php @@ -0,0 +1,148 @@ + __('仅限侧栏区域:首页侧栏、文章页侧边栏、全站侧栏、分类/标签/搜索侧栏。', 'aksrt'), + 'homepage' => __('仅限首页挂载区域:首页顶部/底部全宽、首页内容上方/下方。', 'aksrt'), + 'hybrid' => __('支持侧栏、首页和归档页挂载区域。', 'aksrt'), + 'archive' => __('仅限归档页挂载区域:分类页、标签页、搜索页的顶部/底部/侧栏。', 'aksrt'), + ]; + if (empty($messages[$scope])) { + return; + } + printf('
%s
', esc_html($messages[$scope])); +} + +function aksrt_filter_widget_display_by_area($instance, WP_Widget $widget, array $args) { + if ($instance === false) { + return false; + } + $sidebar_id = isset($args['id']) ? (string) $args['id'] : ''; + $widget_base_id = isset($widget->id_base) ? (string) $widget->id_base : ''; + return aksrt_widget_is_allowed_in_sidebar($widget_base_id, $sidebar_id) ? $instance : false; +} +add_filter('widget_display_callback', 'aksrt_filter_widget_display_by_area', 10, 3); + +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); diff --git a/inc/modules/widget-common.php b/inc/modules/widget-common.php deleted file mode 100644 index c26baba8..00000000 --- a/inc/modules/widget-common.php +++ /dev/null @@ -1,638 +0,0 @@ - - */ - function aksrt_widget_common_defaults(): array { - return [ - 'subtitle' => '', - 'title_style' => '', - 'title_highlight' => '', - 'title_highlight_color'=> 'focus-color', - 'title_link' => ['url' => '', 'text' => '', 'target' => ''], - 'title_link2' => ['url' => '', 'text' => '', 'target' => ''], - 'title_link3' => ['url' => '', 'text' => '', 'target' => ''], - 'title_link_style' => ['color_1' => 'jb-blue', 'color_2' => 'jb-yellow', 'color_3' => 'jb-green'], - 'sidebar_affix' => false, - 'show_type' => 'all', - 'show_id_type' => '', - 'show_ids' => '', - 'animation_in' => '', - 'animation_repeat' => false, - 'layout_pin_pc' => ['top' => '', 'bottom' => ''], - 'layout_pin_m' => ['top' => '', 'bottom' => ''], - 'layout_bg' => ['img_white' => [], 'img_dark' => []], - ]; - } -} - -if (!function_exists('aksrt_widget_normalize_link')) { - /** - * Normalize a title_linkN array {url,text,target}. - * - * @param mixed $raw - * @return array{url:string,text:string,target:string} - */ - function aksrt_widget_normalize_link($raw): array { - $raw = is_array($raw) ? $raw : []; - return [ - 'url' => esc_url_raw(trim((string) ($raw['url'] ?? ''))), - 'text' => sanitize_text_field((string) ($raw['text'] ?? '')), - 'target' => ($raw['target'] ?? '') === '_blank' ? '_blank' : '', - ]; - } -} - -if (!function_exists('aksrt_widget_normalize_common')) { - /** - * Normalize common widget instance fields, filling defaults for legacy instances. - * - * Accepts both the new structured shape (title_link as array) and legacy - * flat shapes (title_link as URL string, in_affix bool) emitted by older - * widget versions, normalizing them onto the canonical shared schema. - * - * @param array- - - -
- $instance Current widget instance. - */ - function aksrt_widget_render_common_form(array $instance): void { - $instance = aksrt_widget_normalize_common($instance); - $pin_pc = $instance['layout_pin_pc']; - $pin_m = $instance['layout_pin_m']; - $bg_w = $instance['layout_bg']['img_white']; - $bg_d = $instance['layout_bg']['img_dark']; - ?> -- -
-- - - -
-- -
-- -
- - - - - - -- - - - -
- - - -- - - - -
-- - - - -
-- -
-- -
-- -
-- -
- - -- -
-- -
-- - -
-- - -
- $new_instance - * @param array' . esc_html($subtitle) . '
' : ''; - return '%s
', - 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. */ diff --git a/src/Widgets/ButtonsWidget.php b/src/Widgets/ButtonsWidget.php index 1b000775..d7b89b56 100644 --- a/src/Widgets/ButtonsWidget.php +++ b/src/Widgets/ButtonsWidget.php @@ -7,17 +7,15 @@ namespace AKSRT\Widgets; -use AKSRT\Widgets\Traits\CommonWidgetFields; defined('ABSPATH') || exit; class ButtonsWidget extends \WP_Widget { - use CommonWidgetFields; public function __construct() { parent::__construct('aksrt_buttons', esc_html__('AKSRT 按钮组', 'aksrt'), [ - 'description' => esc_html__('显示一组自定义按钮,支持外链跳转、色系与入场动画。', 'aksrt'), + 'description' => esc_html__('显示一组自定义按钮,支持外链跳转与色系。', 'aksrt'), 'classname' => 'widget_aksrt_buttons', ]); } @@ -60,8 +58,6 @@ class ButtonsWidget extends \WP_Widget { if (!in_array($m_pad, ['small', 'medium', 'large'], true)) { $m_pad = 'medium'; } - $anim = sanitize_key((string) ($instance['obs_animation'] ?? '')); - $anim_repeat = !empty($instance['animation_repeat']); $pc_width = max(0, min(400, (int) ($instance['pc_width'] ?? 0))); $m_width = max(0, min(400, (int) ($instance['m_width'] ?? 0))); @@ -74,7 +70,6 @@ class ButtonsWidget extends \WP_Widget { } $buts = ''; - $key = 0; foreach ($buttons as $btn) { if (!is_array($btn)) { continue; @@ -122,19 +117,13 @@ class ButtonsWidget extends \WP_Widget { $left_html = $icon_left !== '' ? ' ' : ''; $right_html = $icon_right !== '' ? ' ' : ''; - $anim_pack = function_exists('aksrt_obs_animate_attrs') - ? aksrt_obs_animate_attrs($anim, $anim_repeat, $key * 0.15) - : ['class' => '', 'attr' => '']; - $tgt = $target !== '' && strpos($url, 'javascript:') !== 0 ? ' target="' . esc_attr($target) . '" rel="noopener noreferrer"' : ''; - $buts .= '- -
$btn) : ?>