PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.4.8
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.4.8
4.4.8 4.4.7 4.4.6 4.4.5 4.4.4 4.4.3 4.4.2 4.4.1 4.4.0 4.3.9.1 4.3.9 4.3.8 4.3.7 4.1.6.9 4.1.6.9.1 4.1.6.9.2 4.1.6.9.3 4.1.6.9.4 4.1.7 4.1.7.1 4.1.7.2 4.1.7.3 4.1.7.3.1 4.1.7.3.2 4.2.0 All 139 releases
← All changes | inc/admin/class-lp-admin-mcp-api-keys.php +239 -214 4.3.94.4.8 View file →
@@ -1,214 +1,239 @@
1 -<?php
2 -
3 -use LearnPress\MCP\Auth\ApiKeysRepository;
4 -
5 -defined( 'ABSPATH' ) || exit;
6 -
7 -/**
8 - * Admin controller for LearnPress MCP API keys UI and actions.
9 - */
10 -class LP_Admin_MCP_API_Keys {
11 - /**
12 - * @var self|null
13 - */
14 - protected static $instance;
15 -
16 - /**
17 - * @var ApiKeysRepository
18 - */
19 - protected $repository;
20 -
21 - /**
22 - * @var string
23 - */
24 - protected $required_capability = 'manage_options';
25 -
26 - /**
27 - * Get singleton instance for MCP API keys admin controller.
28 - *
29 - * @return self
30 - */
31 - public static function instance(): self {
32 - if ( ! self::$instance ) {
33 - self::$instance = new self();
34 - }
35 -
36 - return self::$instance;
37 - }
38 -
39 - /**
40 - * Register admin hooks and required table dependency.
41 - *
42 - * @return void
43 - */
44 - protected function __construct() {
45 - $this->repository = new ApiKeysRepository();
46 -
47 - add_action( 'admin_init', array( $this, 'handle_admin_actions' ) );
48 - add_action( 'admin_enqueue_scripts', array( $this, 'localize_admin_script' ) );
49 -
50 - require_once LP_PLUGIN_PATH . 'inc/admin/class-lp-admin-mcp-api-keys-table-list.php';
51 - }
52 -
53 - /**
54 - * Localize MCP API key settings and i18n labels to admin JavaScript.
55 - *
56 - * Data is exposed under `window.lpMcpApiKeysSettings` and consumed by
57 - * `lp-admin-mcp-api-keys` runtime script.
58 - *
59 - * @return void
60 - */
61 - public function localize_admin_script(): void {
62 - if ( ! LP_Settings_Mcp::is_mcp_available() || ! wp_script_is( 'lp-admin-mcp-api-keys', 'enqueued' ) ) {
63 - return;
64 - }
65 -
66 - wp_localize_script(
67 - 'lp-admin-mcp-api-keys',
68 - 'lpMcpApiKeysSettings',
69 - array(
70 - 'is_mcp_keys_section' => $this->is_mcp_keys_settings_screen(),
71 - 'actions' => array(
72 - 'create' => 'mcp_create_api_key',
73 - ),
74 - 'i18n' => array(
75 - 'processing' => __( 'Processing...', 'learnpress' ),
76 - 'created' => __( 'API key created.', 'learnpress' ),
77 - 'request_failed' => __( 'Request failed. Please try again.', 'learnpress' ),
78 - 'confirm_revoke' => __( 'Revoke this API key?', 'learnpress' ),
79 - 'copy_success' => __( 'Copied.', 'learnpress' ),
80 - 'copy_fallback' => __( 'Copy this value manually.', 'learnpress' ),
81 - ),
82 - )
83 - );
84 - }
85 -
86 - /**
87 - * Render MCP API key management screen inside LearnPress settings.
88 - *
89 - * Prepares list-table data and user options before loading the section template.
90 - *
91 - * @return void
92 - */
93 - public function render_page(): void {
94 - if ( ! current_user_can( $this->required_capability ) ) {
95 - wp_die( esc_html__( 'Sorry, you are not allowed to manage MCP API keys.', 'learnpress' ) );
96 - }
97 - if ( ! LP_Settings_Mcp::is_mcp_available() ) {
98 - return;
99 - }
100 -
101 - $table = new LP_Admin_MCP_API_Keys_Table_List( $this->repository );
102 - $table->prepare_items();
103 -
104 - $users = get_users(
105 - array(
106 - 'fields' => array( 'ID', 'user_login', 'display_name' ),
107 - 'orderby' => 'display_name',
108 - 'order' => 'ASC',
109 - 'number' => 200,
110 - )
111 - );
112 - $message_code = sanitize_key( $_GET['lp_mcp_notice'] ?? '' ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
113 - $message = $this->notice_from_code( $message_code );
114 -
115 - require LP_PLUGIN_PATH . 'inc/admin/views/settings/mcp-api-keys-form.php';
116 - }
117 -
118 - /**
119 - * Process row and bulk revoke actions submitted from the list table.
120 - *
121 - * Supported actions:
122 - * - `lp_mcp_key_action = revoke`
123 - * - `action/action2 = bulk-revoke`
124 - *
125 - * @return void
126 - */
127 - public function handle_admin_actions(): void {
128 - if ( ! $this->is_mcp_keys_settings_screen() || ! current_user_can( $this->required_capability ) || ! LP_Settings_Mcp::is_mcp_available() ) {
129 - return;
130 - }
131 -
132 - $action = sanitize_key( $_REQUEST['lp_mcp_key_action'] ?? '' ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
133 - if ( 'revoke' === $action ) {
134 - $key_id = absint( $_REQUEST['key_id'] ?? 0 ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
135 - if ( $key_id <= 0 ) {
136 - return;
137 - }
138 -
139 - check_admin_referer( 'lp_mcp_revoke_key_' . $key_id );
140 - $this->repository->revoke_key( $key_id );
141 - $this->redirect_with_notice( 'revoked' );
142 - }
143 -
144 - $bulk_action = '';
145 - if ( isset( $_REQUEST['action'] ) && '-1' !== $_REQUEST['action'] ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
146 - $bulk_action = sanitize_key( wp_unslash( $_REQUEST['action'] ) ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
147 - } elseif ( isset( $_REQUEST['action2'] ) && '-1' !== $_REQUEST['action2'] ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
148 - $bulk_action = sanitize_key( wp_unslash( $_REQUEST['action2'] ) ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
149 - }
150 -
151 - if ( 'bulk-revoke' !== $bulk_action ) {
152 - return;
153 - }
154 -
155 - check_admin_referer( 'lp_mcp_bulk_revoke_action', 'lp_mcp_bulk_revoke_nonce' );
156 -
157 - $key_ids = $_REQUEST['key_ids'] ?? array(); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
158 - $key_ids = is_array( $key_ids ) ? $key_ids : array();
159 - $deleted = $this->repository->revoke_keys( $key_ids );
160 -
161 - $this->redirect_with_notice( $deleted > 0 ? 'bulk_revoked' : 'no_selection' );
162 - }
163 -
164 - /**
165 - * Redirect back to MCP keys section with notice code.
166 - *
167 - * @param string $notice_code Notice key used by `notice_from_code`.
168 - *
169 - * @return void
170 - */
171 - protected function redirect_with_notice( string $notice_code ): void {
172 - $url = add_query_arg(
173 - array(
174 - 'page' => 'learn-press-settings',
175 - 'tab' => 'mcp',
176 - 'lp_mcp_notice' => $notice_code,
177 - ),
178 - admin_url( 'admin.php' )
179 - );
180 -
181 - wp_safe_redirect( $url );
182 - exit;
183 - }
184 -
185 - /**
186 - * Convert notice code to display payload.
187 - *
188 - * @param string $code Notice code from query string.
189 - *
190 - * @return array<string, string>|null
191 - */
192 - protected function notice_from_code( string $code ): ?array {
193 - $map = array(
194 - 'revoked' => array( 'type' => 'success', 'message' => __( 'API key revoked.', 'learnpress' ) ),
195 - 'bulk_revoked' => array( 'type' => 'success', 'message' => __( 'Selected API keys revoked.', 'learnpress' ) ),
196 - 'no_selection' => array( 'type' => 'warning', 'message' => __( 'No API keys selected.', 'learnpress' ) ),
197 - );
198 -
199 - return $map[ $code ] ?? null;
200 - }
201 -
202 - /**
203 - * Is current request LearnPress MCP settings screen.
204 - *
205 - * @return bool
206 - */
207 - protected function is_mcp_keys_settings_screen(): bool {
208 - $page = sanitize_key( $_REQUEST['page'] ?? '' ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
209 - $tab = sanitize_key( $_REQUEST['tab'] ?? '' ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
210 -
211 - return 'learn-press-settings' === $page
212 - && 'mcp' === $tab;
213 - }
214 -}
1 +<?php
2 +
3 +use LearnPress\MCP\Auth\ApiKeysRepository;
4 +
5 +defined( 'ABSPATH' ) || exit;
6 +
7 +/**
8 + * Admin controller for LearnPress MCP API keys UI and actions.
9 + */
10 +class LP_Admin_MCP_API_Keys {
11 + /**
12 + * @var self|null
13 + */
14 + protected static $instance;
15 +
16 + /**
17 + * @var ApiKeysRepository
18 + */
19 + protected $repository;
20 +
21 + /**
22 + * @var string
23 + */
24 + protected $required_capability = 'manage_options';
25 +
26 + /**
27 + * Get singleton instance for MCP API keys admin controller.
28 + *
29 + * @return self
30 + */
31 + public static function instance(): self {
32 + if ( ! self::$instance ) {
33 + self::$instance = new self();
34 + }
35 +
36 + return self::$instance;
37 + }
38 +
39 + /**
40 + * Register admin hooks and required table dependency.
41 + *
42 + * @return void
43 + */
44 + protected function __construct() {
45 + $this->repository = new ApiKeysRepository();
46 +
47 + add_action( 'admin_init', array( $this, 'handle_admin_actions' ) );
48 + add_action( 'admin_enqueue_scripts', array( $this, 'localize_admin_script' ) );
49 +
50 + require_once LP_PLUGIN_PATH . 'inc/admin/class-lp-admin-mcp-api-keys-table-list.php';
51 + }
52 +
53 + /**
54 + * Localize MCP API key settings and i18n labels to admin JavaScript.
55 + *
56 + * Data is exposed under `window.lpMcpApiKeysSettings` and consumed by
57 + * `lp-admin-mcp-api-keys` runtime script.
58 + *
59 + * @return void
60 + */
61 + public function localize_admin_script(): void {
62 + if ( ! $this->is_mcp_integration_enabled() || ! wp_script_is( 'lp-admin-mcp-api-keys', 'enqueued' ) ) {
63 + return;
64 + }
65 +
66 + wp_localize_script(
67 + 'lp-admin-mcp-api-keys',
68 + 'lpMcpApiKeysSettings',
69 + array(
70 + 'is_mcp_keys_section' => $this->is_mcp_keys_settings_screen(),
71 + 'actions' => array(
72 + 'create' => 'mcp_create_api_key',
73 + ),
74 + 'i18n' => array(
75 + 'processing' => __( 'Processing...', 'learnpress' ),
76 + 'created' => __( 'API key created.', 'learnpress' ),
77 + 'request_failed' => __( 'Request failed. Please try again.', 'learnpress' ),
78 + 'confirm_revoke' => __( 'Revoke this API key?', 'learnpress' ),
79 + 'copy_success' => __( 'Copied.', 'learnpress' ),
80 + 'copy_fallback' => __( 'Copy this value manually.', 'learnpress' ),
81 + ),
82 + )
83 + );
84 + }
85 +
86 + /**
87 + * Render MCP API key management screen inside LearnPress settings.
88 + *
89 + * Prepares list-table data and user options before loading the section template.
90 + *
91 + * @return void
92 + */
93 + public function render_page(): void {
94 + if ( ! current_user_can( $this->required_capability ) ) {
95 + wp_die( esc_html__( 'Sorry, you are not allowed to manage MCP API keys.', 'learnpress' ) );
96 + }
97 + if ( ! $this->is_mcp_integration_enabled() ) {
98 + return;
99 + }
100 +
101 + $table = new LP_Admin_MCP_API_Keys_Table_List( $this->repository );
102 + $table->prepare_items();
103 +
104 + $users = get_users(
105 + array(
106 + 'fields' => array( 'ID', 'user_login', 'display_name' ),
107 + 'orderby' => 'display_name',
108 + 'order' => 'ASC',
109 + 'number' => 200,
110 + )
111 + );
112 + $message_code = sanitize_key( $_GET['lp_mcp_notice'] ?? '' ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
113 + $message = $this->notice_from_code( $message_code );
114 +
115 + require LP_PLUGIN_PATH . 'inc/admin/views/settings/mcp-api-keys-form.php';
116 + }
117 +
118 + /**
119 + * Process row and bulk revoke actions submitted from the list table.
120 + *
121 + * Supported actions:
122 + * - `lp_mcp_key_action = revoke`
123 + * - `action/action2 = bulk-revoke`
124 + *
125 + * @return void
126 + */
127 + public function handle_admin_actions(): void {
128 + if ( ! $this->is_mcp_keys_settings_screen() || ! current_user_can( $this->required_capability ) || ! $this->is_mcp_integration_enabled() ) {
129 + return;
130 + }
131 +
132 + $action = sanitize_key( $_REQUEST['lp_mcp_key_action'] ?? '' ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
133 + if ( 'revoke' === $action ) {
134 + $key_id = absint( $_REQUEST['key_id'] ?? 0 ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
135 + if ( $key_id <= 0 ) {
136 + return;
137 + }
138 +
139 + check_admin_referer( 'lp_mcp_revoke_key_' . $key_id );
140 + $this->repository->revoke_key( $key_id );
141 + $this->redirect_with_notice( 'revoked' );
142 + }
143 +
144 + $bulk_action = '';
145 + if ( isset( $_REQUEST['action'] ) && '-1' !== $_REQUEST['action'] ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
146 + $bulk_action = sanitize_key( wp_unslash( $_REQUEST['action'] ) ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
147 + } elseif ( isset( $_REQUEST['action2'] ) && '-1' !== $_REQUEST['action2'] ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
148 + $bulk_action = sanitize_key( wp_unslash( $_REQUEST['action2'] ) ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
149 + }
150 +
151 + if ( 'bulk-revoke' !== $bulk_action ) {
152 + return;
153 + }
154 +
155 + check_admin_referer( 'lp_mcp_bulk_revoke_action', 'lp_mcp_bulk_revoke_nonce' );
156 +
157 + $key_ids = $_REQUEST['key_ids'] ?? array(); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
158 + $key_ids = is_array( $key_ids ) ? $key_ids : array();
159 + $deleted = $this->repository->revoke_keys( $key_ids );
160 +
161 + $this->redirect_with_notice( $deleted > 0 ? 'bulk_revoked' : 'no_selection' );
162 + }
163 +
164 + /**
165 + * Redirect back to MCP keys section with notice code.
166 + *
167 + * @param string $notice_code Notice key used by `notice_from_code`.
168 + *
169 + * @return void
170 + */
171 + protected function redirect_with_notice( string $notice_code ): void {
172 + $url = add_query_arg(
173 + array(
174 + 'page' => 'learn-press-settings',
175 + 'tab' => 'advanced',
176 + 'section' => 'mcp',
177 + 'lp_mcp_notice' => $notice_code,
178 + ),
179 + admin_url( 'admin.php' )
180 + );
181 +
182 + wp_safe_redirect( $url );
183 + exit;
184 + }
185 +
186 + /**
187 + * Convert notice code to display payload.
188 + *
189 + * @param string $code Notice code from query string.
190 + *
191 + * @return array<string, string>|null
192 + */
193 + protected function notice_from_code( string $code ): ?array {
194 + $map = array(
195 + 'revoked' => array(
196 + 'type' => 'success',
197 + 'message' => __( 'API key revoked.', 'learnpress' ),
198 + ),
199 + 'bulk_revoked' => array(
200 + 'type' => 'success',
201 + 'message' => __( 'Selected API keys revoked.', 'learnpress' ),
202 + ),
203 + 'no_selection' => array(
204 + 'type' => 'warning',
205 + 'message' => __( 'No API keys selected.', 'learnpress' ),
206 + ),
207 + );
208 +
209 + return $map[ $code ] ?? null;
210 + }
211 +
212 + /**
213 + * Is current request LearnPress MCP settings screen.
214 + *
215 + * @return bool
216 + */
217 + protected function is_mcp_keys_settings_screen(): bool {
218 +
219 + $page = sanitize_key( $_REQUEST['page'] ?? '' ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
220 + $tab = sanitize_key( $_REQUEST['tab'] ?? '' ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
221 + $section = sanitize_key( $_REQUEST['section'] ?? '' ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
222 +
223 + if ( 'learn-press-settings' !== $page ) {
224 + return false;
225 + }
226 +
227 + return ( 'advanced' === $tab && 'mcp' === $section )
228 + || 'mcp' === $tab;
229 + }
230 +
231 + /**
232 + * Check whether MCP integration is enabled.
233 + *
234 + * @return bool
235 + */
236 + protected function is_mcp_integration_enabled(): bool {
237 + return 'yes' === LP_Settings::get_option( 'enable_mcp_integration', 'no' );
238 + }
239 +}