Passed
Pull Request — master (#408)
by Brian
05:34
created

wpinv_subscription_init()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 2
rs 10
1
<?php
2
/**
3
 * Main Subscriptions class.
4
 *
5
 */
6
7
defined( 'ABSPATH' ) || exit;
8
/**
9
 * Main Subscriptions class.
10
 *
11
 */
12
class WPInv_Subscriptions {
13
14
    /**
15
	 * Class constructor.
16
	 */
17
    public function __construct(){
18
19
        // Fire gateway specific hooks when a subscription changes.
20
        add_action( 'getpaid_subscription_status_changed', array( $this, 'process_subscription_status_change' ), 10, 3 );
21
22
        // Handles subscription cancelations.
23
        add_action( 'getpaid_authenticated_action_subscription_cancel', array( $this, 'user_cancel_single_subscription' ) );
24
25
        // Create a subscription whenever an invoice is created, (and update it when it is updated).
26
        add_action( 'getpaid_new_invoice', array( $this, 'maybe_create_invoice_subscription' ) );
27
        add_action( 'getpaid_update_invoice', array( $this, 'maybe_update_invoice_subscription' ) );
28
29
        // Handles admin subscription update actions.
30
        add_action( 'getpaid_authenticated_admin_action_update_single_subscription', array( $this, 'admin_update_single_subscription' ) );
31
        add_action( 'getpaid_authenticated_admin_action_subscription_manual_renew', array( $this, 'admin_renew_single_subscription' ) );
32
        add_action( 'getpaid_authenticated_admin_action_subscription_manual_delete', array( $this, 'admin_delete_single_subscription' ) );
33
    }
34
35
    /**
36
	 * Processes subscription status changes.
37
     * 
38
     * @param WPInv_Subscription $subscription
39
     * @param string $from
40
     * @param string $to
41
	 */
42
    public function process_subscription_status_change( $subscription, $from, $to ) {
43
44
        $gateway = $subscription->get_gateway();
45
46
        if ( ! empty( $gateway ) ) {
47
            $gateway = sanitize_key( $gateway );
48
            $from    = sanitize_key( $from );
49
            $to      = sanitize_key( $to );
50
            do_action( "getpaid_{$gateway}subscription_$to", $subscription, $from );
51
        }
52
53
    }
54
55
    /**
56
     * Get pretty subscription frequency
57
     *
58
     * @param $period
59
     * @param int $frequency_count The frequency of the period.
60
     * @return mixed|string|void
61
     */
62
    public static function wpinv_get_pretty_subscription_frequency( $period, $frequency_count = 1) {
63
64
        $frequency = '';
65
        //Format period details
66
        switch ( strtolower( $period ) ) {
67
            case 'day' :
68
            case 'd' :
69
                $frequency = sprintf( _n('%d Day', '%d Days', $frequency_count, 'invoicing'), $frequency_count);
70
                break;
71
            case 'week' :
72
            case 'w' :
73
                $frequency = sprintf( _n('%d Week', '%d Weeks', $frequency_count, 'invoicing'), $frequency_count);
74
                break;
75
            case 'month' :
76
            case 'm' :
77
                $frequency = sprintf( _n('%d Month', '%d Months', $frequency_count, 'invoicing'), $frequency_count);
78
                break;
79
            case 'year' :
80
            case 'y' :
81
                $frequency = sprintf( _n('%d Year', '%d Years', $frequency_count, 'invoicing'), $frequency_count);
82
                break;
83
            default :
84
                $frequency = apply_filters( 'wpinv_recurring_subscription_frequency', $frequency, $period, $frequency_count );
85
                break;
86
        }
87
88
        return $frequency;
89
90
    }
91
92
    /**
93
     * Handles cancellation requests for a subscription
94
     *
95
     * @access      public
96
     * @since       1.0.0
97
     * @return      void
98
     */
99
    public function user_cancel_single_subscription( $data ) {
100
101
        // Ensure there is a subscription to cancel.
102
        if ( empty( $args['sub_id'] ) ) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $args seems to never exist and therefore empty should always be true.
Loading history...
103
            return;
104
        }
105
106
        $subscription = new WPInv_Subscription( (int) $data['sub_id'] );
107
108
        // Ensure that it exists and that it belongs to the current user.
109
        if ( ! $subscription->get_id() || $subscription->get_customer_id() != get_current_user_id() ) {
110
            wpinv_set_error( 'invalid_subscription', __( 'You do not have permission to cancel this subscription', 'invoicing' ) );
111
112
        // Can it be cancelled.
113
        } else if ( ! $subscription->can_cancel() ) {
114
            wpinv_set_error( 'cannot_cancel', __( 'This subscription cannot be cancelled as it is not active.', 'invoicing' ) );
115
            
116
117
        // Cancel it.
118
        } else {
119
120
            $subscription->cancel();
121
            wpinv_set_error( 'cancelled', __( 'This subscription is now cancelled.', 'invoicing' ), 'info' );
122
        }
123
124
125
        $redirect = add_query_arg(
126
            array(
127
                'getpaid-action' => false,
128
                'getpaid-nonce'  => false,
129
                'sub_id'         => false,
130
            )
131
        );
132
133
        wp_safe_redirect( esc_url( $redirect ) );
134
        exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
135
136
    }
137
138
    /**
139
     * Creates a subscription for an invoice.
140
     *
141
     * @access      public
142
     * @param       WPInv_Invoice $invoice
143
     * @since       1.0.0
144
     */
145
    public function maybe_create_invoice_subscription( $invoice ) {
146
147
        // Abort if it is not recurring.
148
        if ( $invoice->is_free() || ! $invoice->is_recurring() || $invoice->is_renewal() ) {
149
            return;
150
        }
151
152
        $subscription = new WPInv_Subscription();
153
        return $this->update_invoice_subscription( $subscription, $invoice );
154
155
    }
156
157
    /**
158
     * (Maybe) Updates a subscription for an invoice.
159
     *
160
     * @access      public
161
     * @param       WPInv_Invoice $invoice
162
     * @since       1.0.19
163
     */
164
    public function maybe_update_invoice_subscription( $invoice ) {
165
166
        // Do not process renewals.
167
        if ( $invoice->is_renewal() ) {
168
            return;
169
        }
170
171
        // (Maybe) create a new subscription.
172
        if ( ! $invoice->get_subscription_id() ) {
173
            return $this->maybe_create_invoice_subscription( $invoice );
174
        }
175
176
        $subscription = new WPInv_Subscription( $invoice->get_subscription_id() );
177
178
        // In case the subscription was deleted...
179
        if ( ! $subscription->get_id() ) {
180
            $invoice->set_subscription_id(0);
181
            $invoice->save();
182
            return $this->maybe_create_invoice_subscription( $invoice );
183
        }
184
185
        // Abort if an invoice is paid and already has a subscription.
186
        if ( $invoice->is_paid() || $invoice->is_refunded() ) {
187
            return;
188
        }
189
190
        return $this->update_invoice_subscription( $subscription, $invoice );
191
192
    }
193
194
    /**
195
     * Updates a subscription for an invoice.
196
     *
197
     * @access      public
198
     * @param       WPInv_Subscription $subscription
199
     * @param       WPInv_Invoice $invoice
200
     * @since       1.0.19
201
     */
202
    public function update_invoice_subscription( $subscription, $invoice ) {
203
204
        // Delete the subscription if an invoice is free.
205
        if ( $invoice->is_free() || ! $invoice->is_recurring() ) {
206
            return $subscription->delete();
207
        }
208
209
        $subscription->set_customer_id( $invoice->get_customer_id() );
210
        $subscription->set_parent_invoice_id( $invoice->get_id() );
211
        $subscription->set_initial_amount( $invoice->get_initial_total() );
212
        $subscription->set_recurring_amount( $invoice->get_recurring_total() );
213
        $subscription->set_date_created( current_time( 'mysql' ) );
214
        $subscription->set_status( $invoice->is_paid() ? 'active' : 'pending' );
215
216
        // Get the recurring item and abort if it does not exist.
217
        $subscription_item = $invoice->get_recurring( true );
218
        if ( ! $subscription_item->get_id() ) {
219
            return $subscription->delete();
220
        }
221
222
        $subscription->set_product_id( $subscription_item->get_id() );
223
        $subscription->set_period( $subscription_item->get_recurring_period( true ) );
224
        $subscription->set_frequency( $subscription_item->get_recurring_interval() );
225
        $subscription->set_bill_times( $subscription_item->get_recurring_limit() );
226
227
        // Calculate the next renewal date.
228
        $period       = $subscription_item->get_recurring_period( true );
229
        $interval     = $subscription_item->get_recurring_interval();
230
231
        // If the subscription item has a trial period...
232
        if ( $subscription_item->has_free_trial() ) {
233
            $period   = $subscription_item->get_trial_period( true );
234
            $interval = $subscription_item->get_trial_interval();
235
            $subscription->set_trial_period( $interval . ' ' . $period );
236
            $subscription->set_status( 'trialling' );
237
        }
238
239
        // If initial amount is free, treat it as a free trial even if the subscription item does not have a free trial.
240
        if ( $invoice->has_free_trial() ) {
241
            $subscription->set_trial_period( $interval . ' ' . $period );
242
            $subscription->set_status( 'trialling' );
243
        }
244
245
        // Calculate the next renewal date.
246
        $expiration = date( 'Y-m-d H:i:s', strtotime( "+ $interval $period", strtotime( $subscription->get_date_created() ) ) );
247
248
        $subscription->set_next_renewal_date( $expiration );
249
        return $subscription->save();
250
251
    }
252
253
    /**
254
     * Fired when an admin updates a subscription via the single subscription single page.
255
     *
256
     * @param       array $data
257
     * @since       1.0.19
258
     */
259
    public function admin_update_single_subscription( $args ) {
260
261
        // Ensure the subscription exists and that a status has been given.
262
        if ( empty( $args['subscription_id'] ) || empty( $args['subscription_status'] ) ) {
263
            return;
264
        }
265
266
        // Retrieve the subscriptions.
267
        $subscription = new WPInv_Subscription( $args['subscription_id'] );
268
269
        if ( $subscription->get_id() ) {
270
271
            $subscription->set_status( $args['subscription_status'] );
272
            $subscription->save();
273
            getpaid_admin()->show_info( __( 'Your changes have been saved', 'invoicing' ) );
274
275
        }
276
277
    }
278
279
    /**
280
     * Fired when an admin manually renews a subscription.
281
     *
282
     * @param       array $data
283
     * @since       1.0.19
284
     */
285
    public function admin_renew_single_subscription( $args ) {
286
287
        // Ensure the subscription exists and that a status has been given.
288
        if ( empty( $args['id'] ) ) {
289
            return;
290
        }
291
292
        // Retrieve the subscriptions.
293
        $subscription = new WPInv_Subscription( $args['id'] );
294
295
        if ( $subscription->get_id() ) {
296
297
            $args = array( 'transaction_id', $subscription->get_parent_invoice()->generate_key( 'renewal_' ) );
298
299
            if ( $subscription->add_payment( $args ) ) {
300
                $subscription->renew();
301
                getpaid_admin()->show_info( __( 'This subscription has been renewed and extended.', 'invoicing' ) );
302
            } else {
303
                getpaid_admin()->show_error( __( 'We are unable to renew this subscription as the parent invoice does not exist.', 'invoicing' ) );
304
            }
305
    
306
            wp_safe_redirect(
307
                add_query_arg(
308
                    array(
309
                        'getpaid-admin-action' => false,
310
                        'getpaid-nonce'        => false,
311
                    )
312
                )
313
            );
314
            exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
315
316
        }
317
318
    }
319
320
    /**
321
     * Fired when an admin manually deletes a subscription.
322
     *
323
     * @param       array $data
324
     * @since       1.0.19
325
     */
326
    public function admin_delete_single_subscription( $args ) {
327
328
        // Ensure the subscription exists and that a status has been given.
329
        if ( empty( $args['id'] ) ) {
330
            return;
331
        }
332
333
        // Retrieve the subscriptions.
334
        $subscription = new WPInv_Subscription( $args['id'] );
335
336
        if ( $subscription->delete() ) {
337
            getpaid_admin()->show_info( __( 'This subscription has been deleted.', 'invoicing' ) );
338
        } else {
339
            getpaid_admin()->show_error( __( 'We are unable to delete this subscription. Please try again.', 'invoicing' ) );
340
        }
341
    
342
        wp_safe_redirect(
343
            add_query_arg(
344
                array(
345
                    'getpaid-admin-action' => false,
346
                    'getpaid-nonce'        => false,
347
                    'id'                   => false,
348
                )
349
            )
350
        );
351
352
        exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
353
354
    }
355
356
}
357