PluginProbe
Charitable – Donation & Fundraising Platform (Donation Forms, Recurring Donations & Fundraising Campaigns) / 1.8.13
Charitable – Donation & Fundraising Platform (Donation Forms, Recurring Donations & Fundraising Campaigns) v1.8.13
1.8.13.1 1.8.13 1.8.12.3 1.8.12.2 1.8.12.1 1.8.12 1.8.11.3 1.8.11.2 1.8.11.1 1.8.11 1.6.6 1.6.60 1.6.7 1.6.8 1.6.9 1.7.0 1.7.0.1 1.7.0.11 1.7.0.12 1.7.0.14 1.7.0.2 1.7.0.3 1.7.0.5 1.7.0.6 1.7.0.7 All 212 releases
← All changes | includes/admin/tools/charitable-tools-admin-hooks.php +153 -0 1.8.11 → 1.8.13 View file →
@@ -174,4 +174,157 @@
174 174 add_action( 'wp_ajax_charitable_export_logs_csv', array( 'Charitable_Log', 'ajax_export_csv' ) );
175 175 add_action( 'wp_ajax_charitable_toggle_logging', array( 'Charitable_Log', 'ajax_toggle_logging' ) );
176 176 add_action( 'wp_ajax_charitable_save_log_retention', array( 'Charitable_Log', 'ajax_save_retention' ) );
177 177 add_action( 'admin_enqueue_scripts', array( 'Charitable_Log', 'enqueue_scripts' ) );
178 +
179 +/**
180 + * Tools > AI MCP.
181 + *
182 + * Surfaces the Abilities API, which ships with no UI of its own, and carries the
183 + * AI write-access toggle. Charitable_Tools_AI_MCP is autoloaded via the classmap.
184 + *
185 + * Ported from Charitable Pro (pinned commit 4f84275197) for Lite 1.8.13. The
186 + * `ai-mcp` tab itself is registered directly in
187 + * Charitable_Tools::get_sections(), and the "no form / no Save Changes button"
188 + * behaviour Pro gets from its `charitable_tools_tabs_without_form` filter is
189 + * given here by adding 'ai-mcp' to the `$charitable_tab_no_form_tag` array in
190 + * includes/admin/views/tools/tools.php - the hardcoded-array convention that
191 + * file already uses for 'import', 'export', 'system-info' and the rest, rather
192 + * than porting a filter Lite's view template does not read.
193 + *
194 + * @since 1.8.13
195 + */
196 +add_filter(
197 + 'charitable_tools_tab_fields_ai-mcp',
198 + array( Charitable_Tools_AI_MCP::get_instance(), 'add_fields' ),
199 + 5
200 +);
201 +
202 +/**
203 + * Enqueue the AI MCP panel assets, on that one tab only.
204 + *
205 + * @since 1.8.13
206 + *
207 + * @return void
208 + */
209 +add_action(
210 + 'admin_enqueue_scripts',
211 + function () {
212 +
213 + if ( ! function_exists( 'charitable_is_tools_view' ) || ! charitable_is_tools_view() ) {
214 + return;
215 + }
216 +
217 + $tab = isset( $_GET['tab'] ) ? sanitize_key( wp_unslash( $_GET['tab'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
218 +
219 + if ( 'ai-mcp' !== $tab ) {
220 + return;
221 + }
222 +
223 + wp_enqueue_style( 'dashicons' );
224 +
225 + wp_enqueue_style(
226 + 'charitable-ai-mcp',
227 + charitable()->get_path( 'assets', false ) . 'css/admin/charitable-ai-mcp.css',
228 + array(),
229 + charitable()->get_version()
230 + );
231 +
232 + if ( ! current_user_can( 'manage_charitable_settings' ) ) {
233 + return;
234 + }
235 +
236 + /*
237 + * jquery-confirm powers the "Watch video" modal. Guarded the same way
238 + * Charitable_Admin_Splash guards it, because the splash is enqueued on
239 + * this same screen and whichever runs first should win. Do NOT rely on
240 + * the splash having done it: the link has to work on a site where the
241 + * splash is suppressed (hide_announcements), and without the library the
242 + * handler falls through to the anchor's YouTube href.
243 + */
244 + if ( ! wp_style_is( 'jquery-confirm', 'enqueued' ) ) {
245 + wp_enqueue_style(
246 + 'jquery-confirm',
247 + charitable()->get_path( 'directory', false ) . 'assets/lib/jquery.confirm/jquery-confirm.min.css',
248 + null,
249 + '3.3.4'
250 + );
251 + }
252 +
253 + if ( ! wp_script_is( 'jquery-confirm', 'enqueued' ) ) {
254 + wp_enqueue_script(
255 + 'jquery-confirm',
256 + charitable()->get_path( 'directory', false ) . 'assets/lib/jquery.confirm/jquery-confirm.min.js',
257 + array( 'jquery' ),
258 + '3.3.4',
259 + false
260 + );
261 + }
262 +
263 + wp_enqueue_script(
264 + 'charitable-ai-mcp',
265 + charitable()->get_path( 'assets', false ) . 'js/admin/charitable-ai-mcp.js',
266 + array( 'jquery', 'jquery-confirm' ),
267 + charitable()->get_version(),
268 + true
269 + );
270 +
271 + wp_localize_script(
272 + 'charitable-ai-mcp',
273 + 'charitable_ai_mcp',
274 + array(
275 + 'ajax_url' => admin_url( 'admin-ajax.php' ),
276 + 'nonce' => wp_create_nonce( 'charitable_ai_mcp_toggle' ),
277 + // Charitable_Admin_Plugins_Third_Party guards both the install and
278 + // the activate call with the shared 'charitable-admin' nonce, so the
279 + // in-place bridge install needs that one rather than the toggle nonce.
280 + 'plugin_nonce' => wp_create_nonce( 'charitable-admin' ),
281 + 'i18n' => array(
282 + 'error' => __( 'That could not be saved. Please try again.', 'charitable' ),
283 + 'installing' => __( 'Installing WPVibe…', 'charitable' ),
284 + 'activating' => __( 'Activating WPVibe…', 'charitable' ),
285 + 'installError' => __( 'WPVibe could not be installed. Install it from the Plugins screen instead.', 'charitable' ),
286 + /* The iframe's title attribute, read by screen readers in the video modal. */
287 + 'videoTitle' => esc_attr__( 'Using Charitable with AI', 'charitable' ),
288 + /*
289 + * The AI Activity toggle's accessible name, which is the only
290 + * thing that can say which way the control goes - its visible
291 + * label is a chevron. The collapsed wording matches the
292 + * `screen-reader-text` rendered in views/ai-mcp-activity.php,
293 + * since that is the state the panel loads in.
294 + */
295 + 'showActivity' => __( 'Show AI activity', 'charitable' ),
296 + 'hideActivity' => __( 'Hide AI activity', 'charitable' ),
297 + ),
298 + )
299 + );
300 + }
301 +);
302 +
303 +/**
304 + * AJAX: flip the AI write gate.
305 + *
306 + * No _nopriv counterpart, deliberately - this changes a security setting.
307 + *
308 + * @since 1.8.13
309 + */
310 +add_action(
311 + 'wp_ajax_charitable_ai_mcp_toggle_write',
312 + array( Charitable_Tools_AI_MCP::get_instance(), 'ajax_toggle_write' )
313 +);
314 +
315 +/**
316 + * Remember when a user has opened WPVibe's own admin page.
317 + *
318 + * On `current_screen`, and NOT gated to the Tools tab, because WPVibe's page is
319 + * a different screen entirely and the visit has to be caught wherever it
320 + * happens. Flips the AI MCP tab's primary button from "Open WPVibe Setup" to
321 + * "Go to WPVibe" so a user is not told to set up something they have already
322 + * opened. The write is a one-time latch (see maybe_mark_bridge_visited()), so
323 + * this costs a single user-meta read on other admin screens.
324 + *
325 + * @since 1.8.13
326 + */
327 +add_action(
328 + 'current_screen',
329 + array( Charitable_Tools_AI_MCP::get_instance(), 'maybe_mark_bridge_visited' )
330 +);