Passed
Push — master ( abdd42...378b1c )
by Brian
20:25 queued 15:01
created

wpinv_get_pretty_subscription_frequency()   B

Complexity

Conditions 9
Paths 9

Size

Total Lines 27
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 22
c 1
b 0
f 0
dl 0
loc 27
rs 8.0555
cc 9
nc 9
nop 2
1
<?php
2
// Exit if accessed directly.
3
if (!defined( 'ABSPATH' ) ) exit;
4
5
function wpinv_subscription_init() {
6
    return WPInv_Subscriptions::instance();
7
}
8
add_action( 'plugins_loaded', 'wpinv_subscription_init', 100 );
9
10
/**
11
 * WPInv_Subscriptions Class.
12
 *
13
 * @since 1.0.0
14
 */
15
class WPInv_Subscriptions {
16
17
    private static $instance;
18
19
    /**
20
     * Main WPInv_Subscriptions Instance
21
     */
22
    public static function instance() {
23
        if ( ! isset( self::$instance ) ) {
24
            self::$instance = new WPInv_Subscriptions;
25
26
            self::$instance->init();
27
        }
28
29
        return self::$instance;
30
    }
31
32
    /**
33
     * Constructor -- prevent new instances
34
     *
35
     * @since 1.0.0
36
     */
37
    private function __construct(){
38
39
    }
40
41
    /**
42
     * Get things started
43
     *
44
     * Sets up inits actions and filters
45
     *
46
     * @since 1.0.0
47
     */
48
    function init() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
49
50
        self::setup_constants();
0 ignored issues
show
Bug Best Practice introduced by
The method WPInv_Subscriptions::setup_constants() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

50
        self::/** @scrutinizer ignore-call */ 
51
              setup_constants();
Loading history...
51
        self::actions();
0 ignored issues
show
Bug Best Practice introduced by
The method WPInv_Subscriptions::actions() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

51
        self::/** @scrutinizer ignore-call */ 
52
              actions();
Loading history...
52
        self::filters();
0 ignored issues
show
Bug Best Practice introduced by
The method WPInv_Subscriptions::filters() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

52
        self::/** @scrutinizer ignore-call */ 
53
              filters();
Loading history...
53
54
    }
55
56
    /**
57
     * Setup plugin constants.
58
     *
59
     * @access private
60
     * @since 1.0.0
61
     * @return void
62
     */
63
    private function setup_constants() {
64
65
        // Make sure CAL_GREGORIAN is defined.
66
        if ( ! defined( 'CAL_GREGORIAN' ) ) {
67
            define( 'CAL_GREGORIAN', 1 );
68
        }
69
    }
70
71
    /**
72
     * Add our actions
73
     *
74
     * @since  1.0.0
75
     * @return void
76
     */
77
    private function actions() {
78
79
        add_action( 'admin_menu', array( $this, 'wpinv_subscriptions_list' ), 40 );
80
        add_action( 'admin_notices', array( $this, 'notices' ) );
81
        add_action( 'init', array( $this, 'wpinv_post_actions' ) );
82
        add_action( 'init', array( $this, 'wpinv_get_actions' ) );
83
        add_action( 'wpinv_cancel_subscription', array( $this, 'wpinv_process_cancellation' ) );
84
        add_action( 'getpaid_checkout_before_gateway', array( $this, 'add_subscription' ), -999 );
85
        add_action( 'wpinv_subscriptions_front_notices', array( $this, 'notices' ) );
86
        add_action( 'getpaid_authenticated_admin_action_update_single_subscription', array( $this, 'admin_update_single_subscription' ) );
87
        add_action( 'getpaid_authenticated_admin_action_subscription_manual_renew', array( $this, 'admin_renew_single_subscription' ) );
88
    }
89
90
    /**
91
     * Add our filters
92
     *
93
     * @since  1.0
94
     * @return void
95
     */
96
    private function filters() {
97
98
    }
99
100
    /**
101
     * Register our Subscriptions submenu
102
     *
103
     * @since  2.4
104
     * @return void
105
     */
106
    public function wpinv_subscriptions_list() {
107
        add_submenu_page(
108
            'wpinv',
109
            __( 'Subscriptions', 'invoicing' ),
110
            __( 'Subscriptions', 'invoicing' ),
111
            wpinv_get_capability(),
112
            'wpinv-subscriptions',
113
            'wpinv_subscriptions_page'
114
        );
115
    }
116
117
    public function notices() {
118
119
        if( empty( $_GET['wpinv-message'] ) ) {
120
            return;
121
        }
122
123
        $type    = 'updated';
124
        $message = '';
125
126
        switch( strtolower( $_GET['wpinv-message'] ) ) {
127
128
            case 'updated' :
129
130
                $message = __( 'Subscription updated successfully.', 'invoicing' );
131
132
                break;
133
134
            case 'deleted' :
135
136
                $message = __( 'Subscription deleted successfully.', 'invoicing' );
137
138
                break;
139
140
            case 'cancelled' :
141
142
                $message = __( 'Subscription cancelled successfully.', 'invoicing' );
143
144
                break;
145
146
        }
147
148
        if ( ! empty( $message ) ) {
149
            echo '<div class="' . esc_attr( $type ) . '"><p>' . $message . '</p></div>';
150
        }
151
152
    }
