PluginProbe
Subscriptions for WooCommerce with Stripe Recurring Payments / 2.3.0
Subscriptions for WooCommerce with Stripe Recurring Payments v2.3.0
2.4.0 2.3.0 2.2.0 2.1.0 2.0.0 1.11.2 1.11.1 1.11.0 1.10.9 1.10.8 1.10.7 1.10.6 1.10.5 1.10.4 1.10.3 1.10.2 1.10.1 1.10.0 1.9.6 1.9.5 trunk 1.3.0 1.3.1 1.3.2 1.4.0 All 65 releases
← All changes | includes/Admin/Integrations.php +447 -18 1.10.0 → 2.3.0 View file →
@@ -62,9 +62,8 @@
62 62 __( 'Integrations', 'subscription' ),
63 63 'manage_options',
64 64 'wp-subscription-integrations',
65 65 [ $this, 'render_integrations_page' ],
66 - 40
67 66 );
68 67 }
69 68
70 69 /**
@@ -100,8 +99,12 @@
100 99 'nonce' => wp_create_nonce( 'subscrpt_integration_install_nonce' ),
101 100 'ajaxUrl' => admin_url( 'admin-ajax.php' ),
102 101 )
103 102 );
103 +
104 + // Browser-side filter rail. Enqueued on this hook, not in the render
105 + // callback, so it always loads.
106 + wp_enqueue_script( 'subscrpt-integrations-filter', SUBSCRPT_ASSETS . '/js/admin/integrations-filter.js', [], SUBSCRPT_VERSION, true );
104 107 }
105 108
106 109 /**
107 110 * Handle AJAX request for integrations.
@@ -189,8 +192,55 @@
189 192 return is_plugin_active( $plugin_file );
190 193 }
191 194
192 195 /**
196 + * Find the basename of an installed plugin from its wp.org slug.
197 + *
198 + * @param string $slug The wp.org plugin slug, which is also its directory.
199 + * @return string The plugin basename, or an empty string when not installed.
200 + */
201 + protected function find_plugin_file( $slug ) {
202 + if ( ! function_exists( 'get_plugins' ) ) {
203 + require_once ABSPATH . 'wp-admin/includes/plugin.php';
204 + }
205 + foreach ( array_keys( get_plugins() ) as $plugin_file ) {
206 + if ( 0 === strpos( $plugin_file, $slug . '/' ) ) {
207 + return $plugin_file;
208 + }
209 + }
210 + return '';
211 + }
212 +
213 + /**
214 + * Mark a gateway card installed when its plugin is on disk, and give it an
215 + * Activate action for when that plugin is inactive.
216 + *
217 + * Gateway cards otherwise detect installation by a class the plugin declares,
218 + * which only exists while it is active, so an installed-but-inactive gateway
219 + * offered "Install Now" and the install failed on the existing folder.
220 + *
221 + * @param array $integration The integration card.
222 + * @param string $slug The wp.org plugin slug.
223 + * @return array
224 + */
225 + protected function with_gateway_plugin_state( array $integration, $slug ) {
226 + $plugin_file = $this->find_plugin_file( $slug );
227 + if ( '' === $plugin_file ) {
228 + return $integration;
229 + }
230 +
231 + $integration['is_installed'] = true;
232 + $integration['plugin_file'] = $plugin_file;
233 + $integration['actions'][] = [
234 + 'action' => 'activate',
235 + 'label' => __( 'Activate', 'subscription' ),
236 + 'type' => 'function',
237 + 'function' => "subscrptActivatePlugin(this, '" . esc_js( $plugin_file ) . "')",
238 + ];
239 + return $integration;
240 + }
241 +
242 + /**
193 243 * Check if a payment gateway is enabled.
194 244 *
195 245 * @param string $gateway_id Gateway ID.
196 246 */
@@ -205,12 +255,13 @@
205 255 * @return array
206 256 */
207 257 protected function get_integrations(): array {
208 258 $integrations = [
209 - [
259 + 'paypal' => [
210 260 'title' => 'PayPal',
211 - 'description' => 'Accept subscription payments via PayPal.',
212 - 'icon_url' => SUBSCRPT_ASSETS . '/images/paypal.svg',
261 + 'description' => 'Accept recurring subscription payments directly through PayPal.',
262 + 'icon_url' => SUBSCRPT_ASSETS . '/images/integrations/paypal.svg',
263 + 'type' => 'payment_gateway',
213 264 'is_installed' => 'on' === get_option( 'wp_subs_paypal_integration_enabled', 'off' ),
214 265 'is_active' => self::is_gateway_enabled( 'wp_subscription_paypal' ),
215 266 'supports_recurring' => true,
216 267 'actions' => [
@@ -234,12 +285,13 @@
234 285 // 'class' => 'button button-primary wp-subs-button-danger',
235 286 // ],
236 287 ],
237 288 ],
238 - [
289 + 'stripe' => [
239 290 'title' => 'Stripe',
240 291 'description' => 'Process subscription payments securely with Stripe.',
241 - 'icon_url' => 'https://ps.w.org/woocommerce-gateway-stripe/assets/icon-256x256.png',
292 + 'icon_url' => SUBSCRPT_ASSETS . '/images/integrations/stripe.png',
293 + 'type' => 'payment_gateway',
242 294 'is_installed' => class_exists( 'WC_Stripe' ),
243 295 'is_active' => self::is_gateway_enabled( 'stripe' ),
244 296 'supports_recurring' => true,
245 297 'actions' => [
@@ -256,12 +308,13 @@
256 308 'url' => admin_url( 'admin.php?page=wc-settings&tab=checkout&section=stripe&panel=settings' ),
257 309 ],
258 310 ],
259 311 ],
260 - [
312 + 'paddle' => [
261 313 'title' => 'Paddle',
262 314 'description' => 'Process subscription payments securely with Paddle.',
263 - 'icon_url' => SUBSCRPT_ASSETS . '/images/paddle.svg',
315 + 'icon_url' => SUBSCRPT_ASSETS . '/images/integrations/paddle.svg',
316 + 'type' => 'payment_gateway',
264 317 'is_installed' => class_exists( 'SmartPayWoo\Gateways\Paddle\SmartPay_Paddle' ),
265 318 'is_active' => self::is_gateway_enabled( 'smartpay_paddle' ),
266 319 'supports_recurring' => true,
267 320 'actions' => [
@@ -290,10 +343,375 @@
290 343 'url' => 'https://wpsmartpay.com/paddle-for-woocommerce/',
291 344 ],
292 345 ],
293 346 ],
347 + 'mollie' => [
348 + 'title' => 'Mollie',
349 + 'description' => 'Pay for subscriptions with Mollie Payments for WooCommerce.',
350 + 'icon_url' => SUBSCRPT_ASSETS . '/images/integrations/mollie.png',
351 + 'type' => 'payment_gateway',
352 + 'is_pro' => true,
353 + 'is_installed' => class_exists( 'Mollie\WooCommerce\Activation\ActivationModule' ),
354 + 'is_active' => self::is_gateway_enabled( 'mollie_wc_gateway', true ),
355 + 'supports_recurring' => true,
356 + 'actions' => [
357 + [
358 + 'action' => 'install',
359 + 'label' => 'Install Now',
360 + 'type' => 'function',
361 + 'function' => "subscrptInstallPlugin(this, 'mollie-payments-for-woocommerce')",
362 + ],
363 + [
364 + 'action' => 'settings',
365 + 'label' => 'Settings',
366 + 'type' => 'link',
367 + 'url' => admin_url( 'admin.php?page=wc-settings&tab=mollie_settings' ),
368 + ],
369 + [
370 + 'label' => 'More Details',
371 + 'type' => 'external_link',
372 + 'url' => 'https://docs.wpsubscription.co/en/wpsubscription-payment-with-mollie?utm_source=plugin&utm_medium=admin&utm_campaign=docs',
373 + ],
374 + ],
375 + ],
376 + 'razorpay' => [
377 + 'title' => 'Razorpay',
378 + 'description' => 'Pay for subscriptions securely with Razorpay for WooCommerce.',
379 + 'icon_url' => SUBSCRPT_ASSETS . '/images/integrations/razorpay.png',
380 + 'type' => 'payment_gateway',
381 + 'is_pro' => true,
382 + 'is_beta' => true,
383 + 'is_installed' => class_exists( 'WC_Razorpay' ),
384 + 'is_active' => self::is_gateway_enabled( 'razorpay' ),
385 + 'supports_recurring' => true,
386 + 'actions' => [
387 + [
388 + 'action' => 'install',
389 + 'label' => 'Install Now',
390 + 'type' => 'function',
391 + 'function' => "subscrptInstallPlugin(this, 'woo-razorpay')",
392 + ],
393 + [
394 + 'action' => 'settings',
395 + 'label' => 'Settings',
396 + 'type' => 'link',
397 + 'url' => admin_url( 'admin.php?page=wc-settings&tab=checkout&section=razorpay' ),
398 + ],
399 + [
400 + 'label' => 'More Details',
401 + 'type' => 'external_link',
402 + 'url' => 'https://docs.wpsubscription.co/en/wpsubscription-payment-with-razorpay?utm_source=plugin&utm_medium=admin&utm_campaign=docs',
403 + ],
404 + ],
405 + ],
406 + 'xendit' => [
407 + 'title' => 'Xendit',
408 + 'description' => 'Pay for subscriptions securely with Xendit for WooCommerce.',
409 + 'icon_url' => SUBSCRPT_ASSETS . '/images/integrations/xendit.png',
410 + 'type' => 'payment_gateway',
411 + 'is_pro' => true,
412 + 'is_beta' => true,
413 + 'is_installed' => class_exists( 'WC_Xendit_CC' ),
414 + 'is_active' => self::is_gateway_enabled( 'xendit' ),
415 + 'supports_recurring' => true,
416 + 'actions' => [
417 + [
418 + 'action' => 'install',
419 + 'label' => 'Install Now',
420 + 'type' => 'function',
421 + 'function' => "subscrptInstallPlugin(this, 'woo-xendit-virtual-accounts')",
422 + ],
423 + [
424 + 'action' => 'settings',
425 + 'label' => 'Settings',
426 + 'type' => 'link',
427 + 'url' => admin_url( 'admin.php?page=wc-settings&tab=checkout&section=xendit_gateway' ),
428 + ],
429 + [
430 + 'label' => 'More Details',
431 + 'type' => 'external_link',
432 + 'url' => 'https://docs.wpsubscription.co/en/wpsubscription-payment-with-xendit?utm_source=plugin&utm_medium=admin&utm_campaign=docs',
433 + ],
434 + ],
435 + ],
294 436 ];
295 437
438 + $integrations['stripe'] = $this->with_gateway_plugin_state( $integrations['stripe'], 'woocommerce-gateway-stripe' );
439 + $integrations['mollie'] = $this->with_gateway_plugin_state( $integrations['mollie'], 'mollie-payments-for-woocommerce' );
440 + $integrations['razorpay'] = $this->with_gateway_plugin_state( $integrations['razorpay'], 'woo-razorpay' );
441 + $integrations['xendit'] = $this->with_gateway_plugin_state( $integrations['xendit'], 'woo-xendit-virtual-accounts' );
442 +
443 + // Third-party integrations (requires Pro plugin to function).
444 + $third_party = [
445 + // LMS.
446 + 'tutor_lms' => [
447 + 'title' => 'Tutor LMS',
448 + 'description' => 'Restrict course access based on subscription status. Enroll and unenroll students automatically.',
449 + 'icon_url' => SUBSCRPT_ASSETS . '/images/integrations/tutor-lms.jpeg',
450 + 'type' => 'third_party',
451 + 'is_pro' => true,
452 + 'category' => 'lms',
453 + 'is_installed' => $this->is_plugin_installed( 'tutor/tutor.php' ),
454 + 'is_active' => is_plugin_active( 'tutor/tutor.php' ) && class_exists( 'TUTOR\Tutor' ),
455 + 'actions' => [
456 + [
457 + 'action' => 'install',
458 + 'label' => __( 'Install Now', 'subscription' ),
459 + 'type' => 'function',
460 + 'function' => "subscrptInstallPlugin(this, 'tutor')",
461 + ],
462 + [
463 + 'action' => 'activate',
464 + 'label' => __( 'Activate', 'subscription' ),
465 + 'type' => 'function',
466 + 'function' => "subscrptActivatePlugin(this, 'tutor/tutor.php')",
467 + ],
468 + [
469 + 'label' => __( 'Learn More', 'subscription' ),
470 + 'type' => 'external_link',
471 + 'url' => 'https://docs.wpsubscription.co/en/wpsubscription-tutor-lms?utm_source=plugin&utm_medium=admin&utm_campaign=docs',
472 + ],
473 + ],
474 + ],
475 + 'learnpress' => [
476 + 'title' => 'LearnPress',
477 + 'description' => 'Connect subscriptions with LearnPress courses. Enroll users automatically when subscriptions are active.',
478 + 'icon_url' => SUBSCRPT_ASSETS . '/images/integrations/learnpress.png',
479 + 'type' => 'third_party',
480 + 'is_pro' => true,
481 + 'category' => 'lms',
482 + 'is_installed' => $this->is_plugin_installed( 'learnpress/learnpress.php' ),
483 + 'is_active' => is_plugin_active( 'learnpress/learnpress.php' ) && class_exists( 'LearnPress' ),
484 + 'actions' => [
485 + [
486 + 'action' => 'install',
487 + 'label' => __( 'Install Now', 'subscription' ),
488 + 'type' => 'function',
489 + 'function' => "subscrptInstallPlugin(this, 'learnpress')",
490 + ],
491 + [
492 + 'action' => 'activate',
493 + 'label' => __( 'Activate', 'subscription' ),
494 + 'type' => 'function',
495 + 'function' => "subscrptActivatePlugin(this, 'learnpress/learnpress.php')",
496 + ],
497 + [
498 + 'label' => __( 'Learn More', 'subscription' ),
499 + 'type' => 'external_link',
500 + 'url' => 'https://docs.wpsubscription.co/en/wpsubscription-learnpress-lms?utm_source=plugin&utm_medium=admin&utm_campaign=docs',
501 + ],
502 + ],
503 + ],
504 + 'learndash' => [
505 + 'title' => 'LearnDash',
506 + 'description' => 'Sync subscription status with LearnDash group enrollment and course access.',
507 + 'icon_url' => SUBSCRPT_ASSETS . '/images/integrations/learndash.jpeg',
508 + 'type' => 'third_party',
509 + 'is_pro' => true,
510 + 'category' => 'lms',
511 + 'is_installed' => $this->is_plugin_installed( 'sfwd-lms/sfwd_lms.php' ),
512 + 'is_active' => is_plugin_active( 'sfwd-lms/sfwd_lms.php' ) && class_exists( 'LearnDash\Core\App' ),
513 + 'actions' => [
514 + [
515 + 'action' => 'install',
516 + 'label' => __( 'Get LearnDash', 'subscription' ),
517 + 'type' => 'external_link',
518 + 'url' => 'https://www.learndash.com/',
519 + ],
520 + [
521 + 'action' => 'activate',
522 + 'label' => __( 'Activate', 'subscription' ),
523 + 'type' => 'function',
524 + 'function' => "subscrptActivatePlugin(this, 'sfwd-lms/sfwd_lms.php')",
525 + ],
526 + [
527 + 'label' => __( 'Learn More', 'subscription' ),
528 + 'type' => 'external_link',
529 + 'url' => 'https://docs.wpsubscription.co/en/wpsubscription-learndash-lms?utm_source=plugin&utm_medium=admin&utm_campaign=docs',
530 + ],
531 + ],
532 + ],
533 + // CRM.
534 + 'fluentcrm' => [
535 + 'title' => 'FluentCRM',
536 + 'description' => 'Trigger email sequences and manage contacts based on subscription events and status changes.',
537 + 'icon_url' => SUBSCRPT_ASSETS . '/images/integrations/fluentcrm.png',
538 + 'type' => 'third_party',
539 + 'is_pro' => true,
540 + 'category' => 'crm',
541 + 'is_installed' => $this->is_plugin_installed( 'fluent-crm/fluent-crm.php' ),
542 + 'is_active' => class_exists( 'FluentCrm\App\Services\Funnel\BaseTrigger' ),
543 + 'actions' => [
544 + [
545 + 'action' => 'install',
546 + 'label' => __( 'Install Now', 'subscription' ),
547 + 'type' => 'function',
548 + 'function' => "subscrptInstallPlugin(this, 'fluent-crm')",
549 + ],
550 + [
551 + 'action' => 'activate',
552 + 'label' => __( 'Activate', 'subscription' ),
553 + 'type' => 'function',
554 + 'function' => "subscrptActivatePlugin(this, 'fluent-crm/fluent-crm.php')",
555 + ],
556 + [
557 + 'label' => __( 'Learn More', 'subscription' ),
558 + 'type' => 'external_link',
559 + 'url' => 'https://docs.wpsubscription.co/en/wpsubscription-fluent-crm?utm_source=plugin&utm_medium=admin&utm_campaign=docs',
560 + ],
561 + ],
562 + ],
563 + // Automation.
564 + 'automatorwp' => [
565 + 'title' => 'AutomatorWP',
566 + 'description' => 'Build powerful automations triggered by subscription events without writing any code.',
567 + 'icon_url' => SUBSCRPT_ASSETS . '/images/integrations/automatorwp.png',
568 + 'type' => 'third_party',
569 + 'is_pro' => true,
570 + 'category' => 'automation',
571 + 'is_installed' => $this->is_plugin_installed( 'automatorwp/automatorwp.php' ),
572 + 'is_active' => is_plugin_active( 'automatorwp/automatorwp.php' ) && class_exists( 'AutomatorWP' ),
573 + 'actions' => [
574 + [
575 + 'action' => 'install',
576 + 'label' => __( 'Install Now', 'subscription' ),
577 + 'type' => 'function',
578 + 'function' => "subscrptInstallPlugin(this, 'automatorwp')",
579 + ],
580 + [
581 + 'action' => 'activate',
582 + 'label' => __( 'Activate', 'subscription' ),
583 + 'type' => 'function',
584 + 'function' => "subscrptActivatePlugin(this, 'automatorwp/automatorwp.php')",
585 + ],
586 + // [
587 + // 'label' => __( 'Learn More', 'subscription' ),
588 + // 'type' => 'external_link',
589 + // 'url' => 'https://docs.wpsubscription.co/en/',
590 + // ],
591 + ],
592 + ],
593 + 'wpfusion' => [
594 + 'title' => 'WP Fusion',
595 + 'description' => 'Sync subscription data with your CRM and marketing platforms through WP Fusion.',
596 + 'icon_url' => SUBSCRPT_ASSETS . '/images/integrations/wp-fusion.png',
597 + 'type' => 'third_party',
598 + 'is_pro' => true,
599 + 'category' => 'automation',
600 + 'is_installed' => $this->is_plugin_installed( 'wp-fusion/wp-fusion.php' ) || class_exists( 'WPF_Integrations_Base' ),
601 + 'is_active' => class_exists( 'WPF_Integrations_Base' ),
602 + 'actions' => [
603 + [
604 + 'action' => 'install',
605 + 'label' => __( 'Get WP Fusion', 'subscription' ),
606 + 'type' => 'external_link',
607 + 'url' => 'https://wpfusion.com/',
608 + ],
609 + [
610 + 'action' => 'activate',
611 + 'label' => __( 'Activate', 'subscription' ),
612 + 'type' => 'function',
613 + 'function' => "subscrptActivatePlugin(this, 'wp-fusion/wp-fusion.php')",
614 + ],
615 + // [
616 + // 'label' => __( 'Learn More', 'subscription' ),
617 + // 'type' => 'external_link',
618 + // 'url' => 'https://docs.wpsubscription.co/en/',
619 + // ],
620 + ],
621 + ],
622 + // Email Marketing.
623 + 'mailpoet' => [
624 + 'title' => 'MailPoet',
625 + 'description' => 'Add subscribers to MailPoet lists and trigger email automations based on subscription lifecycle events.',
626 + 'icon_url' => SUBSCRPT_ASSETS . '/images/integrations/mailpoet.png',
627 + 'type' => 'third_party',
628 + 'is_pro' => true,
629 + 'category' => 'email',
630 + 'is_installed' => $this->is_plugin_installed( 'mailpoet/mailpoet.php' ) || is_plugin_active( 'mailpoet-premium/mailpoet-premium.php' ),
631 + 'is_active' => is_plugin_active( 'mailpoet/mailpoet.php' ) || is_plugin_active( 'mailpoet-premium/mailpoet-premium.php' ),
632 + 'actions' => [
633 + [
634 + 'action' => 'install',
635 + 'label' => __( 'Install Now', 'subscription' ),
636 + 'type' => 'function',
637 + 'function' => "subscrptInstallPlugin(this, 'mailpoet')",
638 + ],
639 + [
640 + 'action' => 'activate',
641 + 'label' => __( 'Activate', 'subscription' ),
642 + 'type' => 'function',
643 + 'function' => "subscrptActivatePlugin(this, 'mailpoet/mailpoet.php')",
644 + ],
645 + [
646 + 'label' => __( 'Learn More', 'subscription' ),
647 + 'type' => 'external_link',
648 + 'url' => 'https://docs.wpsubscription.co/en/wpsubscription-mailpoet?utm_source=plugin&utm_medium=admin&utm_campaign=docs',
649 + ],
650 + ],
651 + ],
652 + // License Management.
653 + 'wp_soft_lic' => [
654 + 'title' => 'WP Software License',
655 + 'description' => 'Issue and validate software licenses for subscription-based digital products.',
656 + 'icon_url' => SUBSCRPT_ASSETS . '/images/integrations/wp-software-license.png',
657 + 'type' => 'third_party',
658 + 'is_pro' => true,
659 + 'category' => 'license',
660 + 'is_installed' => $this->is_plugin_installed( 'software-license/software-license.php' ),
661 + 'is_active' => is_plugin_active( 'software-license/software-license.php' ) && class_exists( 'WOO_SL' ),
662 + 'actions' => [
663 + [
664 + 'action' => 'install',
665 + 'label' => __( 'Get Plugin', 'subscription' ),
666 + 'type' => 'external_link',
667 + 'url' => 'https://wpsoftwarelicense.com/',
668 + ],
669 + [
670 + 'action' => 'activate',
671 + 'label' => __( 'Activate', 'subscription' ),
672 + 'type' => 'function',
673 + 'function' => "subscrptActivatePlugin(this, 'software-license/software-license.php')",
674 + ],
675 + // [
676 + // 'label' => __( 'Learn More', 'subscription' ),
677 + // 'type' => 'external_link',
678 + // 'url' => 'https://docs.wpsubscription.co/en/',
679 + // ],
680 + ],
681 + ],
682 + 'license_mgr' => [
683 + 'title' => 'License Manager for WooCommerce',
684 + 'description' => 'Generate and manage software license keys that are automatically tied to active subscriptions.',
685 + 'icon_url' => SUBSCRPT_ASSETS . '/images/integrations/license-manager.png',
686 + 'type' => 'third_party',
687 + 'is_pro' => true,
688 + 'category' => 'license',
689 + 'is_installed' => $this->is_plugin_installed( 'license-manager-for-woocommerce/license-manager-for-woocommerce.php' ),
690 + 'is_active' => is_plugin_active( 'license-manager-for-woocommerce/license-manager-for-woocommerce.php' ) && class_exists( 'LicenseManagerForWooCommerce\Models\Resources\License' ),
691 + 'actions' => [
692 + [
693 + 'action' => 'install',
694 + 'label' => __( 'Install Now', 'subscription' ),
695 + 'type' => 'function',
696 + 'function' => "subscrptInstallPlugin(this, 'license-manager-for-woocommerce')",
697 + ],
698 + [
699 + 'action' => 'activate',
700 + 'label' => __( 'Activate', 'subscription' ),
701 + 'type' => 'function',
702 + 'function' => "subscrptActivatePlugin(this, 'license-manager-for-woocommerce/license-manager-for-woocommerce.php')",
703 + ],
704 + // [
705 + // 'label' => __( 'Learn More', 'subscription' ),
706 + // 'type' => 'external_link',
707 + // 'url' => 'https://docs.wpsubscription.co/en/',
708 + // ],
709 + ],
710 + ],
711 + ];
712 + $integrations = array_merge( $integrations, $third_party );
713 +
296 714 // Add more integrations as needed.
297 715 $integrations = apply_filters( 'wpsubs_integrations', $integrations );
298 716
299 717 return $integrations;
@@ -310,10 +728,16 @@
310 728 foreach ( $integrations as $integration ) {
311 729 $is_installed = $integration['is_installed'] ?? false;
312 730 $is_active = $integration['is_active'] ?? false;
313 731
314 - $cleaned_actions = [];
732 + // A gateway card is "active" when its gateway is enabled, which is not
733 + // the same as its plugin being active; read the plugin itself.
734 + $plugin_file = $integration['plugin_file'] ?? '';
735 + $plugin_active = '' !== $plugin_file ? is_plugin_active( $plugin_file ) : $is_active;
315 736
737 + $cleaned_actions = [];
738 + $shown_install_url = null;
739 +
316 740 foreach ( $integration['actions'] as $integration_action ) {
317 741 $action_tag = $integration_action['action'] ?? null;
318 742
319 743 if ( 'install' === $action_tag ) {
@@ -318,8 +742,9 @@
318 742
319 743 if ( 'install' === $action_tag ) {
320 744 if ( ! $is_installed ) {
321 745 $cleaned_actions[] = $integration_action;
746 + $shown_install_url = $integration_action['url'] ?? null;
322 747 }
323 748 continue;
324 749 }
325 750 if ( 'uninstall' === $action_tag ) {
@@ -327,8 +752,14 @@
327 752 $cleaned_actions[] = $integration_action;
328 753 }
329 754 continue;
330 755 }
756 + if ( 'activate' === $action_tag ) {
757 + if ( $is_installed && ! $plugin_active ) {
758 + $cleaned_actions[] = $integration_action;
759 + }
760 + continue;
761 + }
331 762 if ( 'enable' === $action_tag ) {
332 763 if ( $is_installed && ! $is_active ) {
333 764 $cleaned_actions[] = $integration_action;
334 765 }
@@ -334,15 +765,20 @@
334 765 }
335 766 continue;
336 767 }
337 768 if ( 'settings' === $action_tag ) {
338 - if ( $is_installed ) {
769 + if ( $is_installed && ( '' === $plugin_file || $plugin_active ) ) {
339 770 $cleaned_actions[] = $integration_action;
340 771 }
341 772 continue;
342 773 }
343 774
344 - // Default.
775 + // Default. Skip a "More Details"-style link that just repeats the
776 + // install/"Get X" link already shown (e.g. Paddle), so the card
777 + // does not carry the same URL twice.
778 + if ( null !== $shown_install_url && ( $integration_action['url'] ?? null ) === $shown_install_url ) {
779 + continue;
780 + }
345 781 $cleaned_actions[] = $integration_action;
346 782 }
347 783
348 784 // Overwrite.
@@ -356,17 +792,10 @@
356 792 /**
357 793 * Render the Integrations admin page.
358 794 */
359 795 public function render_integrations_page() {
360 - if ( ! empty( $_GET['subscrpt_installed'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
361 - echo '<div class="notice notice-success is-dismissible"><p>' . esc_html__( 'Plugin installed and activated successfully.', 'subscription' ) . '</p></div>';
362 - }
363 -
364 796 $integrations = $this->integrations;
365 797 $integrations = $this->filter_integration_actions( $integrations );
366 -
367 - // Integrations styles.
368 - // wp_enqueue_style( 'wp-subs-integration-settings', SUBSCRPT_ASSETS . '/css/integration_settings.css', [], SUBSCRPT_VERSION, 'all' );
369 798
370 799 $menu = new \SpringDevs\Subscription\Admin\Menu();
371 800 $menu->render_admin_header( __( 'Integrations', 'subscription' ) );
372 801 include 'views/integrations.php';