';
+
+ woocommerce_wp_checkbox([
+ 'id' => '_woonoow_subscription_enabled',
+ 'label' => __('Enable Subscription', 'woonoow'),
+ 'description' => __('Enable recurring subscription billing for this product', 'woonoow'),
+ ]);
+
+ echo '
';
+
+ woocommerce_wp_select([
+ 'id' => '_woonoow_subscription_period',
+ 'label' => __('Billing Period', 'woonoow'),
+ 'description' => __('How often to bill the customer', 'woonoow'),
+ 'options' => [
+ 'day' => __('Daily', 'woonoow'),
+ 'week' => __('Weekly', 'woonoow'),
+ 'month' => __('Monthly', 'woonoow'),
+ 'year' => __('Yearly', 'woonoow'),
+ ],
+ 'value' => get_post_meta($post->ID, '_woonoow_subscription_period', true) ?: 'month',
+ ]);
+
+ woocommerce_wp_text_input([
+ 'id' => '_woonoow_subscription_interval',
+ 'label' => __('Billing Interval', 'woonoow'),
+ 'description' => __('Bill every X periods (e.g., 2 = every 2 months)', 'woonoow'),
+ 'type' => 'number',
+ 'value' => get_post_meta($post->ID, '_woonoow_subscription_interval', true) ?: 1,
+ 'custom_attributes' => [
+ 'min' => '1',
+ 'max' => '365',
+ 'step' => '1',
+ ],
+ ]);
+
+ woocommerce_wp_text_input([
+ 'id' => '_woonoow_subscription_trial_days',
+ 'label' => __('Free Trial Days', 'woonoow'),
+ 'description' => __('Number of free trial days before first billing (0 = no trial)', 'woonoow'),
+ 'type' => 'number',
+ 'value' => get_post_meta($post->ID, '_woonoow_subscription_trial_days', true) ?: 0,
+ 'custom_attributes' => [
+ 'min' => '0',
+ 'step' => '1',
+ ],
+ ]);
+
+ woocommerce_wp_text_input([
+ 'id' => '_woonoow_subscription_signup_fee',
+ 'label' => __('Sign-up Fee', 'woonoow') . ' (' . get_woocommerce_currency_symbol() . ')',
+ 'description' => __('One-time fee charged on first subscription order', 'woonoow'),
+ 'type' => 'text',
+ 'value' => get_post_meta($post->ID, '_woonoow_subscription_signup_fee', true) ?: '',
+ 'data_type' => 'price',
+ ]);
+
+ woocommerce_wp_text_input([
+ 'id' => '_woonoow_subscription_length',
+ 'label' => __('Subscription Length', 'woonoow'),
+ 'description' => __('Number of billing periods (0 = unlimited/until cancelled)', 'woonoow'),
+ 'type' => 'number',
+ 'value' => get_post_meta($post->ID, '_woonoow_subscription_length', true) ?: 0,
+ 'custom_attributes' => [
+ 'min' => '0',
+ 'step' => '1',
+ ],
+ ]);
+
+ echo '
'; // .woonoow-subscription-options
+
+ // Add inline script to show/hide options based on checkbox
+?>
+
+'; // .options_group
+ }
+
+ /**
+ * Save subscription fields
+ */
+ public static function save_product_subscription_fields($post_id)
+ {
+ $subscription_enabled = isset($_POST['_woonoow_subscription_enabled']) ? 'yes' : 'no';
+ update_post_meta($post_id, '_woonoow_subscription_enabled', $subscription_enabled);
+
+ if (isset($_POST['_woonoow_subscription_period'])) {
+ update_post_meta($post_id, '_woonoow_subscription_period', sanitize_text_field($_POST['_woonoow_subscription_period']));
+ }
+
+ if (isset($_POST['_woonoow_subscription_interval'])) {
+ update_post_meta($post_id, '_woonoow_subscription_interval', absint($_POST['_woonoow_subscription_interval']));
+ }
+
+ if (isset($_POST['_woonoow_subscription_trial_days'])) {
+ update_post_meta($post_id, '_woonoow_subscription_trial_days', absint($_POST['_woonoow_subscription_trial_days']));
+ }
+
+ if (isset($_POST['_woonoow_subscription_signup_fee'])) {
+ update_post_meta($post_id, '_woonoow_subscription_signup_fee', wc_format_decimal($_POST['_woonoow_subscription_signup_fee']));
+ }
+
+ if (isset($_POST['_woonoow_subscription_length'])) {
+ update_post_meta($post_id, '_woonoow_subscription_length', absint($_POST['_woonoow_subscription_length']));
+ }
+ }
+
+ /**
+ * Maybe create subscription from completed order
+ */
+ public static function maybe_create_subscription($order_id)
+ {
+ if (!ModuleRegistry::is_enabled('subscription')) {
+ return;
+ }
+
+ $order = wc_get_order($order_id);
+ if (!$order) {
+ return;
+ }
+
+ // Check if subscription already created for this order
+ if ($order->get_meta('_woonoow_subscription_created')) {
+ return;
+ }
+
+ foreach ($order->get_items() as $item) {
+ $product_id = $item->get_product_id();
+ $variation_id = $item->get_variation_id();
+
+ // Check if product has subscription enabled
+ if (get_post_meta($product_id, '_woonoow_subscription_enabled', true) !== 'yes') {
+ continue;
+ }
+
+ // Create subscription for this product
+ SubscriptionManager::create_from_order($order, $item);
+ }
+
+ // Mark order as processed
+ $order->update_meta_data('_woonoow_subscription_created', 'yes');
+ $order->save();
+ }
+
+ /**
+ * Modify add to cart button text for subscription products
+ */
+ public static function subscription_add_to_cart_text($text, $product)
+ {
+ if (!ModuleRegistry::is_enabled('subscription')) {
+ return $text;
+ }
+
+ $product_id = $product->get_id();
+ if (get_post_meta($product_id, '_woonoow_subscription_enabled', true) === 'yes') {
+ $settings = ModuleRegistry::get_settings('subscription');
+ return $settings['button_text_subscribe'] ?? __('Subscribe Now', 'woonoow');
+ }
+
+ return $text;
+ }
+
+ /**
+ * Register subscription notification events
+ *
+ * @param array $events Existing events
+ * @return array Updated events
+ */
+ public static function register_notification_events($events)
+ {
+ // Customer notifications
+ $events['subscription_pending_cancel'] = [
+ 'id' => 'subscription_pending_cancel',
+ 'label' => __('Subscription Pending Cancellation', 'woonoow'),
+ 'description' => __('When a subscription is scheduled for cancellation at period end', 'woonoow'),
+ 'category' => 'subscriptions',
+ 'recipient_type' => 'customer',
+ 'wc_email' => '',
+ 'enabled' => true,
+ 'variables' => self::get_subscription_variables(),
+ ];
+
+ $events['subscription_cancelled'] = [
+ 'id' => 'subscription_cancelled',
+ 'label' => __('Subscription Cancelled', 'woonoow'),
+ 'description' => __('When a subscription is cancelled and access ends', 'woonoow'),
+ 'category' => 'subscriptions',
+ 'recipient_type' => 'customer',
+ 'wc_email' => '',
+ 'enabled' => true,
+ 'variables' => self::get_subscription_variables(),
+ ];
+
+ $events['subscription_expired'] = [
+ 'id' => 'subscription_expired',
+ 'label' => __('Subscription Expired', 'woonoow'),
+ 'description' => __('When a subscription expires due to end date or failed payments', 'woonoow'),
+ 'category' => 'subscriptions',
+ 'recipient_type' => 'customer',
+ 'wc_email' => '',
+ 'enabled' => true,
+ 'variables' => self::get_subscription_variables(),
+ ];
+
+ $events['subscription_paused'] = [
+ 'id' => 'subscription_paused',
+ 'label' => __('Subscription Paused', 'woonoow'),
+ 'description' => __('When a subscription is put on hold', 'woonoow'),
+ 'category' => 'subscriptions',
+ 'recipient_type' => 'customer',
+ 'wc_email' => '',
+ 'enabled' => true,
+ 'variables' => self::get_subscription_variables(),
+ ];
+
+ $events['subscription_resumed'] = [
+ 'id' => 'subscription_resumed',
+ 'label' => __('Subscription Resumed', 'woonoow'),
+ 'description' => __('When a subscription is resumed from pause', 'woonoow'),
+ 'category' => 'subscriptions',
+ 'recipient_type' => 'customer',
+ 'wc_email' => '',
+ 'enabled' => true,
+ 'variables' => self::get_subscription_variables(),
+ ];
+
+ $events['subscription_renewal_failed'] = [
+ 'id' => 'subscription_renewal_failed',
+ 'label' => __('Subscription Renewal Failed', 'woonoow'),
+ 'description' => __('When a renewal payment fails', 'woonoow'),
+ 'category' => 'subscriptions',
+ 'recipient_type' => 'customer',
+ 'wc_email' => '',
+ 'enabled' => true,
+ 'variables' => self::get_subscription_variables(),
+ ];
+
+ $events['subscription_renewal_payment_due'] = [
+ 'id' => 'subscription_renewal_payment_due',
+ 'label' => __('Subscription Renewal Payment Due', 'woonoow'),
+ 'description' => __('When a manual payment is required for subscription renewal', 'woonoow'),
+ 'category' => 'subscriptions',
+ 'recipient_type' => 'customer',
+ 'wc_email' => '',
+ 'enabled' => true,
+ 'variables' => array_merge(self::get_subscription_variables(), [
+ '{payment_link}' => __('Link to payment page', 'woonoow'),
+ ]),
+ ];
+
+ $events['subscription_renewal_reminder'] = [
+ 'id' => 'subscription_renewal_reminder',
+ 'label' => __('Subscription Renewal Reminder', 'woonoow'),
+ 'description' => __('Reminder before subscription renewal', 'woonoow'),
+ 'category' => 'subscriptions',
+ 'recipient_type' => 'customer',
+ 'wc_email' => '',
+ 'enabled' => true,
+ 'variables' => self::get_subscription_variables(),
+ ];
+
+ // Staff notifications
+ $events['subscription_cancelled_admin'] = [
+ 'id' => 'subscription_cancelled',
+ 'label' => __('Subscription Cancelled', 'woonoow'),
+ 'description' => __('When a customer cancels their subscription', 'woonoow'),
+ 'category' => 'subscriptions',
+ 'recipient_type' => 'staff',
+ 'wc_email' => '',
+ 'enabled' => true,
+ 'variables' => self::get_subscription_variables(),
+ ];
+
+ $events['subscription_renewal_failed_admin'] = [
+ 'id' => 'subscription_renewal_failed',
+ 'label' => __('Subscription Renewal Failed', 'woonoow'),
+ 'description' => __('When a subscription renewal payment fails', 'woonoow'),
+ 'category' => 'subscriptions',
+ 'recipient_type' => 'staff',
+ 'wc_email' => '',
+ 'enabled' => true,
+ 'variables' => self::get_subscription_variables(),
+ ];
+
+ return $events;
+ }
+
+ /**
+ * Get subscription-specific template variables
+ *
+ * @return array
+ */
+ private static function get_subscription_variables()
+ {
+ return [
+ '{subscription_id}' => __('Subscription ID', 'woonoow'),
+ '{subscription_status}' => __('Subscription status', 'woonoow'),
+ '{product_name}' => __('Product name', 'woonoow'),
+ '{billing_period}' => __('Billing period (e.g., monthly)', 'woonoow'),
+ '{recurring_amount}' => __('Recurring payment amount', 'woonoow'),
+ '{next_payment_date}' => __('Next payment date', 'woonoow'),
+ '{end_date}' => __('Subscription end date', 'woonoow'),
+ '{cancel_reason}' => __('Cancellation reason', 'woonoow'),
+ ];
+ }
+
+ /**
+ * Handle pending cancellation notification
+ */
+ public static function on_pending_cancel($subscription_id, $reason = '')
+ {
+ self::send_subscription_notification('subscription_pending_cancel', $subscription_id, $reason);
+ }
+
+ /**
+ * Handle cancellation notification
+ */
+ public static function on_cancelled($subscription_id, $reason = '')
+ {
+ self::send_subscription_notification('subscription_cancelled', $subscription_id, $reason);
+ }
+
+ /**
+ * Handle expiration notification
+ */
+ public static function on_expired($subscription_id, $reason = '')
+ {
+ self::send_subscription_notification('subscription_expired', $subscription_id, $reason);
+ }
+
+ /**
+ * Handle pause notification
+ */
+ public static function on_paused($subscription_id)
+ {
+ self::send_subscription_notification('subscription_paused', $subscription_id);
+ }
+
+ /**
+ * Handle resume notification
+ */
+ public static function on_resumed($subscription_id)
+ {
+ self::send_subscription_notification('subscription_resumed', $subscription_id);
+ }
+
+ /**
+ * Handle renewal failed notification
+ */
+ public static function on_renewal_failed($subscription_id, $failed_count)
+ {
+ self::send_subscription_notification('subscription_renewal_failed', $subscription_id, '', $failed_count);
+ }
+
+ /**
+ * Handle renewal payment due notification
+ */
+ public static function on_renewal_payment_due($subscription_id, $order = null)
+ {
+ $payment_link = '';
+ if ($order && is_a($order, 'WC_Order')) {
+ $payment_link = $order->get_checkout_payment_url();
+ }
+ self::send_subscription_notification('subscription_renewal_payment_due', $subscription_id, '', 0, ['payment_link' => $payment_link]);
+ }
+
+ /**
+ * Handle renewal reminder notification
+ */
+ public static function on_renewal_reminder($subscription)
+ {
+ if (!$subscription || !isset($subscription->id)) {
+ return;
+ }
+ self::send_subscription_notification('subscription_renewal_reminder', $subscription->id);
+ }
+
+ /**
+ * Send subscription notification
+ *
+ * @param string $event_id Event ID
+ * @param int $subscription_id Subscription ID
+ * @param string $reason Optional reason
+ * @param int $failed_count Optional failed payment count
+ * @param array $extra_data Optional extra data variables
+ */
+ private static function send_subscription_notification($event_id, $subscription_id, $reason = '', $failed_count = 0, $extra_data = [])
+ {
+ $subscription = SubscriptionManager::get($subscription_id);
+ if (!$subscription) {
+ return;
+ }
+
+ $user = get_user_by('id', $subscription->user_id);
+ $product = wc_get_product($subscription->product_id);
+
+ $data = [
+ 'subscription' => $subscription,
+ 'customer' => $user,
+ 'product' => $product,
+ 'reason' => $reason,
+ 'failed_count' => $failed_count,
+ 'payment_link' => $extra_data['payment_link'] ?? '',
+ ];
+
+ // Send via NotificationManager
+ if (class_exists('\\WooNooW\\Core\\Notifications\\NotificationManager')) {
+ \WooNooW\Core\Notifications\NotificationManager::send($event_id, 'email', $data);
+ }
+ }
+
+ /**
+ * Handle manual renewal payment completion
+ */
+ public static function on_order_status_changed($order_id, $old_status, $new_status)
+ {
+ if (!ModuleRegistry::is_enabled('subscription')) {
+ return;
+ }
+
+ if (!in_array($new_status, ['processing', 'completed'])) {
+ return;
+ }
+
+ // Check if this is a subscription renewal order
+ global $wpdb;
+ $table_orders = $wpdb->prefix . 'woonoow_subscription_orders';
+
+ $link = $wpdb->get_row($wpdb->prepare(
+ "SELECT subscription_id, order_type FROM $table_orders WHERE order_id = %d",
+ $order_id
+ ));
+
+ if ($link && $link->order_type === 'renewal') {
+ $order = wc_get_order($order_id);
+ if ($order) {
+ SubscriptionManager::handle_renewal_success($link->subscription_id, $order);
+ }
+ }
+ }
+}
diff --git a/includes/Modules/Subscription/SubscriptionScheduler.php b/includes/Modules/Subscription/SubscriptionScheduler.php
new file mode 100644
index 0000000..904d9d8
--- /dev/null
+++ b/includes/Modules/Subscription/SubscriptionScheduler.php
@@ -0,0 +1,263 @@
+id);
+
+ try {
+ $success = SubscriptionManager::renew($subscription->id);
+
+ if ($success) {
+ do_action('woonoow/subscription/renewal_completed', $subscription->id);
+ } else {
+ // Auto-debit failed (returns false), so schedule retry
+ // Note: 'manual' falls into a separate bucket in SubscriptionManager and returns true (handled)
+ self::schedule_retry($subscription->id);
+ }
+ } catch (\Exception $e) {
+ // Log error
+ error_log('[WooNooW Subscription] Renewal failed for subscription #' . $subscription->id . ': ' . $e->getMessage());
+ do_action('woonoow/subscription/renewal_error', $subscription->id, $e);
+
+ // Also schedule retry on exception
+ self::schedule_retry($subscription->id);
+ }
+ }
+ }
+
+ /**
+ * Check for expired subscriptions
+ */
+ public static function check_expirations()
+ {
+ global $wpdb;
+
+ if (!ModuleRegistry::is_enabled('subscription')) {
+ return;
+ }
+
+ $table = $wpdb->prefix . 'woonoow_subscriptions';
+ $now = current_time('mysql');
+
+ // Find subscriptions that have passed their end date
+ $expired = $wpdb->get_results($wpdb->prepare(
+ "SELECT id FROM $table
+ WHERE status = 'active'
+ AND end_date IS NOT NULL
+ AND end_date <= %s",
+ $now
+ ));
+
+ foreach ($expired as $subscription) {
+ SubscriptionManager::update_status($subscription->id, 'expired');
+ do_action('woonoow/subscription/expired', $subscription->id, 'end_date_reached');
+ }
+
+ // Also check pending-cancel subscriptions that need to be finalized
+ $pending_cancel = $wpdb->get_results($wpdb->prepare(
+ "SELECT id FROM $table
+ WHERE status = 'pending-cancel'
+ AND next_payment_date IS NOT NULL
+ AND next_payment_date <= %s",
+ $now
+ ));
+
+ foreach ($pending_cancel as $subscription) {
+ SubscriptionManager::update_status($subscription->id, 'cancelled');
+ do_action('woonoow/subscription/cancelled', $subscription->id, 'pending_cancel_completed');
+ }
+ }
+
+ /**
+ * Send renewal reminder emails
+ */
+ public static function send_reminders()
+ {
+ global $wpdb;
+
+ if (!ModuleRegistry::is_enabled('subscription')) {
+ return;
+ }
+
+ // Check if reminders are enabled
+ $settings = ModuleRegistry::get_settings('subscription');
+ if (empty($settings['send_renewal_reminder'])) {
+ return;
+ }
+
+ $days_before = $settings['reminder_days_before'] ?? 3;
+ $reminder_date = date('Y-m-d H:i:s', strtotime("+$days_before days"));
+ $tomorrow = date('Y-m-d H:i:s', strtotime('+' . ($days_before + 1) . ' days'));
+
+ $table = $wpdb->prefix . 'woonoow_subscriptions';
+
+ // Find subscriptions due for reminder (that haven't had reminder sent for this billing cycle)
+ $due_reminders = $wpdb->get_results($wpdb->prepare(
+ "SELECT * FROM $table
+ WHERE status = 'active'
+ AND next_payment_date IS NOT NULL
+ AND next_payment_date >= %s
+ AND next_payment_date < %s
+ AND (reminder_sent_at IS NULL OR reminder_sent_at < last_payment_date OR (last_payment_date IS NULL AND reminder_sent_at < start_date))",
+ $reminder_date,
+ $tomorrow
+ ));
+
+ foreach ($due_reminders as $subscription) {
+ // Trigger reminder email
+ do_action('woonoow/subscription/renewal_reminder', $subscription);
+
+ // Mark reminder as sent in database
+ $wpdb->update(
+ $table,
+ ['reminder_sent_at' => current_time('mysql')],
+ ['id' => $subscription->id],
+ ['%s'],
+ ['%d']
+ );
+ }
+ }
+
+ /**
+ * Get retry schedule for failed payments
+ *
+ * @param int $subscription_id
+ * @return string|null Next retry datetime or null if no more retries
+ */
+ public static function get_next_retry_date($subscription_id)
+ {
+ $subscription = SubscriptionManager::get($subscription_id);
+ if (!$subscription) {
+ return null;
+ }
+
+ $settings = ModuleRegistry::get_settings('subscription');
+
+ if (empty($settings['renewal_retry_enabled'])) {
+ return null;
+ }
+
+ $retry_days_str = $settings['renewal_retry_days'] ?? '1,3,5';
+ $retry_days = array_map('intval', array_filter(explode(',', $retry_days_str)));
+
+ $failed_count = $subscription->failed_payment_count;
+
+ if ($failed_count >= count($retry_days)) {
+ return null; // No more retries
+ }
+
+ $days_to_add = $retry_days[$failed_count] ?? 1;
+ return date('Y-m-d H:i:s', strtotime("+$days_to_add days"));
+ }
+
+ /**
+ * Schedule a retry for failed payment
+ *
+ * @param int $subscription_id
+ */
+ public static function schedule_retry($subscription_id)
+ {
+ global $wpdb;
+
+ $next_retry = self::get_next_retry_date($subscription_id);
+
+ if ($next_retry) {
+ $table = $wpdb->prefix . 'woonoow_subscriptions';
+ $wpdb->update(
+ $table,
+ ['next_payment_date' => $next_retry],
+ ['id' => $subscription_id],
+ ['%s'],
+ ['%d']
+ );
+ }
+ }
+}
diff --git a/includes/Modules/SubscriptionSettings.php b/includes/Modules/SubscriptionSettings.php
new file mode 100644
index 0000000..6bedf91
--- /dev/null
+++ b/includes/Modules/SubscriptionSettings.php
@@ -0,0 +1,109 @@
+ [
+ 'type' => 'select',
+ 'label' => __('Default Subscription Status', 'woonoow'),
+ 'description' => __('Status for new subscriptions after successful payment', 'woonoow'),
+ 'options' => [
+ 'active' => __('Active', 'woonoow'),
+ 'pending' => __('Pending', 'woonoow'),
+ ],
+ 'default' => 'active',
+ ],
+ 'button_text_subscribe' => [
+ 'type' => 'text',
+ 'label' => __('Subscribe Button Text', 'woonoow'),
+ 'description' => __('Text for the subscribe button on subscription products', 'woonoow'),
+ 'placeholder' => 'Subscribe Now',
+ 'default' => 'Subscribe Now',
+ ],
+ 'button_text_renew' => [
+ 'type' => 'text',
+ 'label' => __('Renew Button Text', 'woonoow'),
+ 'description' => __('Text for the renewal button', 'woonoow'),
+ 'placeholder' => 'Renew Subscription',
+ 'default' => 'Renew Subscription',
+ ],
+ 'allow_customer_cancel' => [
+ 'type' => 'toggle',
+ 'label' => __('Allow Customer Cancellation', 'woonoow'),
+ 'description' => __('Allow customers to cancel their own subscriptions', 'woonoow'),
+ 'default' => true,
+ ],
+ 'allow_customer_pause' => [
+ 'type' => 'toggle',
+ 'label' => __('Allow Customer Pause', 'woonoow'),
+ 'description' => __('Allow customers to pause and resume their subscriptions', 'woonoow'),
+ 'default' => true,
+ ],
+ 'max_pause_count' => [
+ 'type' => 'number',
+ 'label' => __('Maximum Pause Count', 'woonoow'),
+ 'description' => __('Maximum number of times a subscription can be paused (0 = unlimited)', 'woonoow'),
+ 'default' => 3,
+ 'min' => 0,
+ 'max' => 10,
+ ],
+ 'renewal_retry_enabled' => [
+ 'type' => 'toggle',
+ 'label' => __('Retry Failed Renewals', 'woonoow'),
+ 'description' => __('Automatically retry failed renewal payments', 'woonoow'),
+ 'default' => true,
+ ],
+ 'renewal_retry_days' => [
+ 'type' => 'text',
+ 'label' => __('Retry Days', 'woonoow'),
+ 'description' => __('Days after failure to retry payment (comma-separated, e.g., 1,3,5)', 'woonoow'),
+ 'placeholder' => '1,3,5',
+ 'default' => '1,3,5',
+ ],
+ 'expire_after_failed_attempts' => [
+ 'type' => 'number',
+ 'label' => __('Max Failed Attempts', 'woonoow'),
+ 'description' => __('Number of failed payment attempts before subscription expires', 'woonoow'),
+ 'default' => 3,
+ 'min' => 1,
+ 'max' => 10,
+ ],
+ 'send_renewal_reminder' => [
+ 'type' => 'toggle',
+ 'label' => __('Send Renewal Reminders', 'woonoow'),
+ 'description' => __('Send email reminder before subscription renewal', 'woonoow'),
+ 'default' => true,
+ ],
+ 'reminder_days_before' => [
+ 'type' => 'number',
+ 'label' => __('Reminder Days Before', 'woonoow'),
+ 'description' => __('Days before renewal to send reminder email', 'woonoow'),
+ 'default' => 3,
+ 'min' => 1,
+ 'max' => 14,
+ ],
+ ];
+
+ return $schemas;
+ }
+}
diff --git a/woonoow.php b/woonoow.php
index 84665d6..845eb4e 100644
--- a/woonoow.php
+++ b/woonoow.php
@@ -13,6 +13,7 @@ if (!defined('ABSPATH')) exit;
define('WOONOOW_PATH', plugin_dir_path(__FILE__));
define('WOONOOW_URL', plugin_dir_url(__FILE__));
define('WOONOOW_VERSION', '0.1.0');
+define('WOONOOW_PLUGIN_FILE', __FILE__);
spl_autoload_register(function ($class) {
$prefix = 'WooNooW\\';
@@ -41,6 +42,7 @@ add_action('plugins_loaded', function () {
WooNooW\Modules\NewsletterSettings::init();
WooNooW\Modules\WishlistSettings::init();
WooNooW\Modules\Licensing\LicensingModule::init();
+ WooNooW\Modules\Subscription\SubscriptionModule::init();
});
// Activation/Deactivation hooks