| @@ -25,21 +25,30 @@ | ||
| 25 | 25 | add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_scripts' ) ); |
| 26 | 26 | add_filter( 'post_row_actions', array( $this, 'post_row_actions' ) ); |
| 27 | 27 | add_filter( 'manage_subscrpt_order_posts_columns', array( $this, 'add_custom_columns' ) ); |
| 28 | 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' ) ); | |
| 29 | + add_action( 'load-post.php', array( $this, 'redirect_legacy_edit_screen' ) ); | |
| 35 | 30 | add_filter( 'woocommerce_order_item_get_formatted_meta_data', array( $this, 'remove_order_meta' ), 10, 1 ); |
| 36 | 31 | add_filter( 'bulk_actions-edit-subscrpt_order', array( $this, 'remove_bulk_actions' ) ); |
| 37 | 32 | add_action( 'restrict_manage_posts', array( $this, 'add_subscription_filter_select' ) ); |
| 38 | 33 | add_action( 'admin_menu', array( $this, 'add_overview_submenu' ), 40 ); |
| 39 | - add_action( 'edit_form_after_title', array( $this, 'display_subscription_details_section' ) ); | |
| 34 | + } | |
| 40 | 35 | |
| 41 | - add_action( 'admin_head-post.php', [ $this, 'add_back_to_list_button' ] ); | |
| 36 | + /** | |
| 37 | + * Redirect the legacy CPT edit screen to the standalone details page. | |
| 38 | + * | |
| 39 | + * The subscription details UI now lives at | |
| 40 | + * admin.php?page=wp-subscription-details. Anyone landing on the old | |
| 41 | + * post.php edit screen for a subscrpt_order is sent there. | |
| 42 | + * | |
| 43 | + * @return void | |
| 44 | + */ | |
| 45 | + public function redirect_legacy_edit_screen() { | |
| 46 | + $post_id = isset( $_GET['post'] ) ? absint( wp_unslash( $_GET['post'] ) ) : 0; // phpcs:ignore WordPress.Security.NonceVerification.Recommended | |
| 47 | + if ( $post_id && 'subscrpt_order' === get_post_type( $post_id ) ) { | |
| 48 | + wp_safe_redirect( admin_url( 'admin.php?page=wp-subscription-details&id=' . $post_id ) ); | |
| 49 | + exit; | |
| 50 | + } | |
| 42 | 51 | } |
| 43 | 52 | |
| 44 | 53 | /** |
| 45 | 54 | * Remove 'Edit` and 'Trash' from bulk actions. |
| @@ -154,9 +163,9 @@ | ||
| 154 | 163 | } elseif ( 'subscrpt_status' === $column ) { |
| 155 | 164 | $status_obj = get_post_status_object( get_post_status( $post_id ) ); |
| 156 | 165 | ?> |
| 157 | 166 | <span |
| 158 | - class="subscrpt-<?php echo esc_html( $status_obj->name ); ?>"><?php echo esc_html( $status_obj->label ); ?></span> | |
| 167 | + class="subscrpt-legacy-status subscrpt-legacy-status--<?php echo esc_html( $status_obj->name ); ?>"><?php echo esc_html( $status_obj->label ); ?></span> | |
| 159 | 168 | <?php |
| 160 | 169 | } |
| 161 | 170 | } else { |
| 162 | 171 | esc_html_e( 'Order not found !!', 'subscription' ); |
| @@ -163,183 +172,31 @@ | ||
| 163 | 172 | } |
| 164 | 173 | } |
| 165 | 174 | |
| 166 | 175 | /** |
| 167 | - * Create meta boxes for admin subscriptions. | |
| 168 | - */ | |
| 169 | - public function create_meta_boxes() { | |
| 170 | - remove_meta_box( 'submitdiv', 'subscrpt_order', 'side' ); | |
| 171 | - add_meta_box( | |
| 172 | - 'subscrpt_order_save_post', | |
| 173 | - __( 'Subscription Action', 'subscription' ), | |
| 174 | - array( $this, 'subscrpt_order_save_post' ), | |
| 175 | - 'subscrpt_order', | |
| 176 | - 'side', | |
| 177 | - 'default' | |
| 178 | - ); | |
| 179 | - | |
| 180 | - add_meta_box( | |
| 181 | - 'subscrpt_customer_info', | |
| 182 | - __( 'Customer Details', 'subscription' ), | |
| 183 | - array( $this, 'customer_info' ), | |
| 184 | - 'subscrpt_order', | |
| 185 | - 'side', | |
| 186 | - 'default' | |
| 187 | - ); | |
| 188 | - | |
| 189 | - // Removed the redundant subscription info meta box as it's now shown prominently above | |
| 190 | - | |
| 191 | - add_meta_box( | |
| 192 | - 'subscrpt_order_history', | |
| 193 | - __( 'Related Orders', 'subscription' ), | |
| 194 | - array( $this, 'order_histories' ), | |
| 195 | - 'subscrpt_order', | |
| 196 | - 'normal', | |
| 197 | - 'default' | |
| 198 | - ); | |
| 199 | - | |
| 200 | - add_meta_box( | |
| 201 | - 'subscrpt_order_activities', | |
| 202 | - __( 'Subscription Activities', 'subscription' ), | |
| 203 | - array( $this, 'order_activities' ), | |
| 204 | - 'subscrpt_order', | |
| 205 | - 'normal', | |
| 206 | - 'default' | |
| 207 | - ); | |
| 208 | - } | |
| 209 | - | |
| 210 | - /** | |
| 211 | - * Display Order Histories. | |
| 176 | + * Build the subscription info rows. | |
| 212 | 177 | * |
| 213 | - * @param \WP_Post $post Post Object. | |
| 178 | + * Assembles the label/value rows describing a subscription (product, cost, | |
| 179 | + * dates, status, payment method, addresses, trial, etc.) and applies the | |
| 180 | + * `subscrpt_admin_info_rows` filter so extensions (e.g. the Pro plugin) can | |
| 181 | + * add or reorder rows. Returns null when the related order is missing. | |
| 214 | 182 | * |
| 215 | - * @return void | |
| 216 | - */ | |
| 217 | - public function order_histories( $post ) { | |
| 218 | - $subscription_id = $post->ID; | |
| 219 | - global $wpdb; | |
| 220 | - $table_name = $wpdb->prefix . 'subscrpt_order_relation'; | |
| 221 | - | |
| 222 | - // @phpcs:ignore | |
| 223 | - $order_histories = $wpdb->get_results( | |
| 224 | - $wpdb->prepare( | |
| 225 | - 'SELECT * FROM %i WHERE subscription_id=%d ORDER BY id DESC', | |
| 226 | - array( | |
| 227 | - $table_name, | |
| 228 | - $subscription_id, | |
| 229 | - ) | |
| 230 | - ) | |
| 231 | - ); | |
| 232 | - | |
| 233 | - include 'views/order-history.php'; | |
| 234 | - } | |
| 235 | - | |
| 236 | - /** | |
| 237 | - * Display Order Activities | |
| 183 | + * @param int $subscription_id Subscription (subscrpt_order) post ID. | |
| 238 | 184 | * |
| 239 | - * @param \WP_Post $post Post Object. | |
| 240 | - * | |
| 241 | - * @return void | |
| 185 | + * @return array<string,array{label:string,value:string}>|null | |
| 242 | 186 | */ |
| 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 WPSubscription 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', 'subscription' ), | |
| 275 | - 'value' => 'active', | |
| 276 | - ), | |
| 277 | - 'pending' => array( | |
| 278 | - 'label' => __( 'Pending Subscription', 'subscription' ), | |
| 279 | - 'value' => 'pending', | |
| 280 | - ), | |
| 281 | - 'expire' => array( | |
| 282 | - 'label' => __( 'Expire Subscription', 'subscription' ), | |
| 283 | - 'value' => 'expired', | |
| 284 | - ), | |
| 285 | - 'pe_cancelled' => array( | |
| 286 | - 'label' => __( 'Pending Cancel Subscription', 'subscription' ), | |
| 287 | - 'value' => 'pe_cancelled', | |
| 288 | - ), | |
| 289 | - 'cancelled' => array( | |
| 290 | - 'label' => __( 'Cancel Subscription', 'subscription' ), | |
| 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 ); | |
| 187 | + public static function get_info_rows( $subscription_id ) { | |
| 188 | + $order_id = get_post_meta( $subscription_id, '_subscrpt_order_id', true ); | |
| 189 | + $order_item_id = get_post_meta( $subscription_id, '_subscrpt_order_item_id', true ); | |
| 190 | + $trial = get_post_meta( $subscription_id, '_subscrpt_trial', true ); | |
| 191 | + $start_date = get_post_meta( $subscription_id, '_subscrpt_start_date', true ); | |
| 192 | + $next_date = get_post_meta( $subscription_id, '_subscrpt_next_date', true ); | |
| 193 | + $trial_start_date = get_post_meta( $subscription_id, '_subscrpt_trial_started', true ); | |
| 194 | + $trial_end_date = get_post_meta( $subscription_id, '_subscrpt_trial_ended', true ); | |
| 195 | + $trial_mode = get_post_meta( $subscription_id, '_subscrpt_trial_mode', true ); | |
| 339 | 196 | $order = wc_get_order( $order_id ); |
| 340 | 197 | if ( ! $order ) { |
| 341 | - return; | |
| 198 | + return null; | |
| 342 | 199 | } |
| 343 | 200 | $order_item = $order->get_item( $order_item_id ); |
| 344 | 201 | |
| 345 | 202 | $product_name = $order_item->get_name(); |
| @@ -345,11 +202,11 @@ | ||
| 345 | 202 | $product_name = $order_item->get_name(); |
| 346 | 203 | $product_link = get_the_permalink( $order_item->get_product_id() ); |
| 347 | 204 | |
| 348 | 205 | // Get payment information |
| 349 | - $product_id = $order_item->get_product_id(); // get_post_meta( get_the_ID(), '_subscrpt_product_id', true ); | |
| 350 | - $max_payments = subscrpt_get_max_payments( get_the_ID() ) ?: 0; | |
| 351 | - $payments_made = subscrpt_count_payments_made( get_the_ID() ); | |
| 206 | + $product_id = $order_item->get_product_id(); | |
| 207 | + $max_payments = subscrpt_get_max_payments( $subscription_id ) ? subscrpt_get_max_payments( $subscription_id ) : 0; | |
| 208 | + $payments_made = subscrpt_count_payments_made( $subscription_id ); | |
| 352 | 209 | |
| 353 | 210 | $rows = array( |
| 354 | 211 | 'product' => array( |
| 355 | 212 | 'label' => __( 'Product', 'subscription' ), |
| @@ -356,9 +213,9 @@ | ||
| 356 | 213 | 'value' => '<a href="' . esc_html( $product_link ) . '" target="_blank">' . esc_html( $product_name ) . '</a>', |
| 357 | 214 | ), |
| 358 | 215 | 'cost' => array( |
| 359 | 216 | 'label' => __( 'Cost', 'subscription' ), |
| 360 | - 'value' => Helper::format_price_with_order_item( get_post_meta( get_the_ID(), '_subscrpt_price', true ), $order_item->get_id() ), | |
| 217 | + 'value' => Helper::get_subscription_recurring_price_html( $subscription_id, $order_item ), | |
| 361 | 218 | ), |
| 362 | 219 | 'quantity' => array( |
| 363 | 220 | 'label' => __( 'Qty', 'subscription' ), |
| 364 | 221 | 'value' => "x{$order_item->get_quantity()}", |
| @@ -383,9 +240,9 @@ | ||
| 383 | 240 | 'value' => ! empty( $next_date ) ? wp_date( 'F d, Y', $trial && $trial_end_date && 'on' === $trial_mode ? $trial_end_date : ( $next_date ?? '-' ) ) : '-', |
| 384 | 241 | ), |
| 385 | 242 | 'status' => array( |
| 386 | 243 | 'label' => __( 'Status', 'subscription' ), |
| 387 | - 'value' => '<span class="subscrpt-' . get_post_status() . '">' . get_post_status_object( get_post_status() )->label . '</span>', | |
| 244 | + 'value' => '<span class="subscrpt-legacy-status subscrpt-legacy-status--' . get_post_status( $subscription_id ) . '">' . get_post_status_object( get_post_status( $subscription_id ) )->label . '</span>', | |
| 388 | 245 | ), |
| 389 | 246 | 'payment_method' => array( |
| 390 | 247 | 'label' => __( 'Payment Method', 'subscription' ), |
| 391 | 248 | 'value' => empty( $order->get_payment_method_title() ) ? '-' : $order->get_payment_method_title(), |
| @@ -412,9 +269,9 @@ | ||
| 412 | 269 | ) + array_slice( $rows, 3, count( $rows ) - 1, true ); |
| 413 | 270 | } |
| 414 | 271 | |
| 415 | 272 | if ( class_exists( 'WC_Stripe' ) && 'stripe' === $order->get_payment_method() ) { |
| 416 | - $is_auto_renew = get_post_meta( get_the_ID(), '_subscrpt_auto_renew', true ); | |
| 273 | + $is_auto_renew = get_post_meta( $subscription_id, '_subscrpt_auto_renew', true ); | |
| 417 | 274 | $new_rows = array(); |
| 418 | 275 | foreach ( $rows as $key => $value ) { |
| 419 | 276 | $new_rows[ $key ] = $value; |
| 420 | 277 | if ( 'payment_method' === $key ) { |
| @@ -427,374 +284,27 @@ | ||
| 427 | 284 | |
| 428 | 285 | $rows = $new_rows; |
| 429 | 286 | } |
| 430 | 287 | |
| 431 | - $rows = apply_filters( 'subscrpt_admin_info_rows', $rows, get_the_ID(), $order ); | |
| 288 | + $rows = apply_filters( 'subscrpt_admin_info_rows', $rows, $subscription_id, $order ); | |
| 432 | 289 | |
| 433 | - include 'views/subscription-info.php'; | |
| 290 | + return $rows; | |
| 434 | 291 | } |
| 435 | 292 | |
| 436 | 293 | /** |
| 437 | - * Display a prominent subscription details section. | |
| 294 | + * Apply a status change to a subscription. | |
| 438 | 295 | * |
| 439 | - * @param \WP_Post $post The post object. | |
| 296 | + * Updates the subscription post status, fires the admin status-change email | |
| 297 | + * notification, runs the subscription status action, and completes the | |
| 298 | + * related order when the subscription becomes active. Called from the | |
| 299 | + * standalone subscription details page. | |
| 440 | 300 | * |
| 441 | - * @return void | |
| 442 | - */ | |
| 443 | - public function display_subscription_details_section( $post ) { | |
| 444 | - // Only display for subscription post type | |
| 445 | - if ( 'subscrpt_order' !== $post->post_type ) { | |
| 446 | - return; | |
| 447 | - } | |
| 448 | - | |
| 449 | - $subscription_id = $post->ID; | |
| 450 | - $subscription_data = Helper::get_subscription_data( $subscription_id ); | |
| 451 | - | |
| 452 | - $order_id = $subscription_data['order']['order_id'] ?? 0; | |
| 453 | - $order = $order_id ? wc_get_order( $order_id ) : null; | |
| 454 | - | |
| 455 | - $order_item_id = $subscription_data['order']['order_item_id'] ?? 0; | |
| 456 | - $order_item = $order ? $order->get_item( $order_item_id ) : null; | |
| 457 | - | |
| 458 | - if ( ! $order || ! $order_item ) { | |
| 459 | - return; | |
| 460 | - } | |
| 461 | - | |
| 462 | - $product_id = $subscription_data['product']['product_id'] ?? 0; | |
| 463 | - $max_payments = ! empty( subscrpt_get_max_payments( $subscription_id ) ) ? subscrpt_get_max_payments( $subscription_id ) : 0; | |
| 464 | - $payments_made = subscrpt_count_payments_made( $subscription_id ); | |
| 465 | - | |
| 466 | - // Get subscription details | |
| 467 | - $product = wc_get_product( $product_id ); | |
| 468 | - $subscrpt_type = $subscription_data['schedule']['timing_option'] ?? ''; | |
| 469 | - $subscrpt_time = $subscription_data['schedule']['timing_per'] ?? ''; | |
| 470 | - | |
| 471 | - $trial_type = $subscription_data['trial']['timing_option'] ?? 'days'; | |
| 472 | - $trial_time = $subscription_data['trial']['timing_per'] ?? 0; | |
| 473 | - | |
| 474 | - $signup_fee = $subscription_data['signup_fee'] ?? ''; | |
| 475 | - | |
| 476 | - $quantity = (int) $order_item->get_quantity(); | |
| 477 | - $cost = (float) ( $subscription_data['price'] ?? 0 ) * max( 1, $quantity ); | |
| 478 | - $cost = empty( $cost ) ? (float) $order_item->get_total() : $cost; | |
| 479 | - | |
| 480 | - $price_excl_tax = (float) $order_item->get_total(); | |
| 481 | - $tax_amount = (float) $order_item->get_total_tax(); | |
| 482 | - if ( $tax_amount > 0 ) { | |
| 483 | - $cost = $price_excl_tax + $tax_amount; | |
| 484 | - $cost = number_format( (float) $cost, 2, '.', '' ); | |
| 485 | - } | |
| 486 | - | |
| 487 | - $subscrpt_status = $subscription_data['status'] ?? ''; | |
| 488 | - $verbose_status = Helper::get_verbose_status( $subscrpt_status ); | |
| 489 | - | |
| 490 | - $started_date = $subscription_data['start_date'] ?? ''; | |
| 491 | - $started_date = ! empty( $started_date ) ? wp_date( 'F j, Y - g:i A', strtotime( $started_date ) ) : '-'; | |
| 492 | - | |
| 493 | - $next_payment_date = $subscription_data['next_date'] ?? ''; | |
| 494 | - $next_payment_date = ! empty( $next_payment_date ) ? wp_date( 'F j, Y - g:i A', strtotime( $next_payment_date ) ) : '-'; | |
| 495 | - | |
| 496 | - $is_grace_period = isset( $subscription_data['grace_period'] ); | |
| 497 | - $grace_remaining = $subscription_data['grace_period']['remaining_days'] ?? 0; | |
| 498 | - $grace_end_date = $subscription_data['grace_period']['end_date'] ?? ''; | |
| 499 | - $grace_end_date = ! empty( $grace_end_date ) ? wp_date( 'F j, Y - g:i A', strtotime( $grace_end_date ) ) : ''; | |
| 500 | - | |
| 501 | - ?> | |
| 502 | - <div class="wp-subscription-details-section"> | |
| 503 | - <h2 style="margin: 0 0 20px 0; padding: 0; border-bottom: 1px solid #ddd; padding-bottom: 12px;"> | |
| 504 | - <?php | |
| 505 | - $text = sprintf( | |
| 506 | - // translators: Subscription ID. | |
| 507 | - __( 'Subscription #%d details', 'subscription' ), | |
| 508 | - $post->ID | |
| 509 | - ); | |
| 510 | - echo esc_html( $text ); | |
| 511 | - ?> | |
| 512 | - </h2> | |
| 513 | - | |
| 514 | - <div class="subscription-details-grid"> | |
| 515 | - <!-- Primary Information --> | |
| 516 | - <div class="details-group primary"> | |
| 517 | - <h3><?php esc_html_e( 'General', 'subscription' ); ?></h3> | |
| 518 | - <table> | |
| 519 | - <tr> | |
| 520 | - <th><?php esc_html_e( 'Status', 'subscription' ); ?></th> | |
| 521 | - <td> | |
| 522 | - <?php if ( $is_grace_period && $grace_remaining > 0 ) : ?> | |
| 523 | - <span class="subscrpt-active grace-active"> | |
| 524 | - Active | |
| 525 | - | |
| 526 | - <?php | |
| 527 | - $grace_remaining_text = sprintf( | |
| 528 | - // translators: Number of days remaining in grace period. | |
| 529 | - __( '%d days remaining!', 'subscription' ), | |
| 530 | - $grace_remaining | |
| 531 | - ); | |
| 532 | - ?> | |
| 533 | - <span class="grace-icon" data-tooltip="<?php echo esc_attr( $grace_remaining_text ); ?>"> | |
| 534 | - <span class="dashicons dashicons-warning"></span> | |
| 535 | - </span> | |
| 536 | - </span> | |
| 537 | - <?php else : ?> | |
| 538 | - <span class="subscrpt-<?php echo esc_attr( strtolower( $subscrpt_status ) ); ?>"> | |
| 539 | - <?php echo esc_html( $verbose_status ); ?> | |
| 540 | - </span> | |
| 541 | - <?php endif; ?> | |
| 542 | - </td> | |
| 543 | - </tr> | |
| 544 | - <tr> | |
| 545 | - <th><?php esc_html_e( 'Product', 'subscription' ); ?></th> | |
| 546 | - <td><a href="<?php echo esc_url( get_the_permalink( $order_item->get_product_id() ) ); ?>" target="_blank"><?php echo esc_html( $order_item->get_name() ); ?></a></td> | |
| 547 | - </tr> | |
| 548 | - </table> | |
| 549 | - </div> | |
| 550 | - | |
| 551 | - <!-- Subscription Terms --> | |
| 552 | - <div class="details-group"> | |
| 553 | - <h3><?php esc_html_e( 'Subscription Terms', 'subscription' ); ?></h3> | |
| 554 | - <table> | |
| 555 | - <tr> | |
| 556 | - <th><?php esc_html_e( 'Billing', 'subscription' ); ?></th> | |
| 557 | - <td> | |
| 558 | - <?php echo wp_kses_post( wc_price( $cost ) ); ?> / | |
| 559 | - <?php | |
| 560 | - echo esc_html( $subscrpt_time > 1 ? $subscrpt_time . '-' : '' ); | |
| 561 | - ?> | |
| 562 | - <?php | |
| 563 | - echo esc_html( $subscrpt_type ); | |
| 564 | - ?> | |
| 565 | - </td> | |
| 566 | - </tr> | |
| 567 | - | |
| 568 | - <?php if ( $signup_fee ) : ?> | |
| 569 | - <tr> | |
| 570 | - <th><?php esc_html_e( 'Signup Fee', 'subscription' ); ?></th> | |
| 571 | - <td><?php echo wp_kses_post( wc_price( $signup_fee ) ); ?></td> | |
| 572 | - </tr> | |
| 573 | - <?php endif; ?> | |
| 574 | - | |
| 575 | - <?php if ( $trial_time ) : ?> | |
| 576 | - <tr> | |
| 577 | - <th><?php esc_html_e( 'Free Trial', 'subscription' ); ?></th> | |
| 578 | - <td><?php echo esc_html( $trial_time . ' ' . $trial_type ); ?></td> | |
| 579 | - </tr> | |
| 580 | - <?php endif; ?> | |
| 581 | - | |
| 582 | - <?php if ( ! empty( $max_payments ) && $max_payments > 0 ) : ?> | |
| 583 | - <tr> | |
| 584 | - <th><?php esc_html_e( 'Total Payments', 'subscription' ); ?></th> | |
| 585 | - <td><strong><?php echo esc_html( $payments_made . ' / ' . $max_payments ); ?></strong></td> | |
| 586 | - </tr> | |
| 587 | - <?php endif; ?> | |
| 588 | - </table> | |
| 589 | - </div> | |
| 590 | - | |
| 591 | - <!-- Schedule Dates --> | |
| 592 | - <div class="details-group"> | |
| 593 | - <h3><?php esc_html_e( 'Schedule Dates', 'subscription' ); ?></h3> | |
| 594 | - <table> | |
| 595 | - <tr> | |
| 596 | - <th><?php esc_html_e( 'Started', 'subscription' ); ?></th> | |
| 597 | - <td><?php echo esc_html( $started_date ); ?></td> | |
| 598 | - </tr> | |
| 599 | - <tr> | |
| 600 | - <th><?php esc_html_e( 'Next Payment', 'subscription' ); ?></th> | |
| 601 | - <td><?php echo esc_html( $next_payment_date ); ?></td> | |
| 602 | - </tr> | |
| 603 | - </table> | |
| 604 | - </div> | |
| 605 | - | |
| 606 | - <!-- Grace Period Info --> | |
| 607 | - <?php if ( $is_grace_period ) : ?> | |
| 608 | - <div class="details-group"> | |
| 609 | - <h3><?php esc_html_e( 'Grace Period', 'subscription' ); ?></h3> | |
| 610 | - <table> | |
| 611 | - <tr> | |
| 612 | - <th><?php esc_html_e( 'Remaining', 'subscription' ); ?></th> | |
| 613 | - <td><?php echo esc_html( $grace_remaining . ' days' ); ?></td> | |
| 614 | - </tr> | |
| 615 | - <tr> | |
| 616 | - <th><?php esc_html_e( 'End Date', 'subscription' ); ?></th> | |
| 617 | - <td><?php echo esc_html( $grace_end_date ); ?></td> | |
| 618 | - </tr> | |
| 619 | - </table> | |
| 620 | - </div> | |
| 621 | - <?php endif; ?> | |
| 622 | - </div> | |
| 623 | - </div> | |
| 624 | - <?php | |
| 625 | - } | |
| 626 | - | |
| 627 | - /** | |
| 628 | - * Include some styles. | |
| 301 | + * @param int $post_id Subscription (subscrpt_order) post ID. | |
| 302 | + * @param string $action Target status slug. | |
| 629 | 303 | * |
| 630 | 304 | * @return void |
| 631 | 305 | */ |
| 632 | - public function some_styles() { | |
| 633 | - global $post; | |
| 634 | - if ( 'subscrpt_order' === $post->post_type ) : | |
| 635 | - ?> | |
| 636 | - <style> | |
| 637 | - .submitbox { | |
| 638 | - display: flex; | |
| 639 | - justify-content: space-around; | |
| 640 | - } | |
| 641 | - | |
| 642 | - .subscrpt_sub_box { | |
| 643 | - display: grid; | |
| 644 | - line-height: 2; | |
| 645 | - } | |
| 646 | - | |
| 647 | - /* Hide WordPress title area margin */ | |
| 648 | - #poststuff #post-body.columns-2 { | |
| 649 | - margin-right: 300px; | |
| 650 | - } | |
| 651 | - | |
| 652 | - /* Clean, minimal details section */ | |
| 653 | - .wp-subscription-details-section { | |
| 654 | - margin: 20px 0 30px 0; | |
| 655 | - padding: 20px; | |
| 656 | - border: 1px solid #ddd; | |
| 657 | - background: #fff; | |
| 658 | - } | |
| 659 | - | |
| 660 | - /* Grid layout for organized sections */ | |
| 661 | - .subscription-details-grid { | |
| 662 | - display: grid; | |
| 663 | - grid-template-columns: 1fr 1fr; | |
| 664 | - gap: 30px; | |
| 665 | - margin-top: 20px; | |
| 666 | - } | |
| 667 | - | |
| 668 | - @media (max-width: 782px) { | |
| 669 | - .subscription-details-grid { | |
| 670 | - grid-template-columns: 1fr; | |
| 671 | - } | |
| 672 | - } | |
| 673 | - | |
| 674 | - /* Details group styling */ | |
| 675 | - .details-group h3 { | |
| 676 | - margin: 0 0 12px 0; | |
| 677 | - padding: 0 0 8px 0; | |
| 678 | - border-bottom: 1px solid #eee; | |
| 679 | - font-size: 14px; | |
| 680 | - font-weight: 600; | |
| 681 | - color: #555; | |
| 682 | - text-transform: uppercase; | |
| 683 | - letter-spacing: 0.5px; | |
| 684 | - } | |
| 685 | - | |
| 686 | - .details-group.primary h3 { | |
| 687 | - color: #333; | |
| 688 | - } | |
| 689 | - | |
| 690 | - .details-group table { | |
| 691 | - width: 100%; | |
| 692 | - border-collapse: collapse; | |
| 693 | - } | |
| 694 | - | |
| 695 | - .details-group table th { | |
| 696 | - text-align: left; | |
| 697 | - padding: 8px 12px 8px 0; | |
| 698 | - font-weight: 500; | |
| 699 | - color: #666; | |
| 700 | - width: 40%; | |
| 701 | - vertical-align: top; | |
| 702 | - font-size: 13px; | |
| 703 | - } | |
| 704 | - | |
| 705 | - .details-group table td { | |
| 706 | - padding: 8px 0; | |
| 707 | - color: #333; | |
| 708 | - font-size: 13px; | |
| 709 | - line-height: 1.4; | |
| 710 | - } | |
| 711 | - | |
| 712 | - .details-group table tr { | |
| 713 | - border-bottom: 1px solid #f5f5f5; | |
| 714 | - } | |
| 715 | - | |
| 716 | - .details-group table tr:last-child { | |
| 717 | - border-bottom: none; | |
| 718 | - } | |
| 719 | - | |
| 720 | - /* Simple status badge */ | |
| 721 | - .status-badge { | |
| 722 | - display: inline-block; | |
| 723 | - padding: 2px 8px; | |
| 724 | - border-radius: 3px; | |
| 725 | - font-size: 12px; | |
| 726 | - font-weight: 500; | |
| 727 | - text-transform: capitalize; | |
| 728 | - background: #f5f5f5; | |
| 729 | - color: #666; | |
| 730 | - border: 1px solid #ddd; | |
| 731 | - } | |
| 732 | - | |
| 733 | - /* Clean links */ | |
| 734 | - .details-group a { | |
| 735 | - color: #0073aa; | |
| 736 | - text-decoration: none; | |
| 737 | - } | |
| 738 | - | |
| 739 | - .details-group a:hover { | |
| 740 | - text-decoration: underline; | |
| 741 | - } | |
| 742 | - | |
| 743 | - /* Meta box styling improvements */ | |
| 744 | - .postbox { | |
| 745 | - border: 1px solid #ddd; | |
| 746 | - } | |
| 747 | - | |
| 748 | - .postbox .hndle { | |
| 749 | - border-bottom: 1px solid #eee; | |
| 750 | - background: #fafafa; | |
| 751 | - } | |
| 752 | - | |
| 753 | - #subscrpt_order_history .inside table, | |
| 754 | - #subscrpt_order_activities .inside table { | |
| 755 | - border: none; | |
| 756 | - } | |
| 757 | - </style> | |
| 758 | - <?php | |
| 759 | - endif; | |
| 760 | - } | |
| 761 | - | |
| 762 | - /** | |
| 763 | - * Disable changes popup. | |
| 764 | - * | |
| 765 | - * @return void | |
| 766 | - */ | |
| 767 | - public function some_scripts() { | |
| 768 | - global $post; | |
| 769 | - if ( 'subscrpt_order' === $post->post_type ) : | |
| 770 | - ?> | |
| 771 | - <script> | |
| 772 | - jQuery(document).ready(function() { | |
| 773 | - jQuery(window).off('beforeunload', null); | |
| 774 | - }); | |
| 775 | - </script> | |
| 776 | - <?php | |
| 777 | - endif; | |
| 778 | - } | |
| 779 | - | |
| 780 | - public function save_subscrpt_order( $post_id ) { | |
| 781 | - if ( wp_is_post_revision( $post_id ) || ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) || ! isset( $_POST['subscrpt_order_action'] ) ) { | |
| 782 | - return; | |
| 783 | - } | |
| 784 | - | |
| 785 | - // Verify nonce for security. | |
| 786 | - if ( ! isset( $_POST['subscrpt_order_action_nonce_field'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['subscrpt_order_action_nonce_field'] ) ), 'subscrpt_order_action_nonce' ) ) { | |
| 787 | - return; | |
| 788 | - } | |
| 789 | - | |
| 790 | - // Check permissions. | |
| 791 | - if ( ! current_user_can( 'edit_post', $post_id ) ) { | |
| 792 | - return; | |
| 793 | - } | |
| 794 | - remove_all_actions( 'save_post' ); | |
| 795 | - | |
| 796 | - $action = sanitize_text_field( wp_unslash( $_POST['subscrpt_order_action'] ) ); | |
| 306 | + public static function process_status_change( $post_id, $action ) { | |
| 797 | 307 | $old_status = get_post_status( $post_id ); |
| 798 | 308 | |
| 799 | 309 | wp_update_post( |
| 800 | 310 | array( |
| @@ -812,9 +322,11 @@ | ||
| 812 | 322 | |
| 813 | 323 | $order_id = get_post_meta( $post_id, '_subscrpt_order_id', true ); |
| 814 | 324 | if ( 'active' === $action ) { |
| 815 | 325 | $order = wc_get_order( $order_id ); |
| 816 | - $order->update_status( 'completed' ); | |
| 326 | + if ( $order ) { | |
| 327 | + $order->update_status( 'completed' ); | |
| 328 | + } | |
| 817 | 329 | Action::status( $action, $post_id ); |
| 818 | 330 | } else { |
| 819 | 331 | Action::status( $action, $post_id ); |
| 820 | 332 | } |
| @@ -868,10 +380,10 @@ | ||
| 868 | 380 | <p class="product-desc" style="font-size:1.15em;line-height:1.6;max-width:500px;"> |
| 869 | 381 | <?php esc_html_e( 'WPSubscription 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.', 'subscription' ); ?> |
| 870 | 382 | </p> |
| 871 | 383 | <div class="wpsubscription-links" style="display:flex;gap:12px;flex-wrap:wrap;"> |
| 872 | - <a href="https://docs.converslabs.com/en" target="_blank" class="button button-secondary"><?php esc_html_e( 'Documentation', 'subscription' ); ?></a> | |
| 873 | - <a href="https://wpsubscription.co/" target="_blank" class="button button-secondary"><?php esc_html_e( 'Website', 'subscription' ); ?></a> | |
| 384 | + <a href="https://docs.wpsubscription.co/en?utm_source=plugin&utm_medium=admin&utm_campaign=docs" target="_blank" class="button button-secondary"><?php esc_html_e( 'Documentation', 'subscription' ); ?></a> | |
| 385 | + <a href="https://wpsubscription.co/?utm_source=plugin&utm_medium=admin&utm_campaign=upgrade_pro" target="_blank" class="button button-secondary"><?php esc_html_e( 'Website', 'subscription' ); ?></a> | |
| 874 | 386 | </div> |
| 875 | 387 | </div> |
| 876 | 388 | <div class="promo-video" style="text-align:center;"> |
| 877 | 389 | <iframe width="420" height="236" src="https://www.youtube.com/embed/2e6o5p0M7L4" title="WPSubscription Promo" frameborder="0" allowfullscreen style="max-width:100%;border-radius:8px;"></iframe> |
| @@ -992,43 +504,13 @@ | ||
| 992 | 504 | </tr> |
| 993 | 505 | </tbody> |
| 994 | 506 | </table> |
| 995 | 507 | <div style="text-align:center;margin-top:24px;"> |
| 996 | - <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);"> | |
| 508 | + <a href="https://wpsubscription.co/?utm_source=plugin&utm_medium=admin&utm_campaign=upgrade_pro" 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);"> | |
| 997 | 509 | <?php esc_html_e( 'Upgrade to Pro', 'subscription' ); ?> |
| 998 | 510 | </a> |
| 999 | 511 | </div> |
| 1000 | 512 | </div> |
| 1001 | 513 | </div> |
| 1002 | - <?php | |
| 1003 | - } | |
| 1004 | - | |
| 1005 | - /** | |
| 1006 | - * Add "Back to list" button next to the post title. | |
| 1007 | - */ | |
| 1008 | - public function add_back_to_list_button() { | |
| 1009 | - global $post; | |
| 1010 | - | |
| 1011 | - // Only apply on edit subscription screen | |
| 1012 | - if ( ! isset( $post ) || $post->post_type !== 'subscrpt_order' ) { | |
| 1013 | - return; | |
| 1014 | - } | |
| 1015 | - | |
| 1016 | - $list_url = admin_url( 'admin.php?page=wp-subscription' ); | |
| 1017 | - ?> | |
| 1018 | - <script type="text/javascript"> | |
| 1019 | - document.addEventListener('DOMContentLoaded', function() { | |
| 1020 | - const heading = document.querySelector('.wrap .wp-heading-inline'); | |
| 1021 | - if (heading) { | |
| 1022 | - const iconLink = document.createElement('a'); | |
| 1023 | - iconLink.href = '<?php echo esc_url( $list_url ); ?>'; | |
| 1024 | - iconLink.innerHTML = '<span class="dashicons dashicons-arrow-left-alt2" style="font-size:28px;height:28px;width:28px;"></span>'; | |
| 1025 | - iconLink.style.cssText = "text-decoration:none;color:#555;display:inline-flex;align-items:center;margin-right:2px;transform:translateY(20%);box-shadow:none;"; | |
| 1026 | - iconLink.title = '<?php echo esc_html_e( 'Back to subscriptions list.', 'subscription' ); ?>'; | |
| 1027 | - | |
| 1028 | - heading.insertAdjacentElement('beforebegin', iconLink); | |
| 1029 | - } | |
| 1030 | - }); | |
| 1031 | - </script> | |
| 1032 | 514 | <?php |
| 1033 | 515 | } |
| 1034 | 516 | } |