PluginProbe
StoreEngine — Complete eCommerce Solution with Memberships, Licensing, Affiliates & More / 2.2.0
StoreEngine — Complete eCommerce Solution with Memberships, Licensing, Affiliates & More v2.2.0
2.3.0 2.2.0 2.1.1 2.1.0 2.0.0 1.10.0 1.9.1 1.9.0 1.2.1 1.2.2 1.3.0 1.3.1 1.3.2 1.3.3 1.4.0 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.5.5 1.5.6 1.5.7 1.5.8 1.6.0 All 59 releases
storeengine / includes / admin / screen-options.php

screen-options.php in StoreEngine — Complete eCommerce Solution with Memberships, Licensing, Affiliates & More 2.2.0, at includes/admin/screen-options.php

123 lines 3.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Per-user "Screen Options" storage + AJAX handler.
4 *
5 * All of a user's screen preferences (per-page fetch limit, table column
6 * visibility/order, …) for every admin screen live in ONE user-meta blob:
7 *
8 * storeengine_screen_options => [ 'v' => 1, 'screens' => [ '<screenId>' => [...] ] ]
9 *
10 * The blob is seeded into `StoreEngineGlobal.screen_options` at page load (see
11 * assets.php) so the React app has it on first paint with no extra request;
12 * changes are saved back with a small debounced AJAX call.
13 *
14 * @version 1.0.0
15 */
16
17 namespace StoreEngine\Admin;
18
19 use StoreEngine\Classes\AbstractAjaxHandler;
20
21 if ( ! defined( 'ABSPATH' ) ) {
22 exit;
23 }
24
25 class ScreenOptions extends AbstractAjaxHandler {
26
27 const META_KEY = 'storeengine_screen_options';
28
29 public function __construct() {
30 // `read` — every logged-in user manages only their OWN prefs; the
31 // storeengine_nonce (only localized on StoreEngine admin pages) gates it.
32 $this->actions = [
33 'save_screen_options' => [
34 'capability' => 'read',
35 'callback' => [ $this, 'save' ],
36 'fields' => [
37 'screen' => 'string',
38 'options' => 'string', // JSON blob for the one screen.
39 ],
40 ],
41 'reset_screen_options' => [
42 'capability' => 'read',
43 'callback' => [ $this, 'reset' ],
44 'fields' => [ 'screen' => 'string' ],
45 ],
46 ];
47 }
48
49 /**
50 * The current (or given) user's full screen-options blob, always normalised
51 * to `[ 'v' => 1, 'screens' => [...] ]`.
52 */
53 public static function get_all( ?int $user_id = null ): array {
54 $user_id = $user_id ?: get_current_user_id();
55 $data = $user_id ? get_user_meta( $user_id, self::META_KEY, true ) : [];
56 if ( ! is_array( $data ) ) {
57 $data = [];
58 }
59
60 $screens = isset( $data['screens'] ) && is_array( $data['screens'] ) ? $data['screens'] : [];
61
62 return [ 'v' => 1, 'screens' => $screens ];
63 }
64
65 public function save( array $payload ) {
66 $screen = sanitize_key( $payload['screen'] ?? '' );
67 $raw = is_string( $payload['options'] ?? null ) ? wp_unslash( $payload['options'] ) : '';
68 $options = json_decode( $raw, true );
69
70 if ( '' === $screen || ! is_array( $options ) ) {
71 wp_send_json_error( [ 'message' => __( 'Invalid screen options payload.', 'storeengine' ) ] );
72 }
73
74 $all = self::get_all();
75 $all['screens'][ $screen ] = self::sanitize_screen( $options );
76 update_user_meta( get_current_user_id(), self::META_KEY, $all );
77
78 wp_send_json_success( [ 'screen_options' => $all ] );
79 }
80
81 public function reset( array $payload ) {
82 $screen = sanitize_key( $payload['screen'] ?? '' );
83 $all = self::get_all();
84
85 if ( '' !== $screen && isset( $all['screens'][ $screen ] ) ) {
86 unset( $all['screens'][ $screen ] );
87 update_user_meta( get_current_user_id(), self::META_KEY, $all );
88 }
89
90 wp_send_json_success( [ 'screen_options' => $all ] );
91 }
92
93 /**
94 * Whitelist + clamp a single screen's options.
95 */
96 protected static function sanitize_screen( array $options ): array {
97 $out = [];
98
99 if ( isset( $options['per_page'] ) ) {
100 $out['per_page'] = max( 1, min( 200, (int) $options['per_page'] ) );
101 }
102
103 if ( isset( $options['columns'] ) && is_array( $options['columns'] ) ) {
104 $columns = [];
105 foreach ( $options['columns'] as $column ) {
106 if ( ! is_array( $column ) || empty( $column['id'] ) ) {
107 continue;
108 }
109 $columns[] = [
110 'id' => sanitize_text_field( (string) $column['id'] ),
111 'visible' => ! empty( $column['visible'] ),
112 'order' => isset( $column['order'] ) ? (int) $column['order'] : 0,
113 ];
114 }
115 $out['columns'] = $columns;
116 }
117
118 return $out;
119 }
120 }
121
122 // End of file screen-options.php.
123