PluginProbe
Extendify / 3.1.5
Extendify v3.1.5
3.2.0 3.1.6 3.1.5 3.1.4 3.1.3 3.1.2 3.1.1 3.1.0 3.0.6 3.0.5 3.0.4 trunk 0.1.0 0.10.0 0.10.1 0.10.2 0.11.0 0.11.1 0.2.0 0.3.0 0.3.1 0.4.0 0.5.0 0.6.0 0.7.0 All 126 releases
extendify / app / PluginNotifications / NotificationsListTable.php

NotificationsListTable.php in Extendify 3.1.5, at app/PluginNotifications/NotificationsListTable.php

237 lines 7.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace Extendify\PluginNotifications;
4
5 defined('ABSPATH') || die('No direct access.');
6
7 // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
8 class NotificationsListTable extends \WP_List_Table
9 {
10 public function __construct()
11 {
12 parent::__construct([
13 'singular' => 'notification',
14 'plural' => 'notifications',
15 'ajax' => false,
16 ]);
17 }
18
19 public function get_columns()
20 {
21 return [
22 'cb' => '<input type="checkbox" />',
23 'source' => \__('Plugin', 'extendify-local'),
24 'type' => \__('Type', 'extendify-local'),
25 'first_seen' => \__('Date', 'extendify-local'),
26 ];
27 }
28
29 public function get_sortable_columns()
30 {
31 return [
32 'source' => ['source_name', false],
33 'type' => ['notice_type', false],
34 'first_seen' => ['first_seen', true],
35 ];
36 }
37
38 protected function get_views()
39 {
40 $allNotices = Admin::getNotices('all');
41 $activeCount = count(array_filter($allNotices, function ($n) {
42 return !$n['dismissed'];
43 }));
44 $dismissedCount = count(array_filter($allNotices, function ($n) {
45 return $n['dismissed'];
46 }));
47 $totalCount = count($allNotices);
48
49 // phpcs:ignore WordPress.Security.NonceVerification.Recommended
50 $current = sanitize_text_field(wp_unslash($_REQUEST['filter'] ?? 'active'));
51 $baseUrl = \admin_url('index.php?page=extendify-notifications');
52
53 return [
54 'active' => sprintf(
55 '<a href="%s" class="%s">%s <span class="count">(%d)</span></a>',
56 esc_url($baseUrl . '&filter=active'),
57 $current === 'active' ? 'current' : '',
58 \__('Active', 'extendify-local'),
59 $activeCount
60 ),
61 'all' => sprintf(
62 '<a href="%s" class="%s">%s <span class="count">(%d)</span></a>',
63 esc_url($baseUrl . '&filter=all'),
64 $current === 'all' ? 'current' : '',
65 \__('All', 'extendify-local'),
66 $totalCount
67 ),
68 'dismissed' => sprintf(
69 '<a href="%s" class="%s">%s <span class="count">(%d)</span></a>',
70 esc_url($baseUrl . '&filter=dismissed'),
71 $current === 'dismissed' ? 'current' : '',
72 \__('Dismissed', 'extendify-local'),
73 $dismissedCount
74 ),
75 ];
76 }
77
78 protected function get_bulk_actions()
79 {
80 return [
81 'bulk-dismiss' => \__('Dismiss', 'extendify-local'),
82 ];
83 }
84
85 public function prepare_items()
86 {
87 $this->_column_headers = [
88 $this->get_columns(),
89 [],
90 $this->get_sortable_columns(),
91 ];
92
93 $this->process_bulk_action();
94
95 // phpcs:ignore WordPress.Security.NonceVerification.Recommended
96 $filter = sanitize_text_field(wp_unslash($_REQUEST['filter'] ?? 'active'));
97 $items = array_values(Admin::getNotices($filter));
98
99 $allowedOrderby = ['first_seen', 'source_name', 'notice_type'];
100 // phpcs:ignore WordPress.Security.NonceVerification.Recommended
101 $orderby = sanitize_text_field(wp_unslash($_REQUEST['orderby'] ?? 'first_seen'));
102 if (!in_array($orderby, $allowedOrderby, true)) {
103 $orderby = 'first_seen';
104 }
105
106 // phpcs:ignore WordPress.Security.NonceVerification.Recommended
107 $order = sanitize_text_field(wp_unslash($_REQUEST['order'] ?? 'desc'));
108
109 usort($items, function ($a, $b) use ($orderby, $order) {
110 $result = strcmp($a[$orderby] ?? '', $b[$orderby] ?? '');
111 return $order === 'asc' ? $result : -$result;
112 });
113
114 $perPage = 20;
115 $currentPage = $this->get_pagenum();
116 $totalItems = count($items);
117
118 $this->items = array_slice($items, ($currentPage - 1) * $perPage, $perPage);
119
120 $this->set_pagination_args([
121 'total_items' => $totalItems,
122 'per_page' => $perPage,
123 'total_pages' => ceil($totalItems / $perPage),
124 ]);
125 }
126
127 public function process_bulk_action()
128 {
129 if ($this->current_action() !== 'bulk-dismiss') {
130 return;
131 }
132
133 check_admin_referer('extendify_notifications_bulk', '_extendify_nonce');
134
135 // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
136 $ids = array_map('sanitize_text_field', wp_unslash($_REQUEST['notification'] ?? []));
137
138 foreach ($ids as $id) {
139 Admin::dismissNotice($id);
140 }
141 }
142
143 public function column_cb($item)
144 {
145 return sprintf(
146 '<input type="checkbox" name="notification[]" value="%s" />',
147 esc_attr($item['id'])
148 );
149 }
150
151 public function column_source($item)
152 {
153 $name = esc_html($item['source_name'] ?? 'WordPress');
154
155 $dismissUrl = wp_nonce_url(
156 \admin_url('index.php?page=extendify-notifications&extendify_action=dismiss&notice_id=' . $item['id']),
157 'extendify_notifications_action',
158 '_extendify_nonce'
159 );
160
161 $actions = [
162 'view' => sprintf(
163 '<a href="#" class="extendify-notice-toggle" data-notice-id="%s">%s</a>',
164 esc_attr($item['id']),
165 esc_html__('View', 'extendify-local')
166 ),
167 ];
168
169 if (!$item['dismissed']) {
170 $actions['dismiss'] = sprintf(
171 '<a href="%s">%s</a>',
172 esc_url($dismissUrl),
173 esc_html__('Dismiss', 'extendify-local')
174 );
175 }
176
177 return sprintf('<strong>%s</strong>%s', $name, $this->row_actions($actions));
178 }
179
180 public function column_type($item)
181 {
182 $type = $item['notice_type'] ?? 'info';
183 $labels = [
184 'error' => \__('Error', 'extendify-local'),
185 'warning' => \__('Warning', 'extendify-local'),
186 'success' => \__('Success', 'extendify-local'),
187 'info' => \__('Info', 'extendify-local'),
188 ];
189
190 return sprintf(
191 '<span class="extendify-notice-badge type-%s">%s</span>',
192 esc_attr($type),
193 esc_html($labels[$type] ?? $labels['info'])
194 );
195 }
196
197 public function column_first_seen($item)
198 {
199 $timestamp = strtotime($item['first_seen']);
200
201 return sprintf(
202 '<span title="%s">%s</span>',
203 esc_attr(date_i18n(get_option('date_format') . ' ' . get_option('time_format'), $timestamp)),
204 esc_html(human_time_diff($timestamp, time()) . ' ' . \__('ago', 'extendify-local'))
205 );
206 }
207
208 public function single_row($item)
209 {
210 parent::single_row($item);
211
212 $content = preg_replace(
213 '/class="([^"]*\bnotice\b[^"]*)"/',
214 'class="$1 inline"',
215 $item['content']
216 );
217
218 $colspan = count($this->get_columns());
219 printf(
220 '<tr data-detail="%s" style="display:none" class="extendify-notice-detail"><td colspan="%d">%s</td></tr>',
221 esc_attr($item['id']),
222 (int) $colspan,
223 $content // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
224 );
225 }
226
227 protected function get_primary_column_name()
228 {
229 return 'source';
230 }
231
232 protected function column_default($item, $columnName)
233 {
234 return esc_html($item[$columnName] ?? '');
235 }
236 }
237