PluginProbe
King Addons for Elementor – 80+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce, Mega Menu, Popup Builder / 51.1.74
King Addons for Elementor – 80+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce, Mega Menu, Popup Builder v51.1.74
51.1.83 51.1.82 51.1.81 51.1.79 51.1.78 51.1.77 51.1.76 51.1.74 51.1.75 51.1.65 51.1.64 51.1.63 trunk 51.1.14 51.1.2 51.1.35 51.1.36 51.1.37 51.1.38 51.1.39 51.1.44 51.1.45 51.1.46 51.1.47 51.1.49 All 37 releases
king-addons / includes / helpers / Theme_Builder / Admin_List_Table.php

Admin_List_Table.php in King Addons for Elementor – 80+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce, Mega Menu, Popup Builder 51.1.74, at includes/helpers/Theme_Builder/Admin_List_Table.php

277 lines 9.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Theme Builder admin list table.
4 *
5 * @package King_Addons
6 */
7
8 namespace King_Addons\Theme_Builder;
9
10 use WP_List_Table;
11
12 if (!defined('ABSPATH')) {
13 exit;
14 }
15
16 if (!class_exists('WP_List_Table')) {
17 require_once ABSPATH . 'wp-admin/includes/class-wp-list-table.php';
18 }
19
20 /**
21 * Renders Theme Builder templates list in admin.
22 */
23 class Admin_List_Table extends WP_List_Table
24 {
25 /**
26 * Templates data.
27 *
28 * @var array<int,array<string,mixed>>
29 */
30 private array $items_data;
31
32 /**
33 * Base page URL.
34 *
35 * @var string
36 */
37 private string $base_url;
38
39 /**
40 * Constructor.
41 *
42 * @param array<int,array<string,mixed>> $items Templates.
43 * @param string $base_url Base admin page URL.
44 */
45 public function __construct(array $items, string $base_url)
46 {
47 parent::__construct([
48 'plural' => 'templates',
49 'singular' => 'template',
50 'ajax' => false,
51 ]);
52
53 $this->items_data = $items;
54 $this->base_url = $base_url;
55 }
56
57 /**
58 * Define table columns.
59 *
60 * @return array<string,string>
61 */
62 public function get_columns(): array
63 {
64 return [
65 'cb' => '<input type="checkbox" />',
66 'title' => esc_html__('Title', 'king-addons'),
67 'type' => esc_html__('Type', 'king-addons'),
68 'location' => esc_html__('Location', 'king-addons'),
69 'conditions' => esc_html__('Conditions', 'king-addons'),
70 'priority' => esc_html__('Priority', 'king-addons'),
71 'status' => esc_html__('Status', 'king-addons'),
72 'pro' => esc_html__('Pro', 'king-addons'),
73 ];
74 }
75
76 /**
77 * Sortable columns.
78 *
79 * @return array<string,array<int,string>>
80 */
81 protected function get_sortable_columns(): array
82 {
83 return [
84 'title' => ['title', false],
85 'priority' => ['priority', false],
86 ];
87 }
88
89 /**
90 * Prepare items with filters and pagination.
91 *
92 * @return void
93 */
94 public function prepare_items(): void
95 {
96 // Set column headers - required for WP_List_Table to display properly
97 $this->_column_headers = [
98 $this->get_columns(),
99 [], // hidden columns
100 $this->get_sortable_columns(),
101 ];
102
103 $data = $this->filter_items($this->items_data);
104
105 $per_page = 20;
106 $current_page = $this->get_pagenum();
107 $total_items = count($data);
108
109 $this->items = array_slice($data, ($current_page - 1) * $per_page, $per_page);
110 $this->set_pagination_args([
111 'total_items' => $total_items,
112 'per_page' => $per_page,
113 ]);
114 }
115
116 /**
117 * Render checkbox column.
118 *
119 * @param array<string,mixed> $item Row item.
120 *
121 * @return string
122 */
123 protected function column_cb($item): string
124 {
125 return '<input type="checkbox" name="template_ids[]" value="' . esc_attr((string) $item['id']) . '" />';
126 }
127
128 /**
129 * Render title column with actions.
130 *
131 * @param array<string,mixed> $item Row item.
132 *
133 * @return string
134 */
135 public function column_title($item): string
136 {
137 $title = !empty($item['title']) ? esc_html($item['title']) : esc_html__('(no title)', 'king-addons');
138 $edit_link = esc_url(admin_url('post.php?post=' . $item['id'] . '&action=elementor'));
139 $quick_link = '#';
140 $toggle_action = !empty($item['enabled']) ? 'disable_template' : 'enable_template';
141 $toggle_link = esc_url(wp_nonce_url(add_query_arg(['action' => $toggle_action, 'template_id' => $item['id']], $this->base_url), 'ka_theme_builder_toggle_' . $item['id']));
142 $delete_link = esc_url(wp_nonce_url(add_query_arg(['action' => 'delete_template', 'template_id' => $item['id']], $this->base_url), 'ka_theme_builder_delete_' . $item['id']));
143
144 $title_html = '<strong><a href="' . $edit_link . '">' . $title . '</a></strong>';
145
146 $actions = [
147 'edit' => '<a href="' . $edit_link . '">' . esc_html__('Edit in Elementor', 'king-addons') . '</a>',
148 'quick_edit' => '<a href="' . $quick_link . '" class="ka-tb-quick-edit" data-template-id="' . esc_attr((string) $item['id']) . '" data-priority="' . esc_attr((string) ($item['priority'] ?? '')) . '" data-enabled="' . (!empty($item['enabled']) ? '1' : '0') . '">' . esc_html__('Quick Edit', 'king-addons') . '</a>',
149 'toggle' => '<a href="' . $toggle_link . '">' . (!empty($item['enabled']) ? esc_html__('Disable', 'king-addons') : esc_html__('Enable', 'king-addons')) . '</a>',
150 'delete' => '<a href="' . $delete_link . '" style="color: #ff3b30;">' . esc_html__('Delete', 'king-addons') . '</a>',
151 ];
152
153 if (function_exists('king_addons_freemius') && king_addons_freemius()->can_use_premium_code__premium_only()) {
154 $duplicate_link = wp_nonce_url(
155 admin_url('admin-post.php?action=ka_theme_builder_duplicate&template_id=' . $item['id']),
156 'ka_theme_builder_duplicate_' . $item['id']
157 );
158 $actions['duplicate'] = '<a href="' . esc_url($duplicate_link) . '">' . esc_html__('Duplicate', 'king-addons') . '</a>';
159 }
160
161 return $title_html . $this->row_actions($actions);
162 }
163
164 /**
165 * Render default column output.
166 *
167 * @param array<string,mixed> $item Row item.
168 * @param string $column_name Column name.
169 *
170 * @return string
171 */
172 public function column_default($item, $column_name): string
173 {
174 switch ($column_name) {
175 case 'type':
176 return esc_html($item['type'] ?? '');
177 case 'location':
178 return esc_html($item['sub_location'] ?? '');
179 case 'priority':
180 return esc_html((string) ($item['priority'] ?? ''));
181 case 'status':
182 return !empty($item['enabled']) ? esc_html__('Enabled', 'king-addons') : esc_html__('Disabled', 'king-addons');
183 case 'conditions':
184 return esc_html($this->summarize_conditions($item['conditions'] ?? []));
185 case 'pro':
186 return !empty($item['is_pro_only']) ? esc_html__('Pro', 'king-addons') : esc_html__('Free', 'king-addons');
187 default:
188 return '';
189 }
190 }
191
192 /**
193 * Views for filters.
194 *
195 * @return array<string,string>
196 */
197 protected function get_views(): array
198 {
199 $current = $_GET['status'] ?? 'all'; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
200 $base = remove_query_arg(['status', 'paged'], $this->base_url);
201
202 $views = [
203 'all' => '<a href="' . esc_url($base) . '"' . ('all' === $current ? ' class="current"' : '') . '>' . esc_html__('All', 'king-addons') . '</a>',
204 'enabled' => '<a href="' . esc_url(add_query_arg('status', 'enabled', $base)) . '"' . ('enabled' === $current ? ' class="current"' : '') . '>' . esc_html__('Enabled', 'king-addons') . '</a>',
205 'disabled' => '<a href="' . esc_url(add_query_arg('status', 'disabled', $base)) . '"' . ('disabled' === $current ? ' class="current"' : '') . '>' . esc_html__('Disabled', 'king-addons') . '</a>',
206 ];
207
208 return $views;
209 }
210
211 /**
212 * Filter items by query args.
213 *
214 * @param array<int,array<string,mixed>> $items Items.
215 *
216 * @return array<int,array<string,mixed>>
217 */
218 private function filter_items(array $items): array
219 {
220 $status_filter = $_GET['status'] ?? ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
221 $type_filter = $_GET['type'] ?? ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
222 $location_filter = $_GET['location'] ?? ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
223
224 $filtered = array_filter(
225 $items,
226 static function ($item) use ($status_filter, $type_filter, $location_filter) {
227 if ('enabled' === $status_filter && empty($item['enabled'])) {
228 return false;
229 }
230 if ('disabled' === $status_filter && !empty($item['enabled'])) {
231 return false;
232 }
233 if (!empty($type_filter) && ($item['type'] ?? '') !== $type_filter) {
234 return false;
235 }
236 if (!empty($location_filter) && ($item['sub_location'] ?? '') !== $location_filter) {
237 return false;
238 }
239 return true;
240 }
241 );
242
243 return array_values($filtered);
244 }
245
246 /**
247 * Summarize conditions to human-friendly string.
248 *
249 * @param array<string,mixed> $conditions Conditions payload.
250 *
251 * @return string
252 */
253 private function summarize_conditions(array $conditions): string
254 {
255 $groups = $conditions['groups'] ?? [];
256 if (empty($groups)) {
257 return esc_html__('All', 'king-addons');
258 }
259
260 $summary = [];
261 foreach ($groups as $group) {
262 $rules = $group['rules'] ?? [];
263 $summary[] = sprintf(
264 /* translators: %d: number of rules */
265 esc_html__('%d rules', 'king-addons'),
266 count($rules)
267 );
268 }
269
270 return implode(' / ', $summary);
271 }
272 }
273
274
275
276
277