PluginProbe
Subscriptions for WooCommerce with Stripe Recurring Payments / 1.4.1
Subscriptions for WooCommerce with Stripe Recurring Payments v1.4.1
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
subscription / includes / Admin / Subscriptions.php

Subscriptions.php in Subscriptions for WooCommerce with Stripe Recurring Payments 1.4.1, at includes/Admin/Subscriptions.php

676 lines 24.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace SpringDevs\Subscription\Admin;
4
5 use SpringDevs\Subscription\Illuminate\Action;
6 use SpringDevs\Subscription\Illuminate\Helper;
7
8 // HPOS: This file is compatible with WooCommerce High-Performance Order Storage (HPOS).
9 // All WooCommerce order data is accessed via WooCommerce CRUD methods (wc_get_order, etc.).
10 // All direct post meta access is for subscription data only, not WooCommerce order data.
11 // If you add new order data access, use WooCommerce CRUD for HPOS compatibility.
12
13 /**
14 * Subscriptions class
15 *
16 * @package SpringDevs\Subscription\Admin
17 */
18 class Subscriptions {
19
20
21 /**
22 * Initialize the class.
23 */
24 public function __construct() {
25 add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
26 add_filter( 'post_row_actions', array( $this, 'post_row_actions' ) );
27 add_filter( 'manage_subscrpt_order_posts_columns', array( $this, 'add_custom_columns' ) );
28 add_action( 'manage_subscrpt_order_posts_custom_column', array( $this, 'add_custom_columns_data' ), 10, 2 );
29 add_action( 'add_meta_boxes', array( $this, 'create_meta_boxes' ) );
30 add_action( 'admin_head-post.php', array( $this, 'some_styles' ) );
31 add_action( 'admin_head-post-new.php', array( $this, 'some_styles' ) );
32 add_action( 'admin_footer-post.php', array( $this, 'some_scripts' ) );
33 add_action( 'admin_footer-post-new.php', array( $this, 'some_scripts' ) );
34 add_action( 'save_post', array( $this, 'save_subscrpt_order' ) );
35 add_filter( 'woocommerce_order_item_get_formatted_meta_data', array( $this, 'remove_order_meta' ), 10, 1 );
36 add_filter( 'bulk_actions-edit-subscrpt_order', array( $this, 'remove_bulk_actions' ) );
37 add_action( 'restrict_manage_posts', array( $this, 'add_subscription_filter_select' ) );
38 add_action( 'admin_menu', array( $this, 'add_overview_submenu' ), 40 );
39 }
40
41 /**
42 * Remove 'Edit` and 'Trash' from bulk actions.
43 *
44 * @param array $actions Action list.
45 *
46 * @return array
47 */
48 public function remove_bulk_actions( $actions ) {
49 unset( $actions['edit'] );
50 unset( $actions['trash'] );
51
52 return $actions;
53 }
54
55 /**
56 * Hide order meta key from custom fields.
57 *
58 * @param array $formatted_meta Data with key-value.
59 *
60 * @return array
61 */
62 public function remove_order_meta( $formatted_meta ): array {
63 $temp_metas = array();
64 foreach ( $formatted_meta as $key => $meta ) {
65 if ( isset( $meta->key ) && '_renew_subscrpt' !== $meta->key ) {
66 $temp_metas[ $key ] = $meta;
67 }
68 }
69
70 return $temp_metas;
71 }
72
73 /**
74 * Enqueue admin assets.
75 *
76 * @return void
77 */
78 public function enqueue_scripts() {
79 wp_enqueue_style( 'subscrpt_admin_css' );
80 wp_enqueue_style( 'subscrpt_status_css' );
81 }
82
83 /**
84 * Remove default post actions.
85 *
86 * @param array $actions Actions.
87 *
88 * @return array
89 */
90 public function post_row_actions( $actions ) {
91 global $current_screen;
92 if ( 'subscrpt_order' !== $current_screen->post_type ) {
93 return $actions;
94 }
95 unset( $actions['inline hide-if-no-js'] );
96 unset( $actions['view'] );
97 unset( $actions['trash'] );
98 unset( $actions['edit'] );
99
100 return $actions;
101 }
102
103 /**
104 * Register custom columns.
105 *
106 * @param array $columns Columns.
107 *
108 * @return array
109 */
110 public function add_custom_columns( $columns ) {
111 $columns['subscrpt_start_date'] = __( 'Start Date', 'sdevs_subscrpt' );
112 $columns['subscrpt_customer'] = __( 'Customer', 'sdevs_subscrpt' );
113 $columns['subscrpt_next_date'] = __( 'Next Date', 'sdevs_subscrpt' );
114 $columns['subscrpt_status'] = __( 'Status', 'sdevs_subscrpt' );
115 unset( $columns['date'] );
116 unset( $columns['cb'] );
117
118 return $columns;
119 }
120
121 /**
122 * Display column data.
123 *
124 * @param string $column Column.
125 * @param int $post_id Post Id.
126 *
127 * @return void
128 */
129 public function add_custom_columns_data( $column, $post_id ) {
130 // HPOS: Safe. Only retrieves WooCommerce order via CRUD, and subscription meta via post meta.
131 $order_id = get_post_meta( $post_id, '_subscrpt_order_id', true ); // HPOS: Only subscription meta, not order meta.
132 $order = wc_get_order( $order_id ); // HPOS: Safe, uses WooCommerce CRUD.
133 if ( $order ) {
134 if ( 'subscrpt_start_date' === $column ) {
135 $start_date = get_post_meta( $post_id, '_subscrpt_start_date', true );
136 echo ! empty( $start_date ) ? esc_html( gmdate( 'F d, Y', $start_date ) ) : '-';
137 } elseif ( 'subscrpt_customer' === $column ) {
138 ?>
139 <?php echo wp_kses_post( $order->get_formatted_billing_full_name() ); ?>
140 <br />
141 <a href="mailto:<?php echo wp_kses_post( $order->get_billing_email() ); ?>"><?php echo wp_kses_post( $order->get_billing_email() ); ?></a>
142 <br />
143 <?php if ( ! empty( $order->get_billing_phone() ) ) : ?>
144 Phone : <a
145 href="tel:<?php echo esc_js( $order->get_billing_phone() ); ?>"><?php echo esc_js( $order->get_billing_phone() ); ?></a>
146 <?php endif; ?>
147 <?php
148 } elseif ( 'subscrpt_next_date' === $column ) {
149 $next_date = get_post_meta( $post_id, '_subscrpt_next_date', true );
150 echo ! empty( $next_date ) ? esc_html( gmdate( 'F d, Y', $next_date ) ) : '-';
151 } elseif ( 'subscrpt_status' === $column ) {
152 $status_obj = get_post_status_object( get_post_status( $post_id ) );
153 ?>
154 <span
155 class="subscrpt-<?php echo esc_html( $status_obj->name ); ?>"><?php echo esc_html( $status_obj->label ); ?></span>
156 <?php
157 }
158 } else {
159 esc_html_e( 'Order not found !!', 'sdevs_subscrpt' );
160 }
161 }
162
163 /**
164 * Create meta boxes for admin subscriptions.
165 */
166 public function create_meta_boxes() {
167 remove_meta_box( 'submitdiv', 'subscrpt_order', 'side' );
168 add_meta_box(
169 'subscrpt_order_save_post',
170 __( 'Subscription Action', 'sdevs_subscrpt' ),
171 array( $this, 'subscrpt_order_save_post' ),
172 'subscrpt_order',
173 'side',
174 'default'
175 );
176
177 add_meta_box(
178 'subscrpt_customer_info',
179 __( 'Customer Info', 'sdevs_subscrpt' ),
180 array( $this, 'customer_info' ),
181 'subscrpt_order',
182 'side',
183 'default'
184 );
185
186 add_meta_box(
187 'subscrpt_order_info',
188 __( 'Subscription Info', 'sdevs_subscrpt' ),
189 array( $this, 'subscrpt_order_info' ),
190 'subscrpt_order',
191 'normal',
192 'default'
193 );
194
195 add_meta_box(
196 'subscrpt_order_history',
197 __( 'Subscription History', 'sdevs_subscrpt' ),
198 array( $this, 'order_histories' ),
199 'subscrpt_order',
200 'normal',
201 'default'
202 );
203
204 add_meta_box(
205 'subscrpt_order_activities',
206 __( 'Subscription Activities', 'sdevs_subscrpt' ),
207 array( $this, 'order_activities' ),
208 'subscrpt_order',
209 'normal',
210 'default'
211 );
212 }
213
214 /**
215 * Display Order Histories.
216 *
217 * @param \WP_Post $post Post Object.
218 *
219 * @return void
220 */
221 public function order_histories( $post ) {
222 $subscription_id = $post->ID;
223 global $wpdb;
224 $table_name = $wpdb->prefix . 'subscrpt_order_relation';
225 // @phpcs:ignore
226 $order_histories = $wpdb->get_results( $wpdb->prepare( 'SELECT * FROM %i WHERE subscription_id=%d', array(
227 $table_name,
228 $subscription_id,
229 )
230 )
231 );
232
233 include 'views/order-history.php';
234 }
235
236 /**
237 * Display Order Activities
238 *
239 * @param \WP_Post $post Post Object.
240 *
241 * @return void
242 */
243 public function order_activities( $post ) {
244 if ( function_exists( 'subscrpt_pro_activated' ) ) :
245 if ( subscrpt_pro_activated() ) :
246 do_action( 'subscrpt_order_activities', $post->ID );
247 else :
248 ?>
249 <div class="wp-subscription-admin-box wp-subscription-upgrade-pro-banner" style="margin-bottom:18px;display:flex;align-items:center;gap:18px;justify-content:space-between;background:linear-gradient(90deg,#38bdf8 0%,#6366f1 100%);border-radius:10px;padding:22px 28px;box-shadow:0 2px 12px rgba(56,189,248,0.08);color:#fff;">
250 <div style="flex:1;">
251 <div style="display:flex;align-items:center;gap:14px;">
252 <span style="font-size:2.2em;line-height:1;">🚀</span>
253 <span style="font-family:Georgia,serif;font-size:1.25em;font-weight:bold;">Upgrade to WP Subscription Pro</span>
254 </div>
255 <div style="margin-top:8px;font-size:1.08em;max-width:500px;opacity:0.95;">
256 Unlock advanced features, automation, and priority support. Take your subscription business to the next level!
257 </div>
258 </div>
259 <div style="flex-shrink:0;">
260 <a href="https://wpsubscription.co/" target="_blank" class="button button-primary" style="background:#fff;color:#6366f1;font-weight:600;font-size:1.08em;padding:12px 28px;border:none;box-shadow:0 2px 8px rgba(99,102,241,0.10);border-radius:6px;">Upgrade to Pro</a>
261 </div>
262 </div>
263 <?php
264 endif;
265 endif;
266 }
267
268 /**
269 * Save subscription HTML.
270 */
271 public function subscrpt_order_save_post() {
272 $actions_data = array(
273 'active' => array(
274 'label' => __( 'Activate Subscription', 'sdevs_subscrpt' ),
275 'value' => 'active',
276 ),
277 'pending' => array(
278 'label' => __( 'Pending Subscription', 'sdevs_subscrpt' ),
279 'value' => 'pending',
280 ),
281 'expire' => array(
282 'label' => __( 'Expire Subscription', 'sdevs_subscrpt' ),
283 'value' => 'expired',
284 ),
285 'pe_cancelled' => array(
286 'label' => __( 'Pending Cancel Subscription', 'sdevs_subscrpt' ),
287 'value' => 'pe_cancelled',
288 ),
289 'cancelled' => array(
290 'label' => __( 'Cancel Subscription', 'sdevs_subscrpt' ),
291 'value' => 'cancelled',
292 ),
293 );
294
295 $map_actions = array(
296 'pending' => array( 'active', 'cancelled' ),
297 'active' => array( 'pe_cancelled', 'cancelled' ),
298 'pe_cancelled' => array( 'active', 'cancelled' ),
299 'cancelled' => array( 'active' ),
300 'expired' => array(),
301 );
302
303 $status = get_post_status( get_the_ID() );
304 $actions = $map_actions[ $status ];
305
306 include 'views/subscription-save-meta.php';
307 }
308
309 /**
310 * Display Customer Info
311 *
312 * @param \WP_Post $post Post Object.
313 *
314 * @return void
315 */
316 public function customer_info( $post ) {
317 $order_id = get_post_meta( $post->ID, '_subscrpt_order_id', true );
318 $order = wc_get_order( $order_id );
319 if ( ! $order ) {
320 return;
321 }
322 include 'views/subscription-customer.php';
323 }
324
325 /**
326 * Display subscription info.
327 *
328 * @return void
329 */
330 public function subscrpt_order_info() {
331 $order_id = get_post_meta( get_the_ID(), '_subscrpt_order_id', true );
332 $order_item_id = get_post_meta( get_the_ID(), '_subscrpt_order_item_id', true );
333 $trial = get_post_meta( get_the_ID(), '_subscrpt_trial', true );
334 $start_date = get_post_meta( get_the_ID(), '_subscrpt_start_date', true );
335 $next_date = get_post_meta( get_the_ID(), '_subscrpt_next_date', true );
336 $trial_start_date = get_post_meta( get_the_ID(), '_subscrpt_trial_started', true );
337 $trial_end_date = get_post_meta( get_the_ID(), '_subscrpt_trial_ended', true );
338 $trial_mode = get_post_meta( get_the_ID(), '_subscrpt_trial_mode', true );
339 $order = wc_get_order( $order_id );
340 if ( ! $order ) {
341 return;
342 }
343 $order_item = $order->get_item( $order_item_id );
344
345 $product_name = $order_item->get_name();
346 $product_link = get_the_permalink( $order_item->get_product_id() );
347 $rows = array(
348 'product' => array(
349 'label' => __( 'Product', 'sdevs_subscrpt' ),
350 'value' => '<a href="' . esc_html( $product_link ) . '" target="_blank">' . esc_html( $product_name ) . '</a>',
351 ),
352 'cost' => array(
353 'label' => __( 'Cost', 'sdevs_subscrpt' ),
354 'value' => Helper::format_price_with_order_item( get_post_meta( get_the_ID(), '_subscrpt_price', true ), $order_item->get_id() ),
355 ),
356 'quantity' => array(
357 'label' => __( 'Qty', 'sdevs_subscrpt' ),
358 'value' => "x{$order_item->get_quantity()}",
359 ),
360 'start_date' => array(
361 'label' => __( 'Started date', 'sdevs_subscrpt' ),
362 'value' => ! empty( $start_date ) ? gmdate( 'F d, Y', $trial && $trial_start_date ? $trial_start_date : $start_date ) : '-',
363 ),
364 'next_date' => array(
365 'label' => __( 'Payment due date', 'sdevs_subscrpt' ),
366 'value' => ! empty( $next_date ) ? gmdate( 'F d, Y', $trial && $trial_end_date && 'on' === $trial_mode ? $trial_end_date : ( $next_date ?? '-' ) ) : '-',
367 ),
368 'status' => array(
369 'label' => __( 'Status', 'sdevs_subscrpt' ),
370 'value' => '<span class="subscrpt-' . get_post_status() . '">' . get_post_status_object( get_post_status() )->label . '</span>',
371 ),
372 'payment_method' => array(
373 'label' => __( 'Payment Method', 'sdevs_subscrpt' ),
374 'value' => empty( $order->get_payment_method_title() ) ? '-' : $order->get_payment_method_title(),
375 ),
376 'billing_address' => array(
377 'label' => __( 'Billing', 'sdevs_subscrpt' ),
378 'value' => $order->get_formatted_billing_address() ? $order->get_formatted_billing_address() : __( 'No billing address set.', 'sdevs_subscrpt' ),
379 ),
380 'shipping_address' => array(
381 'label' => __( 'Shipping', 'sdevs_subscrpt' ),
382 'value' => $order->get_formatted_shipping_address() ? $order->get_formatted_shipping_address() : __( 'No shipping address set.', 'sdevs_subscrpt' ),
383 ),
384 );
385 if ( $trial ) {
386 $rows = array_slice( $rows, 0, 3, true ) + array(
387 'trial' => array(
388 'label' => __( 'Trial', 'sdevs_subscrpt' ),
389 'value' => $trial,
390 ),
391 'trial_period' => array(
392 'label' => __( 'Trial Period', 'sdevs_subscrpt' ),
393 'value' => ( $trial_start_date && $trial_end_date ? ' [ ' . gmdate( 'F d, Y', $trial_start_date ) . ' - ' . gmdate( 'F d, Y', $trial_end_date ) . ' ] ' : __( 'Trial isn\'t activated yet! ', 'sdevs_subscrpt' ) ),
394 ),
395 ) + array_slice( $rows, 3, count( $rows ) - 1, true );
396 }
397
398 if ( class_exists( 'WC_Stripe' ) && 'stripe' === $order->get_payment_method() ) {
399 $is_auto_renew = get_post_meta( get_the_ID(), '_subscrpt_auto_renew', true );
400 $new_rows = array();
401 foreach ( $rows as $key => $value ) {
402 $new_rows[ $key ] = $value;
403 if ( 'payment_method' === $key ) {
404 $new_rows['stripe_auto_renewal'] = array(
405 'label' => __( 'Stripe Auto Renewal', 'sdevs_subscrpt' ),
406 'value' => '0' !== $is_auto_renew ? 'On' : 'Off',
407 );
408 }
409 }
410
411 $rows = $new_rows;
412 }
413
414 $rows = apply_filters( 'subscrpt_admin_info_rows', $rows, get_the_ID(), $order );
415
416 include 'views/subscription-info.php';
417 }
418
419 /**
420 * Include some styles.
421 *
422 * @return void
423 */
424 public function some_styles() {
425 global $post;
426 if ( 'subscrpt_order' === $post->post_type ) :
427 ?>
428 <style>
429 .submitbox {
430 display: flex;
431 justify-content: space-around;
432 }
433
434 .subscrpt_sub_box {
435 display: grid;
436 line-height: 2;
437 }
438 </style>
439 <?php
440 endif;
441 }
442
443 /**
444 * Disable changes popup.
445 *
446 * @return void
447 */
448 public function some_scripts() {
449 global $post;
450 if ( 'subscrpt_order' === $post->post_type ) :
451 ?>
452 <script>
453 jQuery(document).ready(function() {
454 jQuery(window).off('beforeunload', null);
455 });
456 </script>
457 <?php
458 endif;
459 }
460
461 public function save_subscrpt_order( $post_id ) {
462 if ( wp_is_post_revision( $post_id ) || ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) || ! isset( $_POST['subscrpt_order_action'] ) ) {
463 return;
464 }
465 remove_all_actions( 'save_post' );
466
467 $action = sanitize_text_field( wp_unslash( $_POST['subscrpt_order_action'] ) );
468 $old_status = get_post_status( $post_id );
469
470 wp_update_post(
471 array(
472 'ID' => $post_id,
473 'post_status' => $action,
474 )
475 );
476
477 if ( $old_status !== $action ) {
478 $old_status_object = get_post_status_object( $old_status );
479 $new_status_object = get_post_status_object( $action );
480 WC()->mailer();
481 do_action( 'subscrpt_status_changed_admin_email_notification', $post_id, $old_status_object->label, $new_status_object->label );
482 }
483
484 $order_id = get_post_meta( $post_id, '_subscrpt_order_id', true );
485 if ( 'active' === $action ) {
486 $order = wc_get_order( $order_id );
487 $order->update_status( 'completed' );
488 Action::status( $action, $post_id );
489 } else {
490 Action::status( $action, $post_id );
491 }
492 }
493
494 public function add_subscription_filter_select() {
495 // Implementation of add_subscription_filter_select method
496 }
497
498 public function add_overview_submenu() {
499 // Remove and re-add submenu to ensure Overview is first
500 remove_submenu_page('edit.php?post_type=subscrpt_order', 'edit.php?post_type=subscrpt_order');
501 add_submenu_page(
502 'edit.php?post_type=subscrpt_order',
503 __( 'Overview', 'wp_subscription' ),
504 __( 'Overview', 'wp_subscription' ),
505 'manage_options',
506 'subscription_overview',
507 array( $this, 'render_overview_page' ),
508 0
509 );
510 add_submenu_page(
511 'edit.php?post_type=subscrpt_order',
512 __( 'All Subscriptions', 'wp_subscription' ),
513 __( 'All Subscriptions', 'wp_subscription' ),
514 'manage_options',
515 'edit.php?post_type=subscrpt_order',
516 '',
517 1
518 );
519 if ( ! class_exists('Sdevs_Wc_Subscription_Pro') ) {
520 add_submenu_page(
521 'edit.php?post_type=subscrpt_order',
522 __( 'Go Pro', 'wp_subscription' ),
523 __( 'Go Pro', 'wp_subscription' ),
524 'manage_options',
525 'wp_subscription_go_pro',
526 array( $this, 'render_go_pro_page' ),
527 99
528 );
529 }
530 }
531
532 public function render_overview_page() {
533 ?>
534 <div class="wrap wpsubscription-overview" style="max-width:1100px;margin:40px auto 0 auto;">
535 <div class="wpsubscription-overview-card" style="background:#fff;border-radius:12px;box-shadow:0 2px 12px rgba(0,0,0,0.06);padding:40px 32px 32px 32px;">
536 <div class="wpsubscription-overview-top" style="display:grid;grid-template-columns:1fr 1fr;gap:40px;align-items:start;margin-bottom:40px;">
537 <div class="wpsubscription-overview-info" style="display:flex;flex-direction:column;gap:18px;">
538 <h1 style="margin-bottom:0.2em;"><?php esc_html_e( 'WP Subscription Overview', 'wp_subscription' ); ?></h1>
539 <p class="product-desc" style="font-size:1.15em;line-height:1.6;max-width:500px;">
540 <?php esc_html_e( 'WP Subscription is the most seamless and reliable WooCommerce subscription solution for store owners looking to grow recurring revenue. Easily manage recurring payments, automate renewals, and delight your customers with flexible plans.', 'wp_subscription' ); ?>
541 </p>
542 <div class="wpsubscription-links" style="display:flex;gap:12px;flex-wrap:wrap;">
543 <a href="https://converslabs.thrivedeskdocs.com/en" target="_blank" class="button button-secondary"><?php esc_html_e( 'Documentation', 'wp_subscription' ); ?></a>
544 <a href="https://wpsubscription.co/" target="_blank" class="button button-secondary"><?php esc_html_e( 'Website', 'wp_subscription' ); ?></a>
545 </div>
546 </div>
547 <div class="promo-video" style="text-align:center;">
548 <iframe width="420" height="236" src="https://www.youtube.com/embed/2e6o5p0M7L4" title="WP Subscription Promo" frameborder="0" allowfullscreen style="max-width:100%;border-radius:8px;"></iframe>
549 </div>
550 </div>
551
552 <div class="wpsubscription-what-section" style="margin-bottom:40px;">
553 <h2><?php esc_html_e( 'What does Subscriptions for WooCommerce do?', 'wp_subscription' ); ?></h2>
554 <p style="font-size:1.08em;max-width:900px;line-height:1.7;">
555 <?php esc_html_e( 'Subscriptions for WooCommerce enables you to create and manage recurring payment products and services with ease. Automate renewals, offer flexible billing schedules, and provide your customers with a seamless subscription experience. Whether you sell digital content, physical goods, or memberships, WP Subscription gives you the tools to grow your recurring revenue.', 'wp_subscription' ); ?>
556 </p>
557 </div>
558
559 <h2 style="margin-top:2em;"><?php esc_html_e( 'Highlights', 'wp_subscription' ); ?></h2>
560 <div class="wpsubscription-features-grid">
561 <div class="feature-box"><span class="dashicons dashicons-admin-generic"></span><h3>Easy Setup</h3><p>Get started in minutes with our intuitive onboarding wizard.</p></div>
562 <div class="feature-box"><span class="dashicons dashicons-money"></span><h3>Multiple Gateways</h3><p>Support for Stripe, PayPal, and Paddle out of the box.</p></div>
563 <div class="feature-box"><span class="dashicons dashicons-schedule"></span><h3>Flexible Plans</h3><p>Create and manage various subscription types and delivery schedules.</p></div>
564 <div class="feature-box"><span class="dashicons dashicons-chart-line"></span><h3>Comprehensive Dashboard</h3><p>Monitor and manage all subscriptions in one place.</p></div>
565 </div>
566 </div>
567 </div>
568 <style>
569 .wpsubscription-overview .promo-video { text-align:center; }
570 .wpsubscription-features-grid {
571 display: grid;
572 grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
573 gap: 24px;
574 margin-top: 32px;
575 }
576 .feature-box {
577 background: #fff;
578 border-radius: 10px;
579 box-shadow: 0 2px 8px rgba(0,0,0,0.06);
580 padding: 24px 18px 18px 18px;
581 text-align: center;
582 transition: transform 0.2s, box-shadow 0.2s;
583 will-change: transform;
584 }
585 .feature-box:hover {
586 transform: translateY(-6px) scale(1.03);
587 box-shadow: 0 6px 24px rgba(0,0,0,0.10);
588 }
589 .feature-box .dashicons {
590 font-size: 2.2em;
591 color: #7f54b3;
592 margin-bottom: 10px;
593 display: block;
594 }
595 .feature-box h3 {
596 margin: 12px 0 8px 0;
597 font-size: 1.15em;
598 }
599 .feature-box p {
600 color: #555;
601 font-size: 1em;
602 margin: 0;
603 }
604 </style>
605 <?php
606 }
607
608 public function render_go_pro_page() {
609 if ( class_exists('Sdevs_Wc_Subscription_Pro') ) {
610 echo '<div class="notice notice-info" style="margin:40px auto;max-width:700px;text-align:center;font-size:1.2em;">Pro is already active.</div>';
611 return;
612 }
613 ?>
614 <div class="wrap wpsubscription-go-pro" style="max-width:900px;margin:40px auto 0 auto;">
615 <div class="wpsubscription-go-pro-card" style="background:#fff;border-radius:12px;box-shadow:0 2px 12px rgba(0,0,0,0.06);padding:40px 32px 32px 32px;">
616 <h1 style="margin-bottom:0.5em;"><?php esc_html_e( 'Upgrade to WP Subscription Pro', 'wp_subscription' ); ?></h1>
617 <p style="font-size:1.12em;max-width:600px;line-height:1.6;">
618 <?php esc_html_e( 'Unlock the full power of subscriptions for WooCommerce. Get advanced features, priority support, and more ways to grow your recurring revenue.', 'wp_subscription' ); ?>
619 </p>
620 <table class="wpsubscription-compare-table" style="width:100%;margin:32px 0 40px 0;border-collapse:separate;border-spacing:0;box-shadow:0 1px 4px rgba(0,0,0,0.04);background:#fafbfc;border-radius:8px;overflow:hidden;">
621 <thead>
622 <tr style="background:#f8f9fa;">
623 <th style="padding:18px 12px 18px 24px;font-size:1.08em;text-align:left;border:none;"></th>
624 <th style="padding:18px 12px;font-size:1.08em;text-align:center;border:none;">Free</th>
625 <th style="padding:18px 12px;font-size:1.08em;text-align:center;border:none;color:#7f54b3;">Pro</th>
626 </tr>
627 </thead>
628 <tbody>
629 <tr>
630 <td style="padding:16px 12px 16px 24px;">Simple subscription products</td>
631 <td style="text-align:center;">✔️</td>
632 <td style="text-align:center;">✔️</td>
633 </tr>
634 <tr style="background:#f6f7f7;">
635 <td style="padding:16px 12px 16px 24px;">Automated recurring billing</td>
636 <td style="text-align:center;">✔️</td>
637 <td style="text-align:center;">✔️</td>
638 </tr>
639 <tr>
640 <td style="padding:16px 12px 16px 24px;">Multiple payment gateways</td>
641 <td style="text-align:center;">✔️</td>
642 <td style="text-align:center;">✔️</td>
643 </tr>
644 <tr style="background:#f6f7f7;">
645 <td style="padding:16px 12px 16px 24px;">Customer self-service portal</td>
646 <td style="text-align:center;">✔️</td>
647 <td style="text-align:center;">✔️</td>
648 </tr>
649 <tr>
650 <td style="padding:16px 12px 16px 24px;">Priority support</td>
651 <td style="text-align:center;"></td>
652 <td style="text-align:center;">✔️</td>
653 </tr>
654 <tr style="background:#f6f7f7;">
655 <td style="padding:16px 12px 16px 24px;">Advanced reporting & analytics</td>
656 <td style="text-align:center;"></td>
657 <td style="text-align:center;">✔️</td>
658 </tr>
659 <tr>
660 <td style="padding:16px 12px 16px 24px;">Variable product support</td>
661 <td style="text-align:center;"></td>
662 <td style="text-align:center;font-weight:600;color:#43a047;">✔️</td>
663 </tr>
664 </tbody>
665 </table>
666 <div style="text-align:center;margin-top:24px;">
667 <a href="https://wpsubscription.co/" target="_blank" class="button button-primary button-hero" style="font-size:1.2em;padding:16px 40px 16px 40px;background:#7f54b3;border:none;box-shadow:0 2px 8px rgba(127,84,179,0.10);">
668 <?php esc_html_e( 'Upgrade to Pro', 'wp_subscription' ); ?>
669 </a>
670 </div>
671 </div>
672 </div>
673 <?php
674 }
675 }
676