PluginProbe
Subscriptions for WooCommerce with Stripe Recurring Payments / 2.4.0
Subscriptions for WooCommerce with Stripe Recurring Payments v2.4.0
2.4.0 2.3.0 2.2.0 2.1.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 All 65 releases
← All changes | includes/Admin/views/subscription-list.php +76 -47 1.11.1 → 2.4.0 View file →
@@ -11,33 +11,43 @@
11 11
12 12 if ( ! isset( $date_filter ) ) {
13 13 $date_filter = '';
14 14 }
15 +if ( ! isset( $renewal_due ) ) {
16 + $renewal_due = 0;
17 +}
15 18
16 -$filters_active = ! empty( $status ) || ! empty( $date_filter ) || ! empty( $search );
17 -$months = array();
19 +$filters_active = ! empty( $status ) || ! empty( $date_filter ) || ! empty( $search ) || ! empty( $renewal_due );
20 +
21 +// The last twelve of the store's months, counted back from the 1st: stepping
22 +// back from today skips a month on the 29th–31st (31 Oct βˆ’ 1 month is 1 Oct).
23 +// The store's timezone, because the list filters on the local post date.
24 +$months = array();
25 +$this_month = ( new DateTimeImmutable( 'now', wp_timezone() ) )->modify( 'first day of this month' )->setTime( 0, 0 );
18 26 for ( $i = 0; $i < 12; $i++ ) {
19 27 $month = strtotime( "-$i month" );
20 - $months[ date( 'Y-m', $month ) ] = date( 'F Y', $month );
28 + $months[ gmdate( 'Y-m', $month ) ] = wp_date( 'F Y', $month, new \DateTimeZone( 'UTC' ) );
21 29 }
22 30 ?>
23 -<div class="wp-subscription-admin-content list-page subscrpt-subs-list">
31 +<div class="wp-subscription-admin-content list-page">
24 32
25 33 <?php
26 - // Getting started card β€” hidden once a subscription product exists.
27 - require __DIR__ . '/subscription-gsc.php';
34 + // Getting started ("Welcome to WPSubscription") card hidden for now β€” re-enable later.
35 + // require __DIR__ . '/subscription-gsc.php';
28 36 ?>
29 37
30 - <!-- Page header -->
31 - <div style="margin-bottom:20px;">
32 - <h1 style="font-size:1.375rem;font-weight:700;color:var(--wpsubs-text);margin:0 0 6px;line-height:1.2;"><?php esc_html_e( 'Subscriptions', 'subscription' ); ?></h1>
33 - <p style="font-size:13px;color:var(--wpsubs-text-muted);margin:0 0 12px;line-height:1.5;"><?php esc_html_e( 'Manage all your WooCommerce subscriptions.', 'subscription' ); ?></p>
34 - <div style="border-top:1px dashed #d0d3d7;"></div>
35 - </div>
38 + <?php
39 + wpsubs_render_page_header(
40 + array(
41 + 'title' => __( 'Subscriptions', 'subscription' ),
42 + 'description' => __( 'Manage all your WooCommerce subscriptions.', 'subscription' ),
43 + )
44 + );
45 + ?>
36 46
37 47 <form method="post" id="subscriptions-form">
38 48 <?php wp_nonce_field( 'subscrpt_list_action' ); ?>
39 - <input type="hidden" name="page" value="wp-subscription" />
49 + <input type="hidden" name="page" value="wp-subscription-list" />
40 50
41 51 <!-- Toolbar -->
42 52 <div class="wpsubs-toolbar">
43 53
@@ -52,12 +62,20 @@
52 62 'value' => 'active',
53 63 'label' => __( 'Active', 'subscription' ),
54 64 ),
55 65 array(
66 + 'value' => 'on_hold',
67 + 'label' => __( 'On Hold', 'subscription' ),
68 + ),
69 + array(
56 70 'value' => 'pending',
57 71 'label' => __( 'Pending', 'subscription' ),
58 72 ),
59 73 array(
74 + 'value' => 'pe_cancelled',
75 + 'label' => __( 'Pending Cancellation', 'subscription' ),
76 + ),
77 + array(
60 78 'value' => 'cancelled',
61 79 'label' => __( 'Cancelled', 'subscription' ),
62 80 ),
63 81 array(
@@ -64,10 +82,10 @@
64 82 'value' => 'expired',
65 83 'label' => __( 'Expired', 'subscription' ),
66 84 ),
67 85 array(
68 - 'value' => 'draft',
69 - 'label' => __( 'Draft', 'subscription' ),
86 + 'value' => 'completed',
87 + 'label' => __( 'Completed', 'subscription' ),
70 88 ),
71 89 array(
72 90 'value' => 'trash',
73 91 'label' => __( 'Trash', 'subscription' ),
@@ -94,8 +112,32 @@
94 112 )
95 113 );
96 114 ?>
97 115
116 + <?php
117 + // Next-renewal window. The Overview's "Renewals due" figure opens the
118 + // list with 7 chosen; a window reached by URL is offered too, so the
119 + // dropdown always shows what is applied.
120 + $renewal_windows = array_unique( array_merge( array( 7, 14, 30 ), $renewal_due ? array( $renewal_due ) : array() ) );
121 + sort( $renewal_windows );
122 + $renewal_options = array();
123 + foreach ( $renewal_windows as $days ) {
124 + $renewal_options[] = array(
125 + 'value' => (string) $days,
126 + /* translators: %d: number of days ahead. */
127 + 'label' => sprintf( _n( 'Due in %d day', 'Due in %d days', $days, 'subscription' ), $days ),
128 + );
129 + }
130 + wpsubs_render_adv_select(
131 + array(
132 + 'name' => 'renewal_due',
133 + 'placeholder' => __( 'All Renewals', 'subscription' ),
134 + 'value' => $renewal_due ? (string) $renewal_due : '',
135 + 'options' => $renewal_options,
136 + )
137 + );
138 + ?>
139 +
98 140 <div class="wpsubs-search">
99 141 <div class="wpsubs-input-wrap wpsubs-input-wrap--icon-l">
100 142 <svg class="wpsubs-input-icon" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-4.35-4.35M17 11A6 6 0 1 1 5 11a6 6 0 0 1 12 0z"/></svg>
101 143 <input type="search" name="s" value="<?php echo esc_attr( $search ); ?>" placeholder="<?php esc_attr_e( 'Search subscriptions...', 'subscription' ); ?>" class="wpsubs-input" />
@@ -106,9 +148,9 @@
106 148 <?php esc_html_e( 'Filter', 'subscription' ); ?>
107 149 </button>
108 150
109 151 <?php if ( $filters_active ) : ?>
110 - <a href="<?php echo esc_url( remove_query_arg( array( 'subscrpt_status', 'date_filter', 's', 'title', 'paged' ) ) ); ?>" class="wpsubs-btn wpsubs-btn--outline">
152 + <a href="<?php echo esc_url( remove_query_arg( array( 'subscrpt_status', 'date_filter', 's', 'title', 'paged', 'renewal_due' ) ) ); ?>" class="wpsubs-btn wpsubs-btn--outline">
111 153 <?php esc_html_e( 'Clear', 'subscription' ); ?>
112 154 </a>
113 155 <?php endif; ?>
114 156
@@ -113,34 +155,18 @@
113 155 <?php endif; ?>
114 156
115 157 <div class="wpsubs-toolbar__spacer"></div>
116 158
159 + <?php // Page size and bulk actions wrap as one right-aligned group, never one without the other. ?>
160 + <div style="display:flex;flex-wrap:wrap;gap:8px;margin-inline-start:auto;">
117 161 <?php
118 162 $current_per_page = isset( $_GET['per_page'] ) ? intval( wp_unslash( $_GET['per_page'] ) ) : 20;
119 - wpsubs_render_adv_select(
163 + wpsubs_render_per_page_select(
120 164 array(
121 - 'name' => 'per_page',
122 - 'value' => (string) $current_per_page,
123 - 'options' => array(
124 - array(
125 - 'value' => '10',
126 - 'label' => __( '10 / page', 'subscription' ),
127 - ),
128 - array(
129 - 'value' => '20',
130 - 'label' => __( '20 / page', 'subscription' ),
131 - ),
132 - array(
133 - 'value' => '50',
134 - 'label' => __( '50 / page', 'subscription' ),
135 - ),
136 - array(
137 - 'value' => '100',
138 - 'label' => __( '100 / page', 'subscription' ),
139 - ),
140 - ),
141 - 'align' => 'right',
142 - 'id' => 'wpsubs-per-page-select',
165 + 'name' => 'per_page',
166 + 'value' => (string) $current_per_page,
167 + 'align' => 'right',
168 + 'id' => 'wpsubs-per-page-select',
143 169 )
144 170 );
145 171 ?>
146 172
@@ -182,14 +208,15 @@
182 208 <button type="submit" name="bulk_action" value="1" id="wpsubs-bulk-action-submit" style="display:none;" aria-hidden="true"></button>
183 209
184 210 <?php
185 211 if ( 'trash' === $status && ! empty( $subscriptions ) ) :
186 - $empty_trash_url = wp_nonce_url( admin_url( 'admin.php?page=wp-subscription&action=clean_trash&sub_id=all' ), 'wpsubs_action_clean_trash' );
212 + $empty_trash_url = wp_nonce_url( admin_url( 'admin.php?page=wp-subscription-list&action=clean_trash&sub_id=all' ), 'wpsubs_action_clean_trash' );
187 213 ?>
188 214 <a href="<?php echo esc_url( $empty_trash_url ); ?>" class="wpsubs-btn wpsubs-btn--danger" onclick="return confirm('<?php esc_attr_e( 'Permanently delete all trash items? This cannot be undone.', 'subscription' ); ?>')">
189 215 <?php esc_html_e( 'Empty Trash', 'subscription' ); ?>
190 216 </a>
191 217 <?php endif; ?>
218 + </div>
192 219
193 220 </div><!-- /.wpsubs-toolbar -->
194 221
195 222 <!-- Table card -->
@@ -235,9 +262,9 @@
235 262 $customer_url = $customer_id ? admin_url( 'user-edit.php?user_id=' . $customer_id ) : '';
236 263 $customer_email = $order ? $order->get_billing_email() : '';
237 264
238 265 $start_date = $subscription_data['start_date'] ? strtotime( $subscription_data['start_date'] ) : 0;
239 - $renewal_date = $subscription_data['next_date'] ? strtotime( $subscription_data['next_date'] ) : 0;
266 + $renewal_date = $subscription_data['next_date'] && SpringDevs\Subscription\Illuminate\Helper::has_next_payment( $subscrpt_status ) ? strtotime( $subscription_data['next_date'] ) : 0;
240 267
241 268 $is_trash = 'trash' === $subscription->post_status;
242 269 $is_grace_period = isset( $subscription_data['grace_period'] );
243 270 $grace_remaining = $subscription_data['grace_period']['remaining_days'] ?? 0;
@@ -252,11 +279,12 @@
252 279 $timing_per = $subscription_data['schedule']['timing_per'] ?? '';
253 280 $timing_option = $subscription_data['schedule']['timing_option'] ?? '';
254 281 $timing_label = '';
255 282 if ( $timing_per && $timing_option ) {
283 + $timing_unit = \SpringDevs\Subscription\Illuminate\Helper::get_typos( $timing_per, $timing_option );
256 284 $timing_label = ( (int) $timing_per > 1 )
257 - ? $timing_per . ' ' . $timing_option . 's'
258 - : $timing_option;
285 + ? $timing_per . ' ' . $timing_unit
286 + : $timing_unit;
259 287 }
260 288
261 289 // Avatar
262 290 $name_parts = array_values( array_filter( explode( ' ', trim( $customer ) ) ) );
@@ -271,11 +299,11 @@
271 299
272 300 // Action URLs
273 301 $nonce_action = 'wpsubs_action_' . $subscription->ID;
274 302 $view_url = admin_url( 'admin.php?page=wp-subscription-details&id=' . $subscription->ID );
275 - $trash_url = wp_nonce_url( admin_url( 'admin.php?page=wp-subscription&action=trash&sub_id=' . $subscription->ID ), $nonce_action );
276 - $delete_url = wp_nonce_url( admin_url( 'admin.php?page=wp-subscription&action=delete&sub_id=' . $subscription->ID ), $nonce_action );
277 - $restore_url = wp_nonce_url( admin_url( 'admin.php?page=wp-subscription&action=restore&sub_id=' . $subscription->ID ), $nonce_action );
303 + $trash_url = wp_nonce_url( admin_url( 'admin.php?page=wp-subscription-list&action=trash&sub_id=' . $subscription->ID ), $nonce_action );
304 + $delete_url = wp_nonce_url( admin_url( 'admin.php?page=wp-subscription-list&action=delete&sub_id=' . $subscription->ID ), $nonce_action );
305 + $restore_url = wp_nonce_url( admin_url( 'admin.php?page=wp-subscription-list&action=restore&sub_id=' . $subscription->ID ), $nonce_action );
278 306
279 307 // Status badge
280 308 $badge_mod_map = array(
281 309 'active' => 'active',
@@ -282,8 +310,9 @@
282 310 'pending' => 'pending',
283 311 'pe_cancelled' => 'pending-cancel',
284 312 'cancelled' => 'cancelled',
285 313 'expired' => 'expired',
314 + 'completed' => 'completed',
286 315 'draft' => 'draft',
287 316 'trash' => 'trash',
288 317 );
289 318 $badge_mod = $badge_mod_map[ $subscrpt_status ] ?? 'expired';
@@ -304,9 +333,9 @@
304 333 <td style="white-space:nowrap;">
305 334 <span class="wpsubs-badge wpsubs-badge--<?php echo esc_attr( $badge_mod ); ?>">
306 335 <?php echo esc_html( $verbose_status ); ?>
307 336 <?php if ( $is_grace_period && $grace_remaining > 0 ) : ?>
308 - <span class="dashicons dashicons-warning" style="font-size:11px;width:11px;height:11px;color:#d97706;" title="<?php echo esc_attr( sprintf( __( '%d days remaining in grace period', 'subscription' ), $grace_remaining ) ); ?>"></span>
337 + <span class="dashicons dashicons-warning" style="font-size:11px;width:11px;height:11px;color:#d97706;" title="<?php echo esc_attr( sprintf( /* translators: %d: number of days left in the grace period. */ __( '%d days remaining in grace period', 'subscription' ), $grace_remaining ) ); ?>"></span>
309 338 <?php endif; ?>
310 339 </span>
311 340 </td>
312 341