Passed
Pull Request — master (#47)
by Kiran
04:02
created

WPInv_Subscription::is_expired()   B

Complexity

Conditions 9
Paths 5

Size

Total Lines 20
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 9
eloc 12
nc 5
nop 0
dl 0
loc 20
rs 7.756
c 0
b 0
f 0
1
<?php
2
if ( ! defined( 'ABSPATH' ) ) {
3
    exit; // Exit if accessed directly
4
}
5
6
class WPInv_Subscription {
7
8
    private $subscriptions_db;
9
10
    public $id                = 0;
11
    public $user_id           = 0;
12
    public $interval          = 1;
13
    public $period            = '';
14
    public $trial_interval    = 0;
15
    public $trial_period      = '';
16
    public $initial_amount    = '';
17
    public $recurring_amount  = '';
18
    public $bill_times        = 0;
19
    public $transaction_id    = '';
20
    public $parent_invoice_id = 0;
21
    public $item_id           = 0;
22
    public $created           = '0000-00-00 00:00:00';
23
    public $expiration        = '0000-00-00 00:00:00';
24
    public $status            = 'pending';
25
    public $profile_id        = '';
26
    public $gateway           = '';
27
    public $user;
28
    public $post_type;
29
30
    function __construct( $id_or_object = 0, $by_profile_id = false ) {
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...
31
        $this->subscriptions_db = new WPInv_Subscriptions_DB;
32
33
        if ( $by_profile_id ) {
34
            $subscription = $this->subscriptions_db->get_by( 'profile_id', $id_or_object );
35
36
            if ( empty( $subscription ) ) {
37
                return false;
0 ignored issues
show
Bug introduced by
Constructors do not have meaningful return values, anything that is returned from here is discarded. Are you sure this is correct?
Loading history...
38
            }
39
40
            $id_or_object = $subscription;
41
        }
42
43
        return $this->setup_subscription( $id_or_object );
0 ignored issues
show
Bug introduced by
Constructors do not have meaningful return values, anything that is returned from here is discarded. Are you sure this is correct?
Loading history...
44
    }
45
46
    private function setup_subscription( $id_or_object = 0 ) {
47
        if ( empty( $id_or_object ) ) {
48
            return false;
49
        }
50
51
        if ( is_numeric( $id_or_object ) ) {
52
            $subscription = $this->subscriptions_db->get( $id_or_object );
53
        } elseif ( is_object( $id_or_object ) ) {
54
            $subscription = $id_or_object;
55
        }
56
57
        if ( empty( $subscription ) ) {
58
            return false;
59
        }
60
61
        foreach( $subscription as $key => $value ) {
62
            $this->$key = $value;
63
        }
64
65
        $this->post_type = get_post_type( $this->parent_invoice_id );
66
        $this->user = get_user_by( 'id', $this->user_id );
67
        $this->gateway = wpinv_get_payment_gateway( $this->parent_invoice_id );
68
69
        do_action( 'wpinv_recurring_setup_subscription', $this );
70
71
        return $this;
72
    }
73
74 View Code Duplication
    public function __get( $key ) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
75
        if ( method_exists( $this, 'get_' . $key ) ) {
76
            return call_user_func( array( $this, 'get_' . $key ) );
77
        } else {
78
            return new WP_Error( 'wpinv-subscription-invalid-property', sprintf( __( 'Can\'t get property %s', 'invoicing' ), $key ) );
79
        }
80
    }
81
82
    public function create( $data = array() ) {
83
        if ( $this->id != 0 ) {
84
            return false;
85
        }
86
87
        $defaults = array(
88
            'user_id'           => 0,
89
            'interval'          => '',
90
            'period'            => '',
91
            'trial_pinterval'   => '',
92
            'trial_period'      => '',
93
            'initial_amount'    => '',
94
            'recurring_amount'  => '',
95
            'bill_times'        => 0,
96
            'parent_invoice_id' => 0,
97
            'item_id'           => 0,
98
            'created'           => '',
99
            'expiration'        => '',
100
            'status'            => '',
101
            'profile_id'        => '',
102
        );
103
104
        $args = wp_parse_args( $data, $defaults );
105
106 View Code Duplication
        if ( $args['expiration'] && strtotime( 'NOW', current_time( 'timestamp' ) ) > strtotime( $args['expiration'], current_time( 'timestamp' ) ) ) {
107
            if ( 'active' == $args['status'] || 'trialling' == $args['status'] ) {
108
                $args['status'] = 'expired';
109
            }
110
        }
111
112
        do_action( 'wpinv_subscription_pre_create', $args );
113
114
        $id = $this->subscriptions_db->insert( $args, 'subscription' );
115
116
        do_action( 'wpinv_subscription_post_create', $id, $args );
117
118
        return $this->setup_subscription( $id );
119
    }
120
121
    public function update( $args = array() ) {
122
        if ( isset( $args['status'] ) && strtolower( $this->status ) !== strtolower( $args['status'] ) ) {
123
            $this->add_note( sprintf( __( 'Status changed from %s to %s', 'invoicing' ), $this->status, $args['status'] ) );
124
        }
125
126
        $ret = $this->subscriptions_db->update( $this->id, $args );
127
128
        do_action( 'wpinv_recurring_update_subscription', $this->id, $args, $this );
129
130
        return $ret;
131
    }
132
133
    public function delete() {
134
        return $this->subscriptions_db->delete( $this->id );
135
    }
136
137
    public function get_original_invoice_id() {
138
        return $this->parent_invoice_id;
139
    }
140
141
    public function get_child_invoices() {
142
        $invoices = wpinv_get_invoices( array(
143
            'post_parent'    => (int)$this->parent_invoice_id,
144
            'posts_per_page' => '999',
145
            'post_status'    => 'any',
146
            'post_type'      => $this->post_type,
147
            'meta_key'       => '_wpinv_subscription_id',
148
            'meta_value'     => $this->id,
149
            'orderby'        => 'ID',
150
            'order'          => 'DESC',
151
        ) );
152
153
        return (array)$invoices;
154
    }
155
156
    public function get_total_invoices() {
157
        return count( $this->get_child_invoices() ) + 1;
158
    }
159
160
    public function get_times_billed() {
161
        $times_billed = $this->get_total_invoices();
162
163
        if ( ! empty( $this->trial_period ) ) {
164
            $times_billed -= 1;
165
        }
166
167
        return $times_billed;
168
    }
169
170
    public function get_lifetime_value() {
171
        $amount = 0.00;
172
173
        $parent_invoice   = new WPInv_Invoice( $this->parent_invoice_id );
0 ignored issues
show
Documentation introduced by
$this->parent_invoice_id is of type integer, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
174
        $ignored_statuses = array( 'wpi-refunded', 'pending', 'wpi-cancelled', 'wpi-failed' );
175
176
        if ( false === in_array( $parent_invoice->status, $ignored_statuses ) ) {
177
            foreach ( $parent_invoice->cart_details as $cart_item ) {
178
                if ( (int) $this->item_id === (int) $cart_item['id'] ) {
179
                    $amount += $cart_item['price'];
180
                    break;
181
                }
182
            }
183
        }
184
185
        $children = $this->get_child_invoices();
186
187
        if ( $children ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $children of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
188
            foreach( $children as $child ) {
189
                $child_invoice = new WPInv_Invoice( $child->ID );
190
                
191
                if ( 'wpi-refunded' === $child_invoice->status ) {
192
                    continue;
193
                }
194
195
                $amount += $child_invoice->total;
196
            }
197
        }
198
199
        return $amount;
200
    }
201
202
    public function add_invoice( $args = array() ) {
203
        $args = wp_parse_args( $args, array(
204
            'amount'         => '',
205
            'transaction_id' => '',
206
            'gateway'        => ''
207
        ) );
208
209
        if ( wpinv_payment_exists( $args['transaction_id'] ) ) {
210
            return false;
211
        }
212
        
213
        $parent_invoice = wpinv_get_invoice( $this->parent_invoice_id );
214
        if ( empty( $parent_invoice ) ) {
215
            return;
216
        }
217
        
218
        $invoice = new WPInv_Invoice();
219
        $invoice->set( 'parent_invoice', $this->parent_invoice_id );
220
        $invoice->set( 'currency', $parent_invoice->get_currency() );
221
        $invoice->set( 'transaction_id', $args['transaction_id'] );
222
        $invoice->set( 'key', $parent_invoice->get_key() );
223
        $invoice->set( 'ip', $parent_invoice->ip );
224
        $invoice->set( 'user_id', $parent_invoice->get_user_id() );
225
        $invoice->set( 'first_name', $parent_invoice->get_first_name() );
226
        $invoice->set( 'last_name', $parent_invoice->get_last_name() );
227
        $invoice->set( 'phone', $parent_invoice->phone );
228
        $invoice->set( 'address', $parent_invoice->address );
229
        $invoice->set( 'city', $parent_invoice->city );
230
        $invoice->set( 'country', $parent_invoice->country );
231
        $invoice->set( 'state', $parent_invoice->state );
232
        $invoice->set( 'zip', $parent_invoice->zip );
233
        $invoice->set( 'company', $parent_invoice->company );
234
        $invoice->set( 'vat_number', $parent_invoice->vat_number );
235
        $invoice->set( 'vat_rate', $parent_invoice->vat_rate );
236
        $invoice->set( 'adddress_confirmed', $parent_invoice->adddress_confirmed );
237
238 View Code Duplication
        if ( empty( $args['gateway'] ) ) {
239
            $invoice->set( 'gateway', $parent_invoice->get_gateway() );
240
        } else {
241
            $invoice->set( 'gateway', $args['gateway'] );
242
        }
243
        
244
        $recurring_details = $parent_invoice->get_recurring_details();
245
246
        // increase the earnings for each item in the subscription
247
        $items = $recurring_details['cart_details'];
248
        
249 View Code Duplication
        if ( $items ) {        
250
            $add_items      = array();
251
            $cart_details   = array();
252
            
253
            foreach ( $items as $item ) {
254
                $add_item             = array();
255
                $add_item['id']       = $item['id'];
256
                $add_item['quantity'] = $item['quantity'];
257
                
258
                $add_items[]    = $add_item;
259
                $cart_details[] = $item;
260
                break;
261
            }
262
            
263
            $invoice->set( 'items', $add_items );
264
            $invoice->cart_details = $cart_details;
265
        }
266
        
267
        $total              = $args['amount'];
268
        
269
        $subtotal           = $recurring_details['subtotal'];
270
        $tax                = $recurring_details['tax'];
271
        $discount           = $recurring_details['discount'];
272
        
273
        if ( $discount > 0 ) {
274
            $invoice->set( 'discount_code', $parent_invoice->discount_code );
275
        }
276
        
277
        $invoice->subtotal = wpinv_round_amount( $subtotal );
278
        $invoice->tax      = wpinv_round_amount( $tax );
279
        $invoice->discount = wpinv_round_amount( $discount );
280
        $invoice->total    = wpinv_round_amount( $total );
281
        $invoice->save();
282
        $invoice->update_meta( '_wpinv_subscription_id', $this->id );
283
        
284
        wpinv_update_payment_status( $invoice->ID, 'publish' );
285
        sleep(1);
286
        wpinv_update_payment_status( $invoice->ID, 'wpi-renewal' );
287
        
288
        do_action( 'wpinv_recurring_add_subscription_payment', $invoice, $parent_invoice, $this );
289
        do_action( 'wpinv_recurring_record_payment', $invoice->ID, $this->parent_invoice_id, $total, $this );
290
291
        return $invoice;
292
    }
293
294
    public function get_transaction_id() {
295
        if ( empty( $this->transaction_id ) ) {
296
            $txn_id = wpinv_get_payment_transaction_id( $this->parent_invoice_id );
297
298
            if ( ! empty( $txn_id ) && (int) $this->parent_invoice_id !== (int) $txn_id ) {
299
                $this->set_transaction_id( $txn_id );
300
            }
301
        }
302
303
        return $this->transaction_id;
304
    }
305
306
    public function set_transaction_id( $txn_id = '' ) {
307
        $this->update( array( 'transaction_id' => $txn_id ) );
308
        $this->transaction_id = $txn_id;
309
    }
310
311
    public function renew() {
312
        $expires = $this->get_expiration_time();
313
314
        if ( $expires > current_time( 'timestamp' ) && $this->is_active() ) {
315
            $base_date  = $expires;
316
        } else {
317
            $base_date  = current_time( 'timestamp' );
318
        }
319
320
        $last_day = cal_days_in_month( CAL_GREGORIAN, date_i18n( 'n', $base_date ), date_i18n( 'Y', $base_date ) );
321
322
        $interval = isset($this->interval) ? $this->interval : 1;
323
        $expiration = date_i18n( 'Y-m-d H:i:s', strtotime( '+' . $interval . ' ' . $this->period  . ' 23:59:59', $base_date ) );
324
325
        if ( date_i18n( 'j', $base_date ) == $last_day && 'day' != $this->period ) {
326
            $expiration = date_i18n( 'Y-m-d H:i:s', strtotime( $expiration . ' +2 days' ) );
327
        }
328
329
        $expiration  = apply_filters( 'wpinv_subscription_renewal_expiration', $expiration, $this->id, $this );
330
331
        do_action( 'wpinv_subscription_pre_renew', $this->id, $expiration, $this );
332
333
        $this->status = 'active';
334
        $times_billed = $this->get_times_billed();
335
336
        if ( $this->bill_times > 0 && $times_billed >= $this->bill_times ) {
337
            $this->complete();
338
            $this->status = 'completed';
339
        }
340
341
        $args = array(
342
            'expiration' => $expiration,
343
            'status'     => $this->status,
344
        );
345
346
        $this->update( $args );
347
348
        do_action( 'wpinv_subscription_post_renew', $this->id, $expiration, $this );
349
        do_action( 'wpinv_recurring_set_subscription_status', $this->id, $this->status, $this );
350
    }
351
352 View Code Duplication
    public function complete() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
353
        if ( 'cancelled' === $this->status ) {
354
            return;
355
        }
356
357
        $args = array(
358
            'status' => 'completed'
359
        );
360
361
        if ( $this->subscriptions_db->update( $this->id, $args ) ) {
362
            $this->add_note( sprintf( __( 'Status changed from %s to %s', 'invoicing' ), $this->status, 'completed' ) );
363
364
            $this->status = 'completed';
365
366
            do_action( 'wpinv_subscription_completed', $this->id, $this );
367
        }
368
    }
