PluginProbe
Subscriptions for WooCommerce with Stripe Recurring Payments / 2.0.0
Subscriptions for WooCommerce with Stripe Recurring Payments v2.0.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 1.4.1 1.4.2 1.5.0 1.5.1 All 61 releases
← All changes | includes/Installer.php +231 -4 1.3.02.0.0 View file →
@@ -1,8 +1,10 @@
1 1 <?php
2 2
3 3 namespace SpringDevs\Subscription;
4 4
5 +use SpringDevs\Subscription\Illuminate\Gateways\Paypal\PaypalDB;
6 +
5 7 /**
6 8 * Class Installer
7 9 *
8 10 * @package SpringDevs\Subscription
@@ -9,8 +11,15 @@
9 11 */
10 12 class Installer {
11 13
12 14 /**
15 + * Database schema version. Bump whenever a custom table changes.
16 + *
17 + * @var string
18 + */
19 + const DB_VERSION = '1.3.0';
20 +
21 + /**
13 22 * Run the installer
14 23 *
15 24 * @return void
16 25 */
@@ -15,12 +24,29 @@
15 24 * @return void
16 25 */
17 26 public function run() {
18 27 $this->add_version();
28 + $this->register_schedules();
19 29 $this->create_tables();
20 30 }
21 31
22 32 /**
33 + * Create/upgrade custom tables when the stored schema version is outdated.
34 + *
35 + * Lets existing installs pick up new tables on update without a manual
36 + * deactivate/reactivate. A single option read short-circuits once current.
37 + *
38 + * @return void
39 + */
40 + public static function maybe_upgrade() {
41 + if ( get_option( 'subscrpt_db_version' ) === self::DB_VERSION ) {
42 + return;
43 + }
44 +
45 + ( new self() )->create_tables();
46 + }
47 +
48 + /**
23 49 * Add time and version on DB
24 50 */
25 51 public function add_version() {
26 52 $installed = get_option( 'subscrpt_installed' );
@@ -30,13 +56,20 @@
30 56 }
31 57
32 58 update_option( 'subscrpt_version', SUBSCRPT_VERSION );
33 59
34 - if ( ! wp_next_scheduled( 'subscrpt_daily_cron' ) ) {
35 - wp_schedule_event( time(), 'daily', 'subscrpt_daily_cron' );
60 + update_option( 'subscrpt_manual_renew_cart_notice', 'Subscriptional product added to cart. Please complete the checkout to renew subscription.' );
61 + }
62 +
63 + /**
64 + * Register cron events.
65 + *
66 + * @return void
67 + */
68 + public function register_schedules() {
69 + if ( ! wp_next_scheduled( 'subscrpt_hourly_cron' ) ) {
70 + wp_schedule_event( strtotime( 'tomorrow midnight' ), 'hourly', 'subscrpt_hourly_cron' );
36 71 }
37 -
38 - update_option( 'subscrpt_manual_renew_cart_notice', 'Subscriptional product added to cart. Please complete the checkout to renew subscription.' );
39 72 }
40 73
41 74 /**
42 75 * Create necessary database tables
@@ -48,8 +81,202 @@
48 81 require_once ABSPATH . 'wp-admin/includes/upgrade.php';
49 82 }
50 83
51 84 $this->create_histories_table();
85 + $this->create_stats_snapshot_table();
86 + $this->create_cancellation_feedback_table();
87 + $this->create_plan_group_table();
88 + $this->create_plan_table();
89 + $this->create_plan_relation_table();
90 + PaypalDB::maybe_create_tables();
91 +
92 + update_option( 'subscrpt_db_version', self::DB_VERSION );
93 + }
94 +
95 + /**
96 + * Create the daily stats snapshot table.
97 + *
98 + * One row per calendar day holding the subscription status counts and the
99 + * total monthly recurring revenue (MRR) at snapshot time. Powers MRR/
100 + * subscription "over time" charts in reports and the recovery report.
101 + *
102 + * @return void
103 + */
104 + public function create_stats_snapshot_table() {
105 + global $wpdb;
106 +
107 + $charset_collate = $wpdb->get_charset_collate();
108 + $table_name = $wpdb->prefix . 'subscrpt_stats_snapshot';
109 +
110 + $schema = "CREATE TABLE IF NOT EXISTS `{$table_name}` (
111 + `id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
112 + `snapshot_date` DATE NOT NULL,
113 + `active_count` INT(11) NOT NULL DEFAULT 0,
114 + `pending_count` INT(11) NOT NULL DEFAULT 0,
115 + `on_hold_count` INT(11) NOT NULL DEFAULT 0,
116 + `cancelled_count` INT(11) NOT NULL DEFAULT 0,
117 + `expired_count` INT(11) NOT NULL DEFAULT 0,
118 + `pe_cancelled_count` INT(11) NOT NULL DEFAULT 0,
119 + `active_mrr` DECIMAL(14,2) NOT NULL DEFAULT 0,
120 + `created_at` DATETIME NOT NULL,
121 + PRIMARY KEY (`id`),
122 + UNIQUE KEY `snapshot_date` (`snapshot_date`)
123 + ) $charset_collate";
124 +
125 + dbDelta( $schema );
126 + }
127 +
128 + /**
129 + * Create the cancellation survey table.
130 + *
131 + * One row per subscription — the latest cancellation survey (a re-cancel after
132 + * reactivation overwrites the previous row rather than accumulating a log, so
133 + * churn-by-reason reports never double-count a subscription). Stores the
134 + * customer's stated reason (key + a label snapshot that survives later reason
135 + * edits/deletes) and optional comment. Consumed for churn tracking — the recovery
136 + * plugin joins its recovery log to this table on subscription_id.
137 + *
138 + * @return void
139 + */
140 + public function create_cancellation_feedback_table() {
141 + global $wpdb;
142 +
143 + $charset_collate = $wpdb->get_charset_collate();
144 + $table_name = $wpdb->prefix . 'subscrpt_cancellation_feedback';
145 +
146 + $schema = "CREATE TABLE IF NOT EXISTS `{$table_name}` (
147 + `id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
148 + `subscription_id` BIGINT(20) UNSIGNED NOT NULL,
149 + `customer_id` BIGINT(20) UNSIGNED NOT NULL DEFAULT 0,
150 + `reason_key` VARCHAR(60) NOT NULL DEFAULT '',
151 + `reason_label` VARCHAR(191) NOT NULL DEFAULT '',
152 + `comment` TEXT NULL,
153 + `created_at` DATETIME NOT NULL,
154 + PRIMARY KEY (`id`),
155 + KEY `subscription_id` (`subscription_id`),
156 + KEY `created_at` (`created_at`)
157 + ) $charset_collate";
158 +
159 + dbDelta( $schema );
160 + }
161 +
162 + /**
163 + * Create the subscription plan group table.
164 + *
165 + * A plan group is a named, reusable subscription plan (e.g. "Premium
166 + * Membership") attached to one or more products. This is the free base
167 + * schema; Pro adds columns on top via versioned migrations keyed on
168 + * `subscrpt_db_version`.
169 + *
170 + * type: 1 = Subscribe & Save, 2 = Recurring, 3 = Installment (free writes 2).
171 + * product_type: 1 = specific products, 2 = taxonomy (free writes 1).
172 + * data: JSON (group-level settings).
173 + *
174 + * @return void
175 + */
176 + public function create_plan_group_table() {
177 + global $wpdb;
178 +
179 + $charset_collate = $wpdb->get_charset_collate();
180 + $table_name = $wpdb->prefix . 'subscrpt_plan_group';
181 +
182 + $schema = "CREATE TABLE IF NOT EXISTS `{$table_name}` (
183 + `id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
184 + `type` TINYINT(2) NOT NULL DEFAULT 2,
185 + `product_type` TINYINT(2) NOT NULL DEFAULT 1,
186 + `title` VARCHAR(255) NOT NULL DEFAULT '',
187 + `status` VARCHAR(20) NOT NULL DEFAULT 'active',
188 + `data` LONGTEXT NULL,
189 + `created_at` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
190 + `updated_at` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
191 + PRIMARY KEY (`id`),
192 + KEY `type` (`type`),
193 + KEY `status` (`status`)
194 + ) $charset_collate";
195 +
196 + dbDelta( $schema );
197 + }
198 +
199 + /**
200 + * Create the subscription plan (term) table.
201 + *
202 + * A plan is one billing term inside a group (e.g. "every 1 month"). There is
203 + * no price column — pricing lives per product on the relation.
204 + *
205 + * billing_interval: 1 = day, 2 = week, 3 = month, 4 = year.
206 + * billing_length: expiry in cycles, 0 = unlimited.
207 + * price_mode: snapshot (default) | live (free always snapshot).
208 + *
209 + * @return void
210 + */
211 + public function create_plan_table() {
212 + global $wpdb;
213 +
214 + $charset_collate = $wpdb->get_charset_collate();
215 + $table_name = $wpdb->prefix . 'subscrpt_plan';
216 +
217 + $schema = "CREATE TABLE IF NOT EXISTS `{$table_name}` (
218 + `id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
219 + `plan_group_id` BIGINT(20) UNSIGNED NOT NULL,
220 + `title` VARCHAR(255) NOT NULL DEFAULT '',
221 + `type` TINYINT(2) NOT NULL DEFAULT 2,
222 + `billing_frequency` INT(11) NOT NULL DEFAULT 1,
223 + `billing_interval` TINYINT(2) NOT NULL DEFAULT 3,
224 + `billing_length` INT(11) NOT NULL DEFAULT 0,
225 + `signup_fee` LONGTEXT NULL,
226 + `free_trial` VARCHAR(50) NOT NULL DEFAULT '',
227 + `prepaid` TINYINT(1) NOT NULL DEFAULT 0,
228 + `offer` LONGTEXT NULL,
229 + `price_mode` VARCHAR(20) NOT NULL DEFAULT 'snapshot',
230 + `status` VARCHAR(20) NOT NULL DEFAULT 'active',
231 + `data` LONGTEXT NULL,
232 + `created_at` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
233 + `updated_at` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
234 + PRIMARY KEY (`id`),
235 + KEY `plan_group_id` (`plan_group_id`),
236 + KEY `status` (`status`)
237 + ) $charset_collate";
238 +
239 + dbDelta( $schema );
240 + }
241 +
242 + /**
243 + * Create the subscription plan relation table.
244 + *
245 + * The many-to-many join between a plan term and a product, carrying the
246 + * per-product price in its `data` JSON.
247 + *
248 + * oid: product id (type 1) or term id (type 2).
249 + * vid: variation id; 0 for simple products (free always 0).
250 + * type: 1 = product, 2 = taxonomy.
251 + * data: JSON price override (regular_price, sale_price, discount_type,
252 + * discount_value).
253 + * exclude: per-row toggle to hide one term for one product.
254 + *
255 + * @return void
256 + */
257 + public function create_plan_relation_table() {
258 + global $wpdb;
259 +
260 + $charset_collate = $wpdb->get_charset_collate();
261 + $table_name = $wpdb->prefix . 'subscrpt_plan_relation';
262 +
263 + $schema = "CREATE TABLE IF NOT EXISTS `{$table_name}` (
264 + `id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
265 + `plan_id` BIGINT(20) UNSIGNED NOT NULL,
266 + `oid` BIGINT(20) UNSIGNED NOT NULL,
267 + `vid` BIGINT(20) UNSIGNED NOT NULL DEFAULT 0,
268 + `type` TINYINT(2) NOT NULL DEFAULT 1,
269 + `data` LONGTEXT NULL,
270 + `exclude` TINYINT(1) NOT NULL DEFAULT 0,
271 + `status` VARCHAR(20) NOT NULL DEFAULT 'active',
272 + PRIMARY KEY (`id`),
273 + KEY `plan_id` (`plan_id`),
274 + KEY `plan_lookup` (`plan_id`,`type`,`oid`,`vid`),
275 + KEY `product_lookup` (`type`,`oid`,`vid`)
276 + ) $charset_collate";
277 +
278 + dbDelta( $schema );
52 279 }
53 280
54 281 /**
55 282 * Create histories table