PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.4.0
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.4.0
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
learnpress / inc / admin / class-lp-admin-mcp-api-keys.php

class-lp-admin-mcp-api-keys.php in LearnPress – WordPress LMS Plugin for Create and Sell Online Courses 4.4.0, at inc/admin/class-lp-admin-mcp-api-keys.php

233 lines 6.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
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' => '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(
195 'type' => 'success',
196 'message' => __( 'API key revoked.', 'learnpress' ),
197 ),
198 'bulk_revoked' => array(
199 'type' => 'success',
200 'message' => __( 'Selected API keys revoked.', 'learnpress' ),
201 ),
202 'no_selection' => array(
203 'type' => 'warning',
204 'message' => __( 'No API keys selected.', 'learnpress' ),
205 ),
206 );
207
208 return $map[ $code ] ?? null;
209 }
210
211 /**
212 * Is current request LearnPress MCP settings screen.
213 *
214 * @return bool
215 */
216 protected function is_mcp_keys_settings_screen(): bool {
217 $page = LP_Request::get_param( 'page', '', 'key' ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
218 $tab = LP_Request::get_param( 'tab', '', 'key' ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
219
220 return 'learn-press-settings' === $page
221 && 'mcp' === $tab;
222 }
223
224 /**
225 * Check whether MCP integration is enabled.
226 *
227 * @return bool
228 */
229 protected function is_mcp_integration_enabled(): bool {
230 return 'yes' === LP_Settings::get_option( 'enable_mcp_integration', 'no' );
231 }
232 }
233