369
370
    public function expire( $check_expiration = false ) {
371
        $expiration = $this->expiration;
372
373
        if ( $check_expiration && $this->check_expiration() ) {
374
            if ( $expiration < $this->get_expiration() && current_time( 'timestamp' ) < $this->get_expiration_time() ) {
375
                return false;
376
            }
377
        }
378
379
        $args = array(
380
            'status' => 'expired'
381
        );
382
383
        if ( $this->subscriptions_db->update( $this->id, $args ) ) {
384
            $this->add_note( sprintf( __( 'Status changed from %s to %s', 'invoicing' ), $this->status, 'expired' ) );
385
386
            $this->status = 'expired';
387
388
            do_action( 'wpinv_subscription_expired', $this->id, $this );
389
        }
390
    }
391
392 View Code Duplication
    public function failing() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
393
        $args = array(
394
            'status' => 'failing'
395
        );
396
397
        if ( $this->subscriptions_db->update( $this->id, $args ) ) {
398
            $this->add_note( sprintf( __( 'Status changed from %s to %s', 'invoicing' ), $this->status, 'failing' ) );
399
400
            $this->status = 'failing';
401
402
            do_action( 'wpinv_subscription_failing', $this->id, $this );
403
        }
404
    }
405
406
    public function cancel() {
407
        if ( 'cancelled' === $this->status ) {
408
            return;
409
        }
410
411
        $args = array(
412
            'status' => 'cancelled'
413
        );
414
415
        if ( $this->subscriptions_db->update( $this->id, $args ) ) {
416 View Code Duplication
            if ( is_user_logged_in() ) {
417
                $userdata = get_userdata( get_current_user_id() );
418
                $user     = $userdata->user_login;
419
            } else {
420
                $user = __( 'gateway', 'invoicing' );
421
            }
422
423
            $note = sprintf( __( 'Subscription #%d cancelled by %s', 'invoicing' ), $this->id, $user );
424
            $this->add_note( $note );
425
            $this->status = 'cancelled';
426
427
            do_action( 'wpinv_subscription_cancelled', $this->id, $this );
428
        }
429
    }
430
431
    public function can_cancel() {
432
        return apply_filters( 'wpinv_subscription_can_cancel', false, $this );
433
    }
434
435
    public function get_cancel_url() {
436
        $url = wp_nonce_url( add_query_arg( array( 'wpi_action' => 'cancel_subscription', 'sub_id' => $this->id ) ), 'wpinv-recurring-cancel' );
437
438
        return apply_filters( 'wpinv_subscription_cancel_url', $url, $this );
439
    }
440
441
    public function can_renew() {
442
        return apply_filters( 'wpinv_subscription_can_renew', false, $this );
443
    }
444
445
    public function get_renew_url() {
446
        $url = wp_nonce_url( add_query_arg( array( 'wpi_action' => 'renew_subscription', 'sub_id' => $this->id ) ), 'wpinv-recurring-renew' );
447
448
        return apply_filters( 'wpinv_subscription_renew_url', $url, $this );
449
    }
450
451
    public function can_update() {
452
        return apply_filters( 'wpinv_subscription_can_update', false, $this );
453
    }
454
455
    public function get_update_url() {
456
        $url = add_query_arg( array( 'action' => 'update', 'subscription_id' => $this->id ) );
457
458
        return apply_filters( 'wpinv_subscription_update_url', $url, $this );
459
    }
460
461
    public function is_active() {
462
        $ret = false;
463
464
        if ( ! $this->is_expired() && ( $this->status == 'active' || $this->status == 'cancelled' || $this->status == 'trialling' ) ) {
465
            $ret = true;
466
        }
467
468
        return apply_filters( 'wpinv_subscription_is_active', $ret, $this->id, $this );
469
    }
470
471
    public function is_expired() {
472
        $ret = false;
473
474
        if ( $this->status == 'expired' ) {
475
            $ret = true;
476
        } elseif ( 'active' === $this->status || 'cancelled' === $this->status || $this->status == 'trialling'  ) {
477
            $ret        = false;
478
            $expiration = $this->get_expiration_time();
479
480
            if ( $expiration && strtotime( 'NOW', current_time( 'timestamp' ) ) > $expiration ) {
481
                $ret = true;
482
483
                if ( 'active' === $this->status || $this->status == 'trialling'  ) {
484
                    $this->expire();
485
                }
486
            }
487
        }
488
489
        return apply_filters( 'wpinv_subscription_is_expired', $ret, $this->id, $this );
490
    }
491
492
    public function get_expiration( $check_gateway = true ) {
0 ignored issues
show
Unused Code introduced by
The parameter $check_gateway is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
493
        return $this->expiration;
494
    }
495
496
    public function check_expiration() {
497
        $ret   = false;
498
        
499
        $expiration = apply_filters( 'wpinv_subscription_ ' . $this->gateway . '_get_expiration', NULL, $this->id, $this );
0 ignored issues
show
Unused Code introduced by
$expiration is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
500
        
501
        $class = edd_recurring()->get_gateway_class( $this->gateway );
502
503
        if ( $class && class_exists( $class ) ) {
504
            $gateway = new $class;
505
506
            if ( is_callable( array( $gateway, 'get_expiration' ) ) ) {
507
                $expiration = $gateway->get_expiration( $this );
508
509
                if ( ! is_wp_error( $expiration ) && $this->get_expiration_time() < strtotime( $expiration, current_time( 'timestamp' ) ) ) {
510
                    $this->update( array( 'expiration' => $expiration ) );
511
                    $this->expiration = $expiration;
512
                    $ret = true;
513
514
                    $this->add_note( sprintf( __( 'Expiration synced with gateway and updated to %s', 'invoicing' ), $expiration ) );
515
516
                    do_action( 'edd_recurring_check_expiration', $this, $expiration );
517
                }
518
            }
519
        }
520
521
        return $ret;
522
    }
523
524
    public function get_expiration_time() {
525
        return strtotime( $this->expiration, current_time( 'timestamp' ) );
526
    }
527
528
    public function get_status() {
529
        $this->is_expired();
530
        
531
        return $this->status;
532
    }
533
534
    public function get_status_label() {
535
        switch( $this->get_status() ) {
536
            case 'active' :
537
                $status = __( 'Active', 'invoicing' );
538
                break;
539
            case 'cancelled' :
540
                $status = __( 'Cancelled', 'invoicing' );
541
                break;
542
            case 'completed' :
543
                $status = __( 'Completed', 'invoicing' );
544
                break;
545
            case 'expired' :
546
                $status = __( 'Expired', 'invoicing' );
547
                break;
548
            case 'failing' :
549
                $status = __( 'Failing', 'invoicing' );
550
                break;
551
            case 'pending' :
552
                $status = __( 'Pending', 'invoicing' );
553
                break;
554
            case 'stopped' :
555
                $status = __( 'Stopped', 'invoicing' );
556
                break;
557
            case 'trialling' :
558
                $status = __( 'Trialling', 'invoicing' );
559
                break;
560
            default:
561
                $status = $this->get_status();
562
                
563
                if ( $status ) {
564
                    $status = __( wpinv_utf8_ucfirst( $status ), 'invoicing' );
565
                }
566
                break;
567
        }
568
569
        return $status;
570
    }
571
572
    public function get_notes( $length = 20, $paged = 1 ) {
573
        $length = is_numeric( $length ) ? $length : 20;
574
        $offset = is_numeric( $paged ) && $paged != 1 ? ( ( absint( $paged ) - 1 ) * $length ) : 0;
575
576
        $all_notes   = $this->get_raw_notes();
577
        $notes_array = array_reverse( array_filter( explode( "\n\n", $all_notes ) ) );
578
579
        $desired_notes = array_slice( $notes_array, $offset, $length );
580
581
        return $desired_notes;
582
    }
583
584
    public function get_notes_count() {
585
        $all_notes = $this->get_raw_notes();
586
        $notes_array = array_reverse( array_filter( explode( "\n\n", $all_notes ) ) );
587
588
        return count( $notes_array );
589
    }
590
591
    public function add_note( $note = '' ) {
592
        $note = trim( $note );
593
        if ( empty( $note ) ) {
594
            return false;
595
        }
596
597
        $notes = $this->get_raw_notes();
598
599
        if ( empty( $notes ) ) {
600
            $notes = '';
601
        }
602
603
        $note_string = date_i18n( 'F j, Y H:i:s', current_time( 'timestamp' ) ) . ' - ' . $note;
604
        $new_note    = apply_filters( 'edd_subscription_add_note_string', $note_string );
605
        $notes      .= "\n\n" . $new_note;
606
607
        do_action( 'edd_subscription_pre_add_note', $new_note, $this->id );
608
609
        $updated = $this->update( array( 'notes' => $notes ) );
610
611
        if ( $updated ) {
612
            $this->notes = $this->get_notes();
0 ignored issues
show
Bug introduced by
The property notes does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
613
        }
614
615
        do_action( 'edd_subscription_post_add_note', $this->notes, $new_note, $this->id );
616
617
        return $new_note;
618
    }
619
620
    private function get_raw_notes() {
621
        $all_notes = $this->subscriptions_db->get_column( 'notes', $this->id );
622
623
        return (string) $all_notes;
624
    }
625
}
626