153
154
    /**
155
     * Every wpinv_action present in $_GET is called using WordPress's do_action function.
156
     * These functions are called on init.
157
     *
158
     * @since 1.0.0
159
     * @return void
160
     */
161
    function wpinv_get_actions() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
162
        if ( isset( $_GET['wpinv_action'] ) ) {
163
            do_action( 'wpinv_' . $_GET['wpinv_action'], $_GET );
164
        }
165
    }
166
167
    /**
168
     * Every wpinv_action present in $_POST is called using WordPress's do_action function.
169
     * These functions are called on init.
170
     *
171
     * @since 1.0.0
172
     * @return void
173
     */
174
    function wpinv_post_actions() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
175
        if ( isset( $_POST['wpinv_action'] ) ) {
176
            do_action( 'wpinv_' . $_POST['wpinv_action'], $_POST );
177
        }
178
    }
179
180
    /**
181
     * Get pretty subscription frequency
182
     *
183
     * @param $period
184
     * @param int $frequency_count The frequency of the period.
185
     * @return mixed|string|void
186
     */
187
    public static function wpinv_get_pretty_subscription_frequency( $period, $frequency_count = 1) {
188
189
        $frequency = '';
190
        //Format period details
191
        switch ( strtolower( $period ) ) {
192
            case 'day' :
193
            case 'd' :
194
                $frequency = sprintf( _n('%d Day', '%d Days', $frequency_count, 'invoicing'), $frequency_count);
195
                break;
196
            case 'week' :
197
            case 'w' :
198
                $frequency = sprintf( _n('%d Week', '%d Weeks', $frequency_count, 'invoicing'), $frequency_count);
199
                break;
200
            case 'month' :
201
            case 'm' :
202
                $frequency = sprintf( _n('%d Month', '%d Months', $frequency_count, 'invoicing'), $frequency_count);
203
                break;
204
            case 'year' :
205
            case 'y' :
206
                $frequency = sprintf( _n('%d Year', '%d Years', $frequency_count, 'invoicing'), $frequency_count);
207
                break;
208
            default :
209
                $frequency = apply_filters( 'wpinv_recurring_subscription_frequency', $frequency, $period, $frequency_count );
210
                break;
211
        }
212
213
        return $frequency;
214
215
    }
216
217
    /**
218
     * Handles cancellation requests for a subscription
219
     *
220
     * @access      public
221
     * @since       1.0.0
222
     * @return      void
223
     */
224
    public function wpinv_process_cancellation( $data ) {
225
226
227
        if( empty( $data['sub_id'] ) ) {
228
            return;
229
        }
230
231
        if( ! is_user_logged_in() ) {
232
            return;
233
        }
234
235
        if( ! wp_verify_nonce( $data['_wpnonce'], 'wpinv-recurring-cancel' ) ) {
236
            wp_die( __( 'Error', 'invoicing' ), __( 'Nonce verification failed', 'invoicing' ), array( 'response' => 403 ) );
237
        }
238
239
        $data['sub_id'] = absint( $data['sub_id'] );
240
        $subscription   = new WPInv_Subscription( $data['sub_id'] );
241
242
        if( ! $subscription->can_cancel() ) {
243
            wp_die( __( 'Error', 'invoicing' ), __( 'This subscription cannot be cancelled', 'invoicing' ), array( 'response' => 403 ) );
244
        }
245
246
        try {
247
248
            do_action( 'wpinv_recurring_cancel_' . $subscription->gateway . '_subscription', $subscription, true );
0 ignored issues
show
Bug Best Practice introduced by
The property gateway does not exist on WPInv_Subscription. Since you implemented __get, consider adding a @property annotation.
Loading history...
249
250
            $subscription->cancel();
251
252
            if( is_admin() ) {
253
254
                wp_redirect( admin_url( 'admin.php?page=wpinv-subscriptions&wpinv-message=cancelled&id=' . $subscription->id ) );
0 ignored issues
show
Bug Best Practice introduced by
The property $id is declared protected in GetPaid_Data. Since you implement __get, consider adding a @property or @property-read.
Loading history...
255
                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...
256
257
            } else {
258
259
                $redirect = remove_query_arg( array( '_wpnonce', 'wpinv_action', 'sub_id' ), add_query_arg( array( 'wpinv-message' => 'cancelled' ) ) );
260
                $redirect = apply_filters( 'wpinv_recurring_cancellation_redirect', $redirect, $subscription );
261
                wp_safe_redirect( $redirect );
262
                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...
263
264
            }
265
266
        } catch ( Exception $e ) {
267
            wp_die( __( 'Error', 'invoicing' ), $e->getMessage(), array( 'response' => 403 ) );
268
        }
269
270
    }
271
272
    /**
273
     * Creates a subscription on checkout
274
     *
275
     * @access      public
276
     * @param       WPInv_Invoice $invoice
277
     * @since       1.0.0
278
     * @return      void
279
     */
280
    public function add_subscription( $invoice ) {
281
282
        $invoice = new WPInv_Invoice( $invoice );
283
284
        // Abort if it is not recurring.
285
        if ( ! $invoice->is_recurring() || $invoice->is_renewal() ) {
286
            return;
287
        }
288
289
        // Should we create a subscription for the invoice?
290
        if ( apply_filters( 'wpinv_skip_invoice_subscription_creation', false, $invoice ) ) {
291
            return;
292
        }
293
294
        // Get the recurring item.
295
        $subscription_item = $invoice->get_recurring( true );
296
297
        // Prepare the subscription details.
298
        $period       = $subscription_item->get_recurring_period( true );
299
        $interval     = $subscription_item->get_recurring_interval();
300
        $add_period   = $interval . ' ' . $period;
301
        $trial_period = '';
302
303
        if ( $invoice->has_free_trial() ) {
304
305
            if ( $subscription_item->has_free_trial() ) {
306
                $trial_period   = $subscription_item->get_trial_period( true );
307
                $free_interval  = $subscription_item->get_trial_interval();
308
            } else {
309
                $trial_period   = $period;
310
                $free_interval  = $interval;
311
            }
312
313
            $trial_period   = $free_interval . ' ' . $trial_period;
314
            $add_period     = $trial_period;
315
316
        }
317
318
        // Calculate the next renewal date.
319
        $expiration = date( 'Y-m-d H:i:s', strtotime( "+ $add_period", current_time( 'timestamp' ) ) );
320
321
        // Subscription arguments.
322
        $args = array(
323
            'product_id'        => $subscription_item->get_id(),
324
            'customer_id'       => $invoice->get_user_id(),
325
            'parent_payment_id' => $invoice->get_id(),
326
            'status'            => $invoice->has_free_trial() ? 'trialling' : 'pending',
327
            'frequency'         => $interval,
328
            'period'            => $period,
329
            'initial_amount'    => $invoice->get_initial_total(),
330
            'recurring_amount'  => $invoice->get_recurring_total(),
331
            'bill_times'        => $subscription_item->get_recurring_limit(),
332
            'created'           => current_time( 'mysql' ),
333
            'expiration'        => $expiration,
334
            'trial_period'      => $trial_period,
335
            'profile_id'        => '',
336
            'transaction_id'    => '',
337
        );
338
339
        // Create or update the subscription.
340
        $subscription = wpinv_get_subscription( $invoice );
341
342
        if ( empty( $subscription ) ) {
343
344
            $subscription = new WPInv_Subscription();
345
            $subscription->create( $args );
346
347
        } else {
348
349
350
            unset( $args['transaction_id'] );
351
            unset( $args['profile_id'] );
352
            $subscription->update( $args );
353
354
        }
355
356
        return $subscription;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $subscription returns the type WPInv_Subscription|boolean which is incompatible with the documented return type void.
Loading history...
357
    }
358
359
    /**
360
     * Fired when an admin updates a subscription via the single subscription single page.
361
     *
362
     * @param       array $data
363
     * @since       1.0.19
364
     */
365
    public function admin_update_single_subscription( $args ) {
366
367
        // Ensure the subscription exists and that a status has been given.
368
        if ( empty( $args['subscription_id'] ) || empty( $args['subscription_status'] ) ) {
369
            return;
370
        }
371
372
        // Retrieve the subscriptions.
373
        $subscription = new WPInv_Subscription( $args['subscription_id'] );
374
375
        if ( $subscription->get_id() ) {
376
377
            $subscription->set_status( $args['subscription_status'] );
378
            $subscription->save();
379
            getpaid_admin()->show_info( __( 'Your changes have been saved', 'invoicing' ) );
380
381
        }
382
383
    }
384
385
    /**
386
     * Fired when an admin manually renews a subscription.
387
     *
388
     * @param       array $data
389
     * @since       1.0.19
390
     */
391
    public function admin_renew_single_subscription( $args ) {
392
393
        // Ensure the subscription exists and that a status has been given.
394
        if ( empty( $args['id'] ) ) {
395
            return;
396
        }
397
398
        // Retrieve the subscriptions.
399
        $subscription = new WPInv_Subscription( $args['id'] );
400
401
        if ( $subscription->get_id() ) {
402
403
            $args = array( 'transaction_id', $subscription->get_parent_invoice()->generate_key( 'renewal_' ) );
404
405
            if ( $subscription->add_payment( $args ) ) {
406
                $subscription->renew();
407
                getpaid_admin()->show_info( __( 'This subscription has been renewed and extended.', 'invoicing' ) );
408
            } else {
409
                getpaid_admin()->show_error( __( 'We are unable to renew this subscription as the parent invoice does not exist.', 'invoicing' ) );
410
            }
411
    
412
            wp_safe_redirect(
413
                add_query_arg(
414
                    array(
415
                        'getpaid-admin-action' => false,
416
                        'getpaid-nonce'        => false,
417
                    )
418
                )
419
            );
420
            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...
421
422
        }
423
424
    }
425
426
}
427