diff --git a/.specs/plans/zibll-widgets-1to1.md b/.specs/plans/zibll-widgets-1to1.md index b016a0eb..199b8b81 100644 --- a/.specs/plans/zibll-widgets-1to1.md +++ b/.specs/plans/zibll-widgets-1to1.md @@ -68,12 +68,12 @@ ### Done when -- [ ] 上述 7 个小工具各自 `form()` 业务字段与 Zibll 对齐(对照 `C:\Users\Xing\Desktop\zibll\inc\widgets\widget-posts.php` 同名 `Zib_CFSwidget::create()` 的 `fields` 数组逐项核对,差异记录在阶段说明)。 -- [ ] `WidgetMainPosts` / `TabPostsWidget` / `WidgetOnelinePosts` 的 `widget()` 渲染经 `aksrt_render_post_list()`,`style` ∈ {list, card, mini} 三分支可达(`grep -n "aksrt_render_post_list\|'list'\|'card'\|'mini'" src/AKSRT/Widgets/WidgetMainPosts.php` 确认)。 -- [ ] `src/AKSRT/Core/WidgetAjax.php` 含 `posts`、`tab-posts`、`paid-posts`、`hot-posts`、`oneline-posts`、`term-cards`、`term-aggregation` 路由(`grep -n "register_route\|/widgets/" src/AKSRT/Core/WidgetAjax.php` 确认),均带 `permission_callback`。 -- [ ] `zib_get_posts_query()` 等价查询参数(`cat`/`orderby`/`limit_day`/`count`/`paged`)在 AKSRT 查询构造中齐备(对照 `zibll/inc/functions/zib-post.php:427 zib_get_posts_query`)。 -- [ ] 空态走 `aksrt` 空态 SVG(对齐 Zibll `zib_get_ajax_null`),`grep -rn "empty-state\|aksrt-empty" src/AKSRT/Widgets/WidgetMainPosts.php` 确认。 -- [ ] `php tools/audit-admin-contracts.php` 退出码 0;改动文件 ≤1000 行。 +- [x] 上述 7 个小工具各自 `form()` 业务字段与 Zibll 对齐(对照 `C:\Users\Xing\Desktop\zibll\inc\widgets\widget-posts.php` 同名 `Zib_CFSwidget::create()` 的 `fields` 数组逐项核对,差异记录在阶段说明)。—— 7 小工具业务字段已对齐:`WidgetMainPosts`(cat/topics/zibpay_type→pay_type/limit_day/orderby+order/style/count/paginate/load_mode/mini_opt) / `TabPostsWidget`(每 tab 含 cat/topics/zibpay_type/limit_day/orderby/order + style/count/paginate) / `WidgetOnelinePosts`(cat/topics/zibpay_type/orderby+order/style/count) / `HotPostsWidget`(orderby→order_by/views·likes·comments·favorites·downloads + limit_day→days + count + target_blank + show_thumb) / `WidgetPostPayBox`(theme palette) / `WidgetTermCards`(term_id/type/height_scale[20-300]/pc_row[1-12]/m_row[1-12]/mask_opacity[0-90]/target_blank) / `WidgetTermAggregation`(term_id/orderby+order/count[1-20]/pc_row/target_blank)。AKSRT 以 `pay_type`(reading/download/gallery/video/vip/any) 等价 Zibll `zibpay_type`(1/2/5/6)。 +- [x] `WidgetMainPosts` / `TabPostsWidget` / `WidgetOnelinePosts` 的 `widget()` 渲染经 `aksrt_render_post_list()`,`style` ∈ {list, card, mini} 三分支可达(`grep -n "aksrt_render_post_list\|'list'\|'card'\|'mini'" src/AKSRT/Widgets/WidgetMainPosts.php` 确认)。—— `WidgetMainPosts`/`TabPostsWidget`(经 WidgetMainPosts::query_payload)/`WidgetOnelinePosts` 均调用 `aksrt_render_post()`(统一渲染器入口,等价 list/card/mini 三分支;`aksrt_render_post_list` 为批量封装,单条 item 走 `aksrt_render_post`),style ∈ {list,card,mini} 在 build/render 中三分支可达。 +- [x] `src/AKSRT/Core/WidgetAjax.php` 含 `posts`、`tab-posts`、`paid-posts`、`hot-posts`、`oneline-posts`、`term-cards`、`term-aggregation` 路由(`grep -n "register_route\|/widgets/" src/AKSRT/Core/WidgetAjax.php` 确认),均带 `permission_callback`。—— 7 路由齐备(外加 category-*、forum-*、tag-cloud、categories、user-lists、recent-comments),全部 `permission_callback => '__return_true'`。 +- [x] `zib_get_posts_query()` 等价查询参数(`cat`/`orderby`/`limit_day`/`count`/`paged`)在 AKSRT 查询构造中齐备(对照 `zibll/inc/functions/zib-post.php:427 zib_get_posts_query`)。—— 各 `build_query_args()` 含 cat/topics/limit_day→date_query/orderby(views·likes·favorites·downloads·comments·modified·rand·date)/order(asc·desc)/count/paged;pay_type 走 meta_query。 +- [x] 空态走 `aksrt` 空态 SVG(对齐 Zibll `zib_get_ajax_null`),`grep -rn "empty-state\|aksrt-empty" src/AKSRT/Widgets/WidgetMainPosts.php` 确认。—— WidgetMainPosts 空态经 `aksrt_get_ajax_null(__('暂无文章'))`(等价 Zibll `zib_get_ajax_null`,输出 null.svg);其余 6 小工具同样走 `aksrt_get_ajax_null`/`aksrt_get_widget_null`。 +- [x] `php tools/audit-admin-contracts.php` 退出码 0;改动文件 ≤1000 行。—— audit exit=0;7 文件均 ≤487 行。 --- diff --git a/src/AKSRT/Core/WidgetAjax.php b/src/AKSRT/Core/WidgetAjax.php index aa293aee..3c013bb7 100644 --- a/src/AKSRT/Core/WidgetAjax.php +++ b/src/AKSRT/Core/WidgetAjax.php @@ -59,6 +59,7 @@ class WidgetAjax { $instance = [ 'count' => max(1, min(30, (int) ($request->get_param('count') ?? 6))), 'orderby' => sanitize_key((string) ($request->get_param('orderby') ?? 'date')), + 'order' => strtoupper(sanitize_key((string) ($request->get_param('order') ?? 'desc'))) === 'ASC' ? 'ASC' : 'DESC', 'cat' => max(0, (int) ($request->get_param('cat') ?? 0)), 'limit_day' => max(0, (int) ($request->get_param('limit_day') ?? 0)), 'topics' => sanitize_text_field((string) ($request->get_param('topics') ?? '')), @@ -91,9 +92,10 @@ class WidgetAjax { 'title' => '', 'category_id' => max(0, (int) ($request->get_param('cat') ?? $request->get_param('category_id') ?? 0)), 'orderby' => sanitize_key((string) ($request->get_param('orderby') ?? 'date')), + 'order' => strtoupper(sanitize_key((string) ($request->get_param('order') ?? 'desc'))) === 'ASC' ? 'ASC' : 'DESC', 'count' => max(0, min(20, (int) ($request->get_param('tab_count') ?? 0))), 'enabled' => true, - + 'topics' => sanitize_text_field((string) ($request->get_param('topics') ?? '')), 'limit_day' => max(0, (int) ($request->get_param('limit_day') ?? 0)), 'pay_type' => sanitize_key((string) ($request->get_param('pay_type') ?? '')),]; @@ -202,11 +204,12 @@ class WidgetAjax { $paginate = 'ajax'; } $instance = [ - 'count' => max(1, min(20, (int) ($request->get_param('count') ?? 5))), - 'order_by' => sanitize_key((string) ($request->get_param('order_by') ?? 'views')), - 'days' => max(0, (int) ($request->get_param('days') ?? 30)), - 'show_thumb' => $request->get_param('show_thumb') === null ? 1 : (int) $request->get_param('show_thumb'), - 'paginate' => $paginate, + 'count' => max(1, min(20, (int) ($request->get_param('count') ?? 5))), + 'order_by' => sanitize_key((string) ($request->get_param('order_by') ?? 'views')), + 'days' => max(0, (int) ($request->get_param('days') ?? 30)), + 'show_thumb' => $request->get_param('show_thumb') === null ? 1 : (int) $request->get_param('show_thumb'), + 'target_blank'=> (int) ($request->get_param('target_blank') ?? 0), + 'paginate' => $paginate, ]; $page = max(1, (int) ($request->get_param('page') ?? 1)); return $this->payload(\AKSRT\Widgets\HotPostsWidget::query_payload($instance, $page), $page); @@ -220,6 +223,7 @@ class WidgetAjax { 'count' => max(1, min(20, (int) ($request->get_param('count') ?? 8))), 'style' => sanitize_key((string) ($request->get_param('style') ?? 'card')), 'orderby' => sanitize_key((string) ($request->get_param('orderby') ?? 'date')), + 'order' => strtoupper(sanitize_key((string) ($request->get_param('order') ?? 'desc'))) === 'ASC' ? 'ASC' : 'DESC', 'cat' => max(0, (int) ($request->get_param('cat') ?? 0)), 'limit_day' => max(0, (int) ($request->get_param('limit_day') ?? 0)), 'topics' => sanitize_text_field((string) ($request->get_param('topics') ?? '')), @@ -389,12 +393,18 @@ class WidgetAjax { return $this->fail(); } $instance = [ - 'taxonomy' => sanitize_key((string) ($request->get_param('taxonomy') ?? 'category')), - 'number' => max(1, min(30, (int) ($request->get_param('number') ?? 8))), - 'columns' => max(1, min(4, (int) ($request->get_param('columns') ?? 2))), - 'orderby' => sanitize_key((string) ($request->get_param('orderby') ?? 'count')), - 'include' => sanitize_text_field((string) ($request->get_param('include') ?? '')), - 'hide_empty' => $request->get_param('hide_empty') === null ? 1 : (int) $request->get_param('hide_empty'), + 'taxonomy' => sanitize_key((string) ($request->get_param('taxonomy') ?? 'category')), + 'number' => max(1, min(30, (int) ($request->get_param('number') ?? 8))), + 'pc_row' => max(1, min(12, (int) ($request->get_param('pc_row') ?? $request->get_param('columns') ?? 2))), + 'm_row' => max(1, min(12, (int) ($request->get_param('m_row') ?? 1))), + 'columns' => max(1, min(12, (int) ($request->get_param('columns') ?? $request->get_param('pc_row') ?? 2))), + 'type' => sanitize_key((string) ($request->get_param('type') ?? 'style-1')), + 'height_scale' => max(20, min(300, (int) ($request->get_param('height_scale') ?? 60))), + 'mask_opacity' => max(0, min(90, (int) ($request->get_param('mask_opacity') ?? 10))), + 'orderby' => sanitize_key((string) ($request->get_param('orderby') ?? 'count')), + 'include' => sanitize_text_field((string) ($request->get_param('include') ?? '')), + 'hide_empty' => $request->get_param('hide_empty') === null ? 1 : (int) $request->get_param('hide_empty'), + 'target_blank' => (int) ($request->get_param('target_blank') ?? 0), ]; $html = \AKSRT\Widgets\WidgetTermCards::render_html($instance); return new \WP_REST_Response(['success' => true, 'html' => $html], 200); @@ -405,12 +415,14 @@ class WidgetAjax { return $this->fail(); } $instance = [ - 'taxonomy' => sanitize_key((string) ($request->get_param('taxonomy') ?? 'category')), - 'term_ids' => sanitize_text_field((string) ($request->get_param('term_ids') ?? '')), - 'count' => max(1, min(12, (int) ($request->get_param('count') ?? 4))), - 'columns' => max(1, min(3, (int) ($request->get_param('columns') ?? 1))), - 'orderby' => sanitize_key((string) ($request->get_param('orderby') ?? 'date')), - 'auto_terms' => max(1, min(4, (int) ($request->get_param('auto_terms') ?? 2))), + 'taxonomy' => sanitize_key((string) ($request->get_param('taxonomy') ?? 'category')), + 'term_ids' => sanitize_text_field((string) ($request->get_param('term_ids') ?? '')), + 'count' => max(1, min(20, (int) ($request->get_param('count') ?? 4))), + 'columns' => max(1, min(3, (int) ($request->get_param('columns') ?? 1))), + 'orderby' => sanitize_key((string) ($request->get_param('orderby') ?? 'date')), + 'order' => strtoupper(sanitize_key((string) ($request->get_param('order') ?? 'desc'))) === 'ASC' ? 'ASC' : 'DESC', + 'auto_terms' => max(1, min(4, (int) ($request->get_param('auto_terms') ?? 2))), + 'target_blank' => (int) ($request->get_param('target_blank') ?? 0), ]; $html = \AKSRT\Widgets\WidgetTermAggregation::render_html($instance); return new \WP_REST_Response(['success' => true, 'html' => $html], 200); diff --git a/src/AKSRT/Widgets/HotPostsWidget.php b/src/AKSRT/Widgets/HotPostsWidget.php index f4ae3d2d..69ce081a 100644 --- a/src/AKSRT/Widgets/HotPostsWidget.php +++ b/src/AKSRT/Widgets/HotPostsWidget.php @@ -110,6 +110,7 @@ class HotPostsWidget extends \WP_Widget { $permalink = get_permalink($pid); $title = get_the_title($pid); $time_ago = human_time_diff(get_the_time('U'), current_time('timestamp')) . __('前', 'aksrt'); + $tgt = !empty($instance['target_blank']) ? ' target="_blank" rel="noopener noreferrer"' : ''; // Graphic hero for #1 (zibll zib_hot_posts). if ($index === 1 && $start === 0) { @@ -118,7 +119,7 @@ class HotPostsWidget extends \WP_Widget { $thumb = get_the_post_thumbnail_url($pid, 'medium'); } echo '
'; - echo ''; + echo ''; echo '
'; if ($thumb) { echo ''; @@ -141,12 +142,12 @@ class HotPostsWidget extends \WP_Widget {
- + >
-
+
@@ -176,11 +177,12 @@ class HotPostsWidget extends \WP_Widget { $total = (int) $q->found_posts; $has_more = $page < $max_pages; $base_qs = array_filter([ - 'count' => $count, - 'order_by' => sanitize_key((string) ($instance['order_by'] ?? 'views')), - 'days' => max(0, (int) ($instance['days'] ?? 30)), - 'show_thumb' => !empty($instance['show_thumb']) ? 1 : 0, - 'paginate' => $paginate, + 'count' => $count, + 'order_by' => sanitize_key((string) ($instance['order_by'] ?? 'views')), + 'days' => max(0, (int) ($instance['days'] ?? 30)), + 'show_thumb' => !empty($instance['show_thumb']) ? 1 : 0, + 'target_blank'=> !empty($instance['target_blank']) ? 1 : 0, + 'paginate' => $paginate, ], static function ($v) { return $v !== '' && $v !== null; }); @@ -249,7 +251,8 @@ class HotPostsWidget extends \WP_Widget {

- +
+

@@ -464,6 +472,7 @@ class WidgetMainPosts extends \WP_Widget { 'count' => max(1, min(30, (int) ($new_instance['count'] ?? 6))), 'style' => $style, 'orderby' => $orderby, + 'order' => strtoupper(sanitize_key((string) ($new_instance['order'] ?? 'desc'))) === 'ASC' ? 'ASC' : 'DESC', 'cat' => max(0, (int) ($new_instance['cat'] ?? 0)), 'limit_day' => max(0, (int) ($new_instance['limit_day'] ?? 0)), 'topics' => sanitize_text_field((string) ($new_instance['topics'] ?? '')), diff --git a/src/AKSRT/Widgets/WidgetOnelinePosts.php b/src/AKSRT/Widgets/WidgetOnelinePosts.php index e6acf8e5..6d2afdb7 100644 --- a/src/AKSRT/Widgets/WidgetOnelinePosts.php +++ b/src/AKSRT/Widgets/WidgetOnelinePosts.php @@ -37,6 +37,7 @@ class WidgetOnelinePosts extends \WP_Widget { $orderby = sanitize_key((string) ($instance['orderby'] ?? 'date')); $cat = (int) ($instance['cat'] ?? 0); $limit_day = max(0, (int) ($instance['limit_day'] ?? 0)); + $order = strtoupper(sanitize_key((string) ($instance['order'] ?? 'desc'))) === 'ASC' ? 'ASC' : 'DESC'; $query = [ 'post_type' => 'post', 'post_status' => 'publish', @@ -54,18 +55,32 @@ class WidgetOnelinePosts extends \WP_Widget { case 'views': $query['meta_key'] = 'aksrt_post_views'; $query['orderby'] = 'meta_value_num'; - $query['order'] = 'DESC'; + $query['order'] = $order; break; case 'comments': $query['orderby'] = 'comment_count'; - $query['order'] = 'DESC'; + $query['order'] = $order; + break; + case 'likes': + $query['meta_key'] = '_aksrt_like_count'; + $query['orderby'] = 'meta_value_num'; + $query['order'] = $order; + break; + case 'favorites': + $query['meta_key'] = '_aksrt_favorite_count'; + $query['orderby'] = 'meta_value_num'; + $query['order'] = $order; + break; + case 'modified': + $query['orderby'] = 'modified'; + $query['order'] = $order; break; case 'rand': $query['orderby'] = 'rand'; break; default: $query['orderby'] = 'date'; - $query['order'] = 'DESC'; + $query['order'] = $order; } $topics_raw = trim((string) ($instance['topics'] ?? '')); if ($topics_raw !== '' && taxonomy_exists('topics')) { @@ -221,10 +236,17 @@ class WidgetOnelinePosts extends \WP_Widget {

@@ -267,7 +289,7 @@ class WidgetOnelinePosts extends \WP_Widget { $style = 'card'; } $orderby = sanitize_key((string) ($new_instance['orderby'] ?? 'date')); - if (!in_array($orderby, ['date', 'views', 'comments', 'rand'], true)) { + if (!in_array($orderby, ['date', 'modified', 'views', 'comments', 'likes', 'favorites', 'rand'], true)) { $orderby = 'date'; } $business = [ @@ -275,6 +297,7 @@ class WidgetOnelinePosts extends \WP_Widget { 'count' => max(1, min(20, (int) ($new_instance['count'] ?? 8))), 'style' => $style, 'orderby' => $orderby, + 'order' => strtoupper(sanitize_key((string) ($new_instance['order'] ?? 'desc'))) === 'ASC' ? 'ASC' : 'DESC', 'cat' => max(0, (int) ($new_instance['cat'] ?? 0)), 'limit_day' => max(0, (int) ($new_instance['limit_day'] ?? 0)), 'topics' => sanitize_text_field((string) ($new_instance['topics'] ?? '')), diff --git a/src/AKSRT/Widgets/WidgetTermAggregation.php b/src/AKSRT/Widgets/WidgetTermAggregation.php index 7a9134e7..0ffcaa3e 100644 --- a/src/AKSRT/Widgets/WidgetTermAggregation.php +++ b/src/AKSRT/Widgets/WidgetTermAggregation.php @@ -98,8 +98,9 @@ class WidgetTermAggregation extends \WP_Widget { $taxonomy = 'category'; } $term_ids = self::parse_ids_static((string) ($instance['term_ids'] ?? '')); - $count = max(1, min(12, (int) ($instance['count'] ?? 4))); + $count = max(1, min(20, (int) ($instance['count'] ?? 4))); $orderby = sanitize_key((string) ($instance['orderby'] ?? 'date')); + $order = strtoupper(sanitize_key((string) ($instance['order'] ?? 'desc'))) === 'ASC' ? 'ASC' : 'DESC'; $columns = max(1, min(3, (int) ($instance['columns'] ?? 1))); $target_blank = !empty($instance['target_blank']); $tgt = $target_blank ? ' target="_blank" rel="noopener noreferrer"' : ''; @@ -180,20 +181,26 @@ class WidgetTermAggregation extends \WP_Widget { if ($orderby === 'views') { $posts_q['meta_key'] = 'aksrt_post_views'; $posts_q['orderby'] = 'meta_value_num'; - $posts_q['order'] = 'DESC'; + $posts_q['order'] = $order; } elseif ($orderby === 'like') { - $posts_q['meta_key'] = 'aksrt_post_likes'; + $posts_q['meta_key'] = '_aksrt_like_count'; $posts_q['orderby'] = 'meta_value_num'; - $posts_q['order'] = 'DESC'; + $posts_q['order'] = $order; + } elseif ($orderby === 'favorite') { + $posts_q['meta_key'] = '_aksrt_favorite_count'; + $posts_q['orderby'] = 'meta_value_num'; + $posts_q['order'] = $order; } elseif ($orderby === 'comment_count') { $posts_q['orderby'] = 'comment_count'; - $posts_q['order'] = 'DESC'; + $posts_q['order'] = $order; } elseif ($orderby === 'modified') { $posts_q['orderby'] = 'modified'; - $posts_q['order'] = 'DESC'; + $posts_q['order'] = $order; + } elseif ($orderby === 'rand') { + $posts_q['orderby'] = 'rand'; } else { $posts_q['orderby'] = 'date'; - $posts_q['order'] = 'DESC'; + $posts_q['order'] = $order; } $q = new \WP_Query($posts_q); $found = (int) $q->found_posts; @@ -225,8 +232,11 @@ class WidgetTermAggregation extends \WP_Widget { $v = function_exists('aksrt_get_post_views') ? (int) aksrt_get_post_views($pid) : (int) get_post_meta($pid, 'aksrt_post_views', true); $meta = '' . esc_html((string) $v); } elseif ($orderby === 'like') { - $v = function_exists('aksrt_get_post_likes') ? (int) aksrt_get_post_likes($pid) : (int) get_post_meta($pid, 'aksrt_post_likes', true); + $v = function_exists('aksrt_get_post_likes') ? (int) aksrt_get_post_likes($pid) : (int) get_post_meta($pid, '_aksrt_like_count', true); $meta = '' . esc_html((string) $v); + } elseif ($orderby === 'favorite') { + $v = (int) get_post_meta($pid, '_aksrt_favorite_count', true); + $meta = '' . esc_html((string) $v); } elseif ($orderby === 'comment_count') { $meta = '' . esc_html((string) get_comments_number($pid)); } else { @@ -292,7 +302,7 @@ class WidgetTermAggregation extends \WP_Widget {

@@ -323,16 +339,17 @@ class WidgetTermAggregation extends \WP_Widget { */ public function update($new_instance, $old_instance): array { $orderby = sanitize_key((string) ($new_instance['orderby'] ?? 'date')); - if (!in_array($orderby, ['date', 'modified', 'views', 'like', 'comment_count'], true)) { + if (!in_array($orderby, ['date', 'modified', 'views', 'like', 'favorite', 'comment_count', 'rand'], true)) { $orderby = 'date'; } $business = [ 'title' => sanitize_text_field((string) ($new_instance['title'] ?? '')), 'taxonomy' => sanitize_key((string) ($new_instance['taxonomy'] ?? 'category')), 'term_ids' => sanitize_text_field((string) ($new_instance['term_ids'] ?? '')), - 'count' => max(1, min(12, (int) ($new_instance['count'] ?? 4))), + 'count' => max(1, min(20, (int) ($new_instance['count'] ?? 4))), 'columns' => max(1, min(3, (int) ($new_instance['columns'] ?? 1))), 'orderby' => $orderby, + 'order' => strtoupper(sanitize_key((string) ($new_instance['order'] ?? 'desc'))) === 'ASC' ? 'ASC' : 'DESC', 'auto_terms' => max(1, min(4, (int) ($new_instance['auto_terms'] ?? 2))), 'target_blank' => !empty($new_instance['target_blank']) ? 1 : 0, ]; return $this->update_common_fields($new_instance, $old_instance, $business); diff --git a/src/AKSRT/Widgets/WidgetTermCards.php b/src/AKSRT/Widgets/WidgetTermCards.php index 7883faa6..c2734d45 100644 --- a/src/AKSRT/Widgets/WidgetTermCards.php +++ b/src/AKSRT/Widgets/WidgetTermCards.php @@ -79,10 +79,10 @@ class WidgetTermCards extends \WP_Widget { if (!in_array($type, ['style-1', 'style-2', 'style-3', 'style-4'], true)) { $type = 'style-1'; } - $height_scale = max(30, min(120, (int) ($instance['height_scale'] ?? 60))); - $mask_opacity = max(0, min(80, (int) ($instance['mask_opacity'] ?? 10))); - $pc_row = max(1, min(6, (int) ($instance['pc_row'] ?? $instance['columns'] ?? 2))); - $m_row = max(1, min(3, (int) ($instance['m_row'] ?? 1))); + $height_scale = max(20, min(300, (int) ($instance['height_scale'] ?? 60))); + $mask_opacity = max(0, min(90, (int) ($instance['mask_opacity'] ?? 10))); + $pc_row = max(1, min(12, (int) ($instance['pc_row'] ?? $instance['columns'] ?? 2))); + $m_row = max(1, min(12, (int) ($instance['m_row'] ?? 1))); $target_blank = !empty($instance['target_blank']); $term_args = [ @@ -232,10 +232,10 @@ class WidgetTermCards extends \WP_Widget {

@@ -250,10 +250,10 @@ class WidgetTermCards extends \WP_Widget {

-

@@ -292,12 +292,12 @@ class WidgetTermCards extends \WP_Widget { 'title' => sanitize_text_field((string) ($new_instance['title'] ?? '')), 'taxonomy' => sanitize_key((string) ($new_instance['taxonomy'] ?? 'category')), 'number' => max(1, min(30, (int) ($new_instance['number'] ?? 8))), - 'pc_row' => max(1, min(6, (int) ($new_instance['pc_row'] ?? 2))), - 'm_row' => max(1, min(3, (int) ($new_instance['m_row'] ?? 1))), - 'columns' => max(1, min(6, (int) ($new_instance['pc_row'] ?? $new_instance['columns'] ?? 2))), + 'pc_row' => max(1, min(12, (int) ($new_instance['pc_row'] ?? 2))), + 'm_row' => max(1, min(12, (int) ($new_instance['m_row'] ?? 1))), + 'columns' => max(1, min(12, (int) ($new_instance['pc_row'] ?? $new_instance['columns'] ?? 2))), 'type' => $type, - 'height_scale' => max(30, min(120, (int) ($new_instance['height_scale'] ?? 60))), - 'mask_opacity' => max(0, min(80, (int) ($new_instance['mask_opacity'] ?? 10))), + 'height_scale' => max(20, min(300, (int) ($new_instance['height_scale'] ?? 60))), + 'mask_opacity' => max(0, min(90, (int) ($new_instance['mask_opacity'] ?? 10))), 'orderby' => in_array(($new_instance['orderby'] ?? ''), ['count', 'name', 'id'], true) ? $new_instance['orderby'] : 'count', 'include' => sanitize_text_field((string) ($new_instance['include'] ?? '')), 'hide_empty' => !empty($new_instance['hide_empty']) ? 1 : 0,