# subscription/2.4.0/includes/Admin/Settings.php

Subscriptions for WooCommerce with Stripe Recurring Payments, version 2.4.0. 428 lines.

- Page: https://pluginprobe.com/plugins/subscription/2.4.0/code/includes/Admin/Settings.php
- Raw: https://pluginprobe.com/plugins/subscription/2.4.0/raw/includes/Admin/Settings.php
- Modified: 2026-10-08T10:42:46+00:00

Line numbers below start at 1. Link to a line or a range by appending a fragment to the
page URL, for example `https://pluginprobe.com/plugins/subscription/2.4.0/code/includes/Admin/Settings.php#L10-L20`.

```php
<?php

namespace SpringDevs\Subscription\Admin;

use SpringDevs\Subscription\Ajax;

/**
 * Class Settings
 *
 * @package SpringDevs\Subscription\Admin
 */
class Settings {
	/**
	 * Settings fields.
	 *
	 * @var array
	 */
	public $settings_fields = [];

	/**
	 * Initialize the class.
	 */
	public function __construct() {
		// Load the settings helper.
		SettingsHelper::get_instance();

		add_action( 'admin_menu', array( $this, 'admin_menu' ) );
		add_action( 'admin_init', array( $this, 'register_settings' ) );
		add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_wc_admin_styles' ) );
		add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_installer_script' ) );
	}

	/**
	 * Register submenu on `Subscriptions` menu.
	 *
	 * @return void
	 */
	public function admin_menu() {
		// Initialize & process settings fields.
		$this->initiate_settings_fields();

		// Add submenu page.
		$parent_slug = 'wp-subscription';
		add_submenu_page(
			$parent_slug,
			__( 'Settings', 'subscription' ),
			__( 'Settings', 'subscription' ),
			'manage_options',
			'wp-subscription-settings',
			[ $this, 'settings_content' ]
		);
	}

	/**
	 * Initialize settings fields.
	 */
	public function initiate_settings_fields() {
		global $wp_roles;
		$roles = [];
		foreach ( ( $wp_roles->roles ?? [] ) as $role_key => $role ) {
			$roles[ $role_key ] = $role['name'];
		}

		// Setting fields.
		$settings_fields = [
			[
				'type'       => 'heading',
				'group'      => 'renewals',
				'priority'   => 0,
				'field_data' => [
					'title' => __( 'Renewals', 'subscription' ),
				],
			],
			[
				'type'       => 'select',
				'group'      => 'renewals',
				'priority'   => 1,
				'field_data' => [
					'id'          => 'wp_subscription_renewal_process',
					'title'       => __( 'Renewal Process', 'subscription' ),
					'description' => __( 'How renewal process will be done after Subscription Expired.', 'subscription' ),
					'options'     => [
						'auto'   => __( 'Automatic', 'subscription' ),
						'manual' => __( 'Manual', 'subscription' ),
					],
					'selected'    => esc_attr( subscrpt_get_renewal_process() ),
				],
			],
			[
				'type'       => 'input',
				'group'      => 'renewals',
				'priority'   => 2,
				'field_data' => [
					'id'          => 'wp_subscription_manual_renew_cart_notice',
					'title'       => __( 'Renewal Cart Notice', 'subscription' ),
					'description' => __( 'Display Notice when Renewal Subscription product add to cart. Only available for Manual Renewal Process.', 'subscription' ),
					'value'       => esc_attr( subscrpt_get_manual_renew_cart_notice() ),
				],
			],
			[
				'type'       => 'toggle',
				'group'      => 'renewals',
				'priority'   => 3,
				'field_data' => [
					'id'          => 'wp_subscription_stripe_auto_renew',
					'title'       => __( 'Stripe Auto Renewal', 'subscription' ),
					'label'       => __( 'Accept Stripe Auto Renewals', 'subscription' ),
					'description' => class_exists( 'WC_Stripe' )
						? sprintf(
							/* translators: 1: opening plugin link tag, 2: closing link tag, 3: opening settings link tag */
							__( '&#10003; %1$sWooCommerce Stripe Payment Gateway%2$s is active. %3$sConfigure%2$s', 'subscription' ),
							'<a href="https://wordpress.org/plugins/woocommerce-gateway-stripe/" target="_blank">',
							'</a>',
							'<a href="' . esc_url( admin_url( 'admin.php?page=wc-settings&tab=checkout&section=stripe' ) ) . '">'
						)
						: sprintf(
							/* translators: HTML tags */
							__( '%1$s WooCommerce Stripe Payment Gateway %2$s plugin is required!', 'subscription' ),
							'<a href="https://wordpress.org/plugins/woocommerce-gateway-stripe/" target="_blank">',
							'</a>'
						) . $this->get_stripe_plugin_action(),
					'value'       => '1',
					'checked'     => '1' === get_option( 'wp_subscription_stripe_auto_renew', '1' ),
				],
			],
			[
				'type'       => 'toggle',
				'group'      => 'renewals',
				'priority'   => 4,
				'field_data' => [
					'id'          => 'wp_subscription_auto_renewal_toggle',
					'title'       => __( 'Auto Renewal Toggle', 'subscription' ),
					'label'       => __( 'Display the auto renewal toggle', 'subscription' ),
					'description' => __( 'Allow customers to turn on and off automatic renewals from their Subscription details page', 'subscription' ),
					'value'       => '1',
					'checked'     => '1' === get_option( 'wp_subscription_auto_renewal_toggle', '1' ),
				],
			],
			[
				'type'       => 'heading',
				'group'      => 'stock_management',
				'priority'   => 0,
				'field_data' => [
					'title' => __( 'Stock Management', 'subscription' ),
				],
			],
			[
				'type'       => 'toggle',
				'group'      => 'stock_management',
				'priority'   => 1,
				'field_data' => [
					'id'          => 'wp_subscription_stock_pause',
					'title'       => __( 'Pause on Low Stock', 'subscription' ),
					'label'       => __( 'Pause subscriptions when the product runs low on stock', 'subscription' ),
					'description' => __( 'Active subscriptions of a product are put on hold when its stock reaches the threshold, and the customer is emailed, so no renewal is charged for something you cannot ship.', 'subscription' ),
					'value'       => '1',
					'checked'     => '1' === get_option( 'wp_subscription_stock_pause', '' ),
				],
			],
			[
				'type'       => 'input',
				'group'      => 'stock_management',
				'priority'   => 2,
				'field_data' => [
					'id'          => 'wp_subscription_stock_pause_threshold',
					'title'       => __( 'Stock Threshold', 'subscription' ),
					'description' => __( 'Pause when the stock quantity is at or below this number. Products that do not manage a quantity pause only when out of stock.', 'subscription' ),
					'type'        => 'number',
					'value'       => esc_attr( get_option( 'wp_subscription_stock_pause_threshold', 0 ) ),
					'attributes'  => [
						'min'  => 0,
						'step' => 1,
					],
				],
			],
			[
				'type'       => 'toggle',
				'group'      => 'stock_management',
				'priority'   => 3,
				'field_data' => [
					'id'          => 'wp_subscription_stock_auto_resume',
					'title'       => __( 'Auto Resume', 'subscription' ),
					'label'       => __( 'Resume paused subscriptions when stock recovers', 'subscription' ),
					'description' => __( 'Only subscriptions paused because of stock are resumed; ones you put on hold yourself stay on hold.', 'subscription' ),
					'value'       => '1',
					'checked'     => '1' === get_option( 'wp_subscription_stock_auto_resume', '1' ),
				],
			],
			[
				'type'       => 'select',
				'group'      => 'role_based_settings',
				'priority'   => 2,
				'field_data' => [
					'id'          => 'wp_subscription_active_role',
					'title'       => __( 'Subscriber Default Role', 'subscription' ),
					'description' => __( 'When a subscription is activated, either manually or after a successful purchase, new users will be assigned this role.', 'subscription' ),
					'options'     => $roles,
					'selected'    => esc_attr( get_option( 'wp_subscription_active_role', 'subscriber' ) ),
				],
			],
			[
				'type'       => 'select',
				'group'      => 'role_based_settings',
				'priority'   => 3,
				'field_data' => [
					'id'          => 'wp_subscription_unactive_role',
					'title'       => __( 'Subscriber Inactive Role', 'subscription' ),
					'description' => __( "If a subscriber's subscription is manually cancelled or expires, they will be assigned this role.", 'subscription' ),
					'options'     => $roles,
					'selected'    => esc_attr( get_option( 'wp_subscription_unactive_role', 'customer' ) ),
				],
			],
		];

		// Allow other modules to add/modify settings fields.
		$settings_fields = apply_filters( 'subscrpt_settings_fields', $settings_fields );

		// Process settings fields (group & sort).
		$settings_fields = apply_filters( 'process_subscrpt_settings_fields', $settings_fields );

		// Set the settings fields.
		$this->settings_fields = $settings_fields;
	}

	/**
	 * Install / Activate link for the Stripe gateway plugin.
	 *
	 * Rendered inside a field description, which goes through `wp_kses_post()`,
	 * so the link carries data attributes rather than an inline handler;
	 * `integration_settings.js` picks it up.
	 *
	 * @return string Link HTML, or an empty string when the user cannot act on it.
	 */
	private function get_stripe_plugin_action() {
		$slug     = 'woocommerce-gateway-stripe';
		$installed = '' !== Ajax::get_installed_plugin_file( $slug );

		if ( $installed && current_user_can( 'activate_plugins' ) ) {
			$label      = __( 'Activate', 'subscription' );
			$busy_label = __( 'Activating…', 'subscription' );
		} elseif ( ! $installed && current_user_can( 'install_plugins' ) ) {
			$label      = __( 'Install & Activate', 'subscription' );
			$busy_label = __( 'Installing…', 'subscription' );
		} else {
			return '';
		}

		return sprintf(
			' <a href="#" data-subscrpt-install-plugin="%1$s" data-busy-label="%2$s">%3$s</a>',
			esc_attr( $slug ),
			esc_attr( $busy_label ),
			esc_html( $label )
		);
	}

	/**
	 * Enqueue the plugin installer on the settings page.
	 *
	 * @param string $hook The current admin page hook.
	 */
	public function enqueue_installer_script( $hook ) {
		if ( false === strpos( $hook, 'wp-subscription-settings' ) ) {
			return;
		}

		wp_enqueue_script( 'subscrpt-integrations', SUBSCRPT_ASSETS . '/js/integration_settings.js', [], SUBSCRPT_VERSION, true );

		wp_localize_script(
			'subscrpt-integrations',
			'subscrptIntegrations',
			array(
				'nonce'   => wp_create_nonce( 'subscrpt_integration_install_nonce' ),
				'ajaxUrl' => admin_url( 'admin-ajax.php' ),
			)
		);
	}

	/**
	 * Register settings options.
	 **/
	public function register_settings() {
		register_setting(
			'wp_subscription_settings',
			'wp_subscription_renewal_process',
			array(
				'type'              => 'string',
				'sanitize_callback' => 'sanitize_text_field',
			)
		);
		register_setting(
			'wp_subscription_settings',
			'wp_subscription_manual_renew_cart_notice',
			array(
				'type'              => 'string',
				'sanitize_callback' => 'sanitize_textarea_field',
			)
		);
		register_setting(
			'wp_subscription_settings',
			'wp_subscription_active_role',
			array(
				'type'              => 'string',
				'sanitize_callback' => 'sanitize_text_field',
			)
		);
		register_setting(
			'wp_subscription_settings',
			'wp_subscription_unactive_role',
			array(
				'type'              => 'string',
				'sanitize_callback' => 'sanitize_text_field',
			)
		);
		register_setting(
			'wp_subscription_settings',
			'wp_subscription_stripe_auto_renew',
			array(
				'type'              => 'string',
				'sanitize_callback' => 'sanitize_text_field',
			)
		);
		register_setting(
			'wp_subscription_settings',
			'wp_subscription_stock_pause',
			array(
				'type'              => 'string',
				'sanitize_callback' => 'sanitize_text_field',
			)
		);
		register_setting(
			'wp_subscription_settings',
			'wp_subscription_stock_pause_threshold',
			array(
				'type'              => 'integer',
				'sanitize_callback' => 'absint',
			)
		);
		register_setting(
			'wp_subscription_settings',
			'wp_subscription_stock_auto_resume',
			array(
				'type'              => 'string',
				'sanitize_callback' => 'sanitize_text_field',
			)
		);
		register_setting(
			'wp_subscription_settings',
			'wp_subscription_auto_renewal_toggle',
			array(
				'type'              => 'string',
				'sanitize_callback' => 'sanitize_text_field',
			)
		);

		do_action( 'subscrpt_register_settings', 'subscrpt_settings' );
	}

	/**
	 * Settings HTML.
	 */
	public function settings_content() {
		$settings_fields = $this->settings_fields;
		$category_groups = SettingsHelper::category_groups( $settings_fields );
		$active_cat      = $this->get_active_category( $category_groups );

		// Header.
		$menu = new Menu();
		$menu->render_admin_header( __( 'Settings', 'subscription' ) );

		include 'views/settings.php';

		// Footer.
		$menu->render_admin_footer();
	}

	/**
	 * Which settings section the page opens on.
	 *
	 * Read from `?cat=`, and it has to be a query argument rather than a
	 * fragment: the form posts to `options.php`, which redirects back to
	 * `_wp_http_referer`, and a fragment never reaches the server. Keeping the
	 * section in the query string is what returns you to the panel you saved
	 * from.
	 *
	 * Validated against the sections that actually hold groups, so an unknown
	 * or hostile value — or one naming a section only Pro fills — opens the
	 * first real section rather than an empty panel.
	 *
	 * @param array<string,string[]> $category_groups Section key => group keys.
	 * @return string Section key, or an empty string when there are no groups.
	 */
	private function get_active_category( array $category_groups ) {
		$cats = array_keys( $category_groups );

		if ( empty( $cats ) ) {
			return '';
		}

		// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- read-only section selection, validated against the list above.
		$requested = isset( $_GET['cat'] ) ? sanitize_key( wp_unslash( $_GET['cat'] ) ) : '';

		// `all` stacks every section on one page; a known section opens just that
		// one. With nothing requested (or something invalid), open the first
		// section rather than the stacked "All Settings" view.
		if ( 'all' === $requested || in_array( $requested, $cats, true ) ) {
			return $requested;
		}

		return $cats[0];
	}

	/**
	 * Enqueue WooCommerce admin styles for settings page.
	 *
	 * @param string $hook The current admin page hook.
	 */
	public function enqueue_wc_admin_styles( $hook ) {
		// Only load on our settings page
		if ( isset( $_GET['post_type'] ) && strpos( sanitize_text_field( wp_unslash( $_GET['post_type'] ) ), 'subscrpt_order' ) !== false ) {
			// WooCommerce admin styles
			wp_enqueue_style( 'woocommerce_admin_styles', WC()->plugin_url() . '/assets/css/admin.css', array(), SUBSCRPT_VERSION );
			// Optional: WooCommerce enhanced select2
			wp_enqueue_style( 'woocommerce_admin_select2', WC()->plugin_url() . '/assets/css/select2.css', array(), SUBSCRPT_VERSION );
			wp_enqueue_script( 'select2' );
		}
	}
}

```
