Passed
Pull Request — master (#103)
by
unknown
03:48
created

authorizenet.php ➔ wpinv_get_authorizenet_subscription()   D

Complexity

Conditions 9
Paths 9

Size

Total Lines 44
Code Lines 21

Duplication

Lines 19
Ratio 43.18 %

Importance

Changes 0
Metric Value
cc 9
eloc 21
nc 9
nop 2
dl 19
loc 44
rs 4.909
c 0
b 0
f 0
1
<?php
2
// Exit if accessed directly
3
if ( ! defined( 'ABSPATH' ) ) exit;
4
5
add_filter( 'wpinv_authorizenet_support_subscription', '__return_true' );
6
7
function wpinv_authorizenet_cc_form( $invoice_id ) {
8
    $invoice = wpinv_get_invoice( $invoice_id );
9
    $cc_owner = !empty( $invoice ) ? esc_attr( $invoice->get_user_full_name() ) : '';
10
    ?>
11
    <div id="authorizenet_cc_form" class="form-horizontal wpi-cc-form panel panel-default">
12
        <div class="panel-heading"><h3 class="panel-title"><?php _e( 'Card Details', 'invoicing' ) ;?></h3></div>
13
        <div class="panel-body">
14
            <div class="form-group required">
15
              <label for="auth-input-cc-owner" class="col-sm-4 control-label"><?php _e( 'Card Owner', 'invoicing' ) ;?></label>
16
              <div class="col-sm-8">
17
                <input type="text" class="form-control" id="auth-input-cc-owner" placeholder="<?php esc_attr_e( 'Card Owner', 'invoicing' ) ;?>" value="<?php echo $cc_owner;?>" name="authorizenet[cc_owner]">
18
              </div>
19
            </div>
20
            <div class="form-group required">
21
              <label for="auth-input-cc-number" class="col-sm-4 control-label"><?php _e( 'Card Number', 'invoicing' ) ;?></label>
22
              <div class="col-sm-8">
23
                <input type="text" class="form-control" id="auth-input-cc-number" placeholder="<?php esc_attr_e( 'Card Number', 'invoicing' ) ;?>" value="" name="authorizenet[cc_number]">
24
              </div>
25
            </div>
26
            <div class="form-group required">
27
              <label for="auth-input-cc-expire-date" class="col-sm-4 control-label"><?php _e( 'Card Expiry Date', 'invoicing' ) ;?></label>
28
              <div class="col-sm-2">
29
                <select class="form-control" id="auth-input-cc-expire-date" name="authorizenet[cc_expire_month]">
30
                    <?php for ( $i = 1; $i <= 12; $i++ ) { $value = str_pad( $i, 2, '0', STR_PAD_LEFT ); ?>
31
                    <option value="<?php echo $value;?>"><?php echo $value;?></option>
32
                    <?php } ?>
33
                </select>
34
               </div>
35
               <div class="col-sm-2">
36
                <select class="form-control" name="authorizenet[cc_expire_year]">
37
                    <?php $year = date( 'Y' ); for ( $i = $year; $i <= ( $year + 10 ); $i++ ) { ?>
38
                    <option value="<?php echo $i;?>"><?php echo $i;?></option>
39
                    <?php } ?>
40
                </select>
41
              </div>
42
            </div>
43
            <div class="form-group required">
44
              <label for="auth-input-cc-cvv2" class="col-sm-4 control-label"><?php _e( 'Card Security Code (CVV2)', 'invoicing' ) ;?></label>
45
              <div class="col-sm-8">
46
                <input type="text" class="form-control" id="auth-input-cc-cvv2" placeholder="<?php esc_attr_e( 'Card Security Code (CVV2)', 'invoicing' ) ;?>" value="" name="authorizenet[cc_cvv2]"">
47
              </div>
48
            </div>
49
      </div>
50
    </div>
51
    <?php
52
}
53
add_action( 'wpinv_authorizenet_cc_form', 'wpinv_authorizenet_cc_form', 10, 1 );
54
55
function wpinv_process_authorizenet_payment( $purchase_data ) {
56
    if( ! wp_verify_nonce( $purchase_data['gateway_nonce'], 'wpi-gateway' ) ) {
57
        wp_die( __( 'Nonce verification has failed', 'invoicing' ), __( 'Error', 'invoicing' ), array( 'response' => 403 ) );
58
    }
59
    
60
    // Collect payment data
61
    $payment_data = array(
62
        'price'         => $purchase_data['price'],
63
        'date'          => $purchase_data['date'],
64
        'user_email'    => $purchase_data['user_email'],
65
        'invoice_key'   => $purchase_data['invoice_key'],
66
        'currency'      => wpinv_get_currency(),
67
        'items'         => $purchase_data['items'],
68
        'user_info'     => $purchase_data['user_info'],
69
        'cart_details'  => $purchase_data['cart_details'],
70
        'gateway'       => 'authorizenet',
71
        'status'        => 'wpi-pending'
72
    );
73
74
    // Record the pending payment
75
    $invoice = wpinv_get_invoice( $purchase_data['invoice_id'] );
76
77
    if ( !empty( $invoice ) ) {
78
        $authorizenet_card  = !empty( $_POST['authorizenet'] ) ? $_POST['authorizenet'] : array();
79
        $card_defaults      = array(
80
            'cc_owner'          => $invoice->get_user_full_name(),
81
            'cc_number'         => false,
82
            'cc_expire_month'   => false,
83
            'cc_expire_year'    => false,
84
            'cc_cvv2'           => false,
85
        );
86
        $authorizenet_card = wp_parse_args( $authorizenet_card, $card_defaults );
87
        
88
        if ( empty( $authorizenet_card['cc_owner'] ) ) {
89
            wpinv_set_error( 'empty_card_name', __( 'You must enter the name on your card!', 'invoicing'));
90
        }
91
        if ( empty( $authorizenet_card['cc_number'] ) ) {
92
            wpinv_set_error( 'empty_card', __( 'You must enter a card number!', 'invoicing'));
93
        }
94
        if ( empty( $authorizenet_card['cc_expire_month'] ) ) {
95
            wpinv_set_error( 'empty_month', __( 'You must enter an card expiration month!', 'invoicing'));
96
        }
97
        if ( empty( $authorizenet_card['cc_expire_year'] ) ) {
98
            wpinv_set_error( 'empty_year', __( 'You must enter an card expiration year!', 'invoicing'));
99
        }
100
        if ( empty( $authorizenet_card['cc_cvv2'] ) ) {
101
            wpinv_set_error( 'empty_cvv2', __( 'You must enter a valid CVV2!', 'invoicing' ) );
102
        }
103
104
        $errors = wpinv_get_errors();
105
106
        if ( empty( $errors ) ) {
107
            $invoice_id = $invoice->ID;
108
            $quantities_enabled = wpinv_item_quantities_enabled();
109
            $use_taxes          = wpinv_use_taxes();
110
111
            $authorizeAIM = wpinv_authorizenet_AIM();
112
            $authorizeAIM->first_name       = wpinv_utf8_substr( $invoice->get_first_name(), 0, 50 );
0 ignored issues
show
Documentation introduced by
The property first_name does not exist on object<AuthorizeNetAIM>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
113
            $authorizeAIM->last_name        = wpinv_utf8_substr( $invoice->get_last_name(), 0, 50 );
0 ignored issues
show
Documentation introduced by
The property last_name does not exist on object<AuthorizeNetAIM>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
114
            $authorizeAIM->company          = wpinv_utf8_substr( $invoice->company, 0, 50 );
0 ignored issues
show
Documentation introduced by
The property company does not exist on object<AuthorizeNetAIM>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
115
            $authorizeAIM->address          = wpinv_utf8_substr( wp_strip_all_tags( $invoice->get_address(), true ), 0, 60 );
0 ignored issues
show
Documentation introduced by
The property address does not exist on object<AuthorizeNetAIM>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
116
            $authorizeAIM->city             = wpinv_utf8_substr( $invoice->city, 0, 40 );
0 ignored issues
show
Documentation introduced by
The property city does not exist on object<AuthorizeNetAIM>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
117
            $authorizeAIM->state            = wpinv_utf8_substr( $invoice->state, 0, 40 );
0 ignored issues
show
Documentation introduced by
The property state does not exist on object<AuthorizeNetAIM>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
118
            $authorizeAIM->zip              = wpinv_utf8_substr( $invoice->zip, 0, 40 );
0 ignored issues
show
Documentation introduced by
The property zip does not exist on object<AuthorizeNetAIM>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
119
            $authorizeAIM->country          = wpinv_utf8_substr( $invoice->country, 0, 60 );
0 ignored issues
show
Documentation introduced by
The property country does not exist on object<AuthorizeNetAIM>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
120
            $authorizeAIM->phone            = wpinv_utf8_substr( $invoice->phone, 0, 25 );
0 ignored issues
show
Documentation introduced by
The property phone does not exist on object<AuthorizeNetAIM>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
121
            $authorizeAIM->email            = wpinv_utf8_substr( $invoice->get_email(), 0, 255 );
0 ignored issues
show
Documentation introduced by
The property email does not exist on object<AuthorizeNetAIM>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
122
            $authorizeAIM->amount           = wpinv_sanitize_amount( $invoice->get_total() );
0 ignored issues
show
Documentation introduced by
The property amount does not exist on object<AuthorizeNetAIM>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
123
            $authorizeAIM->card_num         = str_replace( ' ', '', sanitize_text_field( $authorizenet_card['cc_number'] ) );
0 ignored issues
show
Documentation introduced by
The property card_num does not exist on object<AuthorizeNetAIM>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
124
            $authorizeAIM->exp_date         = sanitize_text_field( $authorizenet_card['cc_expire_month'] ) . sanitize_text_field( $authorizenet_card['cc_expire_year'] );
0 ignored issues
show
Documentation introduced by
The property exp_date does not exist on object<AuthorizeNetAIM>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
125
            $authorizeAIM->card_code        = sanitize_text_field( $authorizenet_card['cc_cvv2'] );
0 ignored issues
show
Documentation introduced by
The property card_code does not exist on object<AuthorizeNetAIM>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
126
            $authorizeAIM->invoice_num      = $invoice->ID;
0 ignored issues
show
Documentation introduced by
The property invoice_num does not exist on object<AuthorizeNetAIM>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
127
128
            $item_desc = array();
129
            foreach ( $invoice->get_cart_details() as $item ) {
130
                $quantity       = $quantities_enabled && !empty( $item['quantity'] ) && $item['quantity'] > 0 ? $item['quantity'] : 1;
131
                $item_name      = wpinv_utf8_substr( $item['name'], 0, 31 );
132
                $item_desc[]    = $item_name . ' (' . $quantity . 'x ' . wpinv_price( wpinv_format_amount( $item['item_price'] ) ) . ')';
133
134
                $authorizeAIM->addLineItem( $item['id'], $item_name, '', $quantity, $item['item_price'], ( $use_taxes && !empty( $item['tax'] ) && $item['tax'] > 0 ? 'Y' : 'N' ) );
135
            }
136
137
            $item_desc = '#' . $invoice->get_number() . ': ' . implode( ', ', $item_desc );
138
139
            if ( $use_taxes && $invoice->get_tax() > 0 ) {
140
                $authorizeAIM->tax  = $invoice->get_tax();
0 ignored issues
show
Documentation introduced by
The property tax does not exist on object<AuthorizeNetAIM>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
141
142
                $item_desc .= ', ' . wp_sprintf( __( 'Tax: %s', 'invoicing' ), $invoice->get_tax( true ) );
143
            }
144
145
            if ( $invoice->get_discount() > 0 ) {
146
                $item_desc .= ', ' . wp_sprintf( __( 'Discount: %s', 'invoicing' ), $invoice->get_discount( true ) );
147
            }
148
149
            $item_description = wpinv_utf8_substr( $item_desc, 0, 255 );
0 ignored issues
show
Unused Code introduced by
$item_description 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...
150
            $item_description = html_entity_decode( $item_desc , ENT_QUOTES, 'UTF-8' );
151
152
            $authorizeAIM->description  = wpinv_utf8_substr( $item_description, 0, 255 );
0 ignored issues
show
Documentation introduced by
The property description does not exist on object<AuthorizeNetAIM>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
153
154
            $is_recurring = $invoice->is_recurring(); // Recurring payment.
155
156
            if ( $is_recurring ) {
157
                $authorizeAIM->recurring_billing = true;
0 ignored issues
show
Documentation introduced by
The property recurring_billing does not exist on object<AuthorizeNetAIM>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
158
            }
159
160
            try {
161
                if ( $is_recurring ) {
162
                    $response = $authorizeAIM->authorizeOnly();
163
                } else {
164
                    $response = $authorizeAIM->authorizeAndCapture();
165
                }
166
167
                if ( $response->approved || $response->held ) {
0 ignored issues
show
Bug introduced by
The property held does not seem to exist in AuthorizeNetARB_Response.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
168
                    if ( $response->approved ) {
0 ignored issues
show
Bug introduced by
The property approved does not seem to exist in AuthorizeNetARB_Response.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
169
                        wpinv_update_payment_status( $invoice_id, 'publish' );
170
                    }
171
                    wpinv_set_payment_transaction_id( $invoice_id, $response->transaction_id );
0 ignored issues
show
Bug introduced by
The property transaction_id does not seem to exist in AuthorizeNetARB_Response.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
172
173
                    $message = wp_sprintf( __( 'Authorize.Net Payment: %s with transaction id %s using %s and authorization code %s', 'invoicing' ), $response->response_reason_text, $response->transaction_id, strtoupper( $response->transaction_type ), $response->authorization_code );
0 ignored issues
show
Bug introduced by
The property response_reason_text does not seem to exist in AuthorizeNetARB_Response.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
Bug introduced by
The property transaction_type does not seem to exist in AuthorizeNetARB_Response.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
Bug introduced by
The property authorization_code does not seem to exist in AuthorizeNetARB_Response.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
174
175
                    wpinv_insert_payment_note( $invoice_id, $message, '', '', true );
0 ignored issues
show
Documentation introduced by
'' is of type string, 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...
176
177
                    do_action( 'wpinv_authorizenet_handle_response', $response, $invoice, $authorizenet_card );
178
179
                    wpinv_clear_errors();
180
                    wpinv_empty_cart();
181
182
                    wpinv_send_to_success_page( array( 'invoice_key' => $invoice->get_key() ) );
183
                } else {
184
                    if ( !empty( $response->response_reason_text ) ) {
185
                        $error = __( $response->response_reason_text, 'invoicing' );
186
                    } else if ( !empty( $response->error_message ) ) {
187
                        $error = __( $response->error_message, 'invoicing' );
0 ignored issues
show
Bug introduced by
The property error_message does not seem to exist in AuthorizeNetARB_Response.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
188
                    } else {
189
                        $error = wp_sprintf( __( 'Error data: %s', 'invoicing' ), print_r( $response, true ) );
190
                    }
191
192
                    $error = wp_sprintf( __( 'Authorize.Net payment error occurred. %s', 'invoicing' ), $error );
193
194
                    wpinv_set_error( 'payment_error', $error );
195
                    wpinv_record_gateway_error( $error, $response );
0 ignored issues
show
Documentation introduced by
$response is of type object<AuthorizeNetARB_Response>, but the function expects a string.

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...
196
                    wpinv_insert_payment_note( $invoice_id, $error, '', '', true );
0 ignored issues
show
Documentation introduced by
'' is of type string, 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...
197
198
                    wpinv_send_back_to_checkout( '?payment-mode=' . $purchase_data['post_data']['wpi-gateway'] );
0 ignored issues
show
Documentation introduced by
'?payment-mode=' . $purc...t_data']['wpi-gateway'] is of type string, but the function expects a array.

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...
199
                }
200
            } catch ( AuthorizeNetException $e ) {
201
                wpinv_set_error( 'request_error', $e->getMessage() );
202
                wpinv_record_gateway_error( wp_sprintf( __( 'Authorize.Net payment error occurred. %s', 'invoicing' ), $e->getMessage() ) );
203
                wpinv_send_back_to_checkout( '?payment-mode=' . $purchase_data['post_data']['wpi-gateway'] );
0 ignored issues
show
Documentation introduced by
'?payment-mode=' . $purc...t_data']['wpi-gateway'] is of type string, but the function expects a array.

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...
204
            }
205
        } else {
206
            wpinv_send_back_to_checkout( '?payment-mode=' . $purchase_data['post_data']['wpi-gateway'] );
0 ignored issues
show
Documentation introduced by
'?payment-mode=' . $purc...t_data']['wpi-gateway'] is of type string, but the function expects a array.

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...
207
        }
208
    } else {
209
        wpinv_record_gateway_error( wp_sprintf( __( 'Authorize.Net payment error occurred. Payment creation failed while processing a Authorize.net payment. Payment data: %s', 'invoicing' ), print_r( $payment_data, true ) ), $invoice );
0 ignored issues
show
Documentation introduced by
$invoice is of type object<WPInv_Invoice>, but the function expects a string.

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...
210
        wpinv_send_back_to_checkout( '?payment-mode=' . $purchase_data['post_data']['wpi-gateway'] );
0 ignored issues
show
Documentation introduced by
'?payment-mode=' . $purc...t_data']['wpi-gateway'] is of type string, but the function expects a array.

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...
211
    }
212
}
213
add_action( 'wpinv_gateway_authorizenet', 'wpinv_process_authorizenet_payment' );
214
215
function wpinv_authorizenet_cancel_subscription( $subscription = '' ) {
216
    if ( empty( $subscription->id ) ) {
217
        return false;
218
    }
219
    
220
    try {
221
        $authnetXML = wpinv_authorizenet_XML();
222
        $authnetXML->ARBCancelSubscriptionRequest( array( 'subscriptionId' => $subscription->id ) );
0 ignored issues
show
Documentation Bug introduced by
The method ARBCancelSubscriptionRequest does not exist on object<AuthnetXML>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
223
224
        if(wpinv_is_test_mode( 'authorizenet' )){
225
            return true;
226
        }
227
228
        return $authnetXML->isSuccessful();
229
    } catch( Exception $e ) {
230
        wpinv_error_log( $e->getMessage(), __( 'Authorize.Net cancel subscription', 'invoicing' ) );
231
    }
232
233
    return false;
234
}
235
add_action( 'wpinv_recurring_cancel_authorizenet_subscription', 'wpinv_authorizenet_cancel_subscription' );
236
237
function wpinv_authorizenet_valid_ipn( $md5_hash, $transaction_id, $amount ) {
238
    $authorizenet_md5_hash = wpinv_get_option( 'authorizenet_md5_hash' );
239
    if ( empty( $authorizenet_md5_hash ) ) {
240
        return true;
241
    }
242
243
    $compare_md5 = strtoupper( md5( $authorizenet_md5_hash . $transaction_id . $amount ) );
244
245
    return hash_equals( $compare_md5, $md5_hash );
246
}
247
248
function wpinv_authorizenet_AIM() {
249
    if ( !class_exists( 'AuthorizeNetException' ) ) {
250
        require_once plugin_dir_path( WPINV_PLUGIN_FILE ) . 'includes/gateways/authorizenet/anet_php_sdk/AuthorizeNet.php';
251
    }
252
253
    $authorizeAIM = new AuthorizeNetAIM( wpinv_get_option( 'authorizenet_login_id' ), wpinv_get_option( 'authorizenet_transaction_key' ) );
254
255
    if ( wpinv_is_test_mode( 'authorizenet' ) ) {
256
        $authorizeAIM->setSandbox( true );
257
    } else {
258
        $authorizeAIM->setSandbox( false );
259
    }
260
261
    $authorizeAIM->customer_ip = wpinv_get_ip();
0 ignored issues
show
Documentation introduced by
The property customer_ip does not exist on object<AuthorizeNetAIM>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
262
263
    return $authorizeAIM;
264
}
265
266
function wpinv_authorizenet_XML() {
267
    if ( !class_exists( 'AuthnetXML' ) ) {
268
        require_once plugin_dir_path( WPINV_PLUGIN_FILE ) . 'includes/gateways/authorizenet/Authorize.Net-XML/AuthnetXML.class.php';
269
    }
270
271
    $authnetXML = new AuthnetXML( wpinv_get_option( 'authorizenet_login_id' ), wpinv_get_option( 'authorizenet_transaction_key' ), (bool)wpinv_is_test_mode( 'authorizenet' ) );
0 ignored issues
show
Documentation introduced by
(bool) wpinv_is_test_mode('authorizenet') is of type boolean, but the function expects a integer.

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...
272
273
    return $authnetXML;
274
}
275
276
function wpinv_authorizenet_handle_response( $response, $invoice, $card_info = array() ) {
277
    if ( empty( $response ) || empty( $invoice ) ) {
278
        return false;
279
    }
280
281
    if ( $invoice->is_recurring() && !empty( $response->approved ) ) {
282
        $subscription = wpinv_authorizenet_create_new_subscription( $invoice, $response, $card_info );
283
        $success = false;
0 ignored issues
show
Unused Code introduced by
$success 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...
284
        if(wpinv_is_test_mode( 'authorizenet' )){
285
            $success = true;
286
        } else {
287
            $success = $subscription->isSuccessful();
288
        }
289
290
        if ( !empty( $subscription ) && $success ) {
291
            do_action( 'wpinv_recurring_post_create_subscription', $subscription, $invoice, 'authorizenet' );
292
293
            wpinv_authorizenet_subscription_record_signup( $subscription, $invoice );
294
295
            do_action( 'wpinv_recurring_post_record_signup', $subscription, $invoice, 'authorizenet' );
296
        } else {
297
            if ( isset( $subscription->messages->message ) ) {
298
                $error = $subscription->messages->message->code . ': ' . $subscription->messages->message->text;
299
                wpinv_set_error( 'wpinv_authorize_recurring_error', $error, 'invoicing' );
0 ignored issues
show
Unused Code introduced by
The call to wpinv_set_error() has too many arguments starting with 'invoicing'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
300
            } else {
301
                $error = __( 'Your subscription cannot be created due to an error.', 'invoicing' );
302
                wpinv_set_error( 'wpinv_authorize_recurring_error', $error );
303
            }
304
305
            wpinv_record_gateway_error( $error, $subscription );
306
307
            wpinv_insert_payment_note( $invoice->ID, wp_sprintf( __( 'Authorize.Net subscription error occurred. %s', 'invoicing' ), $error ), '', '', true );
0 ignored issues
show
Documentation introduced by
'' is of type string, 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...
308
        }
309
    }
310
}
311
add_action( 'wpinv_authorizenet_handle_response', 'wpinv_authorizenet_handle_response', 10, 3 );
312
313
function wpinv_authorizenet_create_new_subscription( $invoice, $response = array(), $card_info = array() ) {
314
    if ( empty( $invoice ) ) {
315
        return false;
316
    }
317
318
    $params = wpinv_authorizenet_generate_subscription_params( $invoice, $card_info, $response );
319
320
    try {
321
        $authnetXML = wpinv_authorizenet_XML();
322
        $authnetXML->ARBCreateSubscriptionRequest( $params );
0 ignored issues
show
Documentation Bug introduced by
The method ARBCreateSubscriptionRequest does not exist on object<AuthnetXML>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
323
    } catch( Exception $e ) {
324
        $authnetXML = array();
325
        wpinv_error_log( $e->getMessage(), __( 'Authorize.Net cancel subscription', 'invoicing' ) );
326
    }
327
328
    return $authnetXML;
329
}
330
331
function wpinv_authorizenet_generate_subscription_params( $invoice, $card_info = array(), $response = array() ) {
332
    if ( empty( $invoice ) ) {
333
        return false;
334
    }
335
336
    $subscription_item = $invoice->get_recurring( true );
337
    if ( !$subscription_item->ID ) {
338
        return false;
339
    }
340
341
    $card_details       = wpinv_authorizenet_generate_card_info( $card_info );
342
    $subscription_name  = $invoice->get_subscription_name();
343
    $initial_amount     = wpinv_round_amount( $invoice->get_total() );
344
    $recurring_amount   = wpinv_round_amount( $invoice->get_recurring_details( 'total' ) );
345
    $interval           = $subscription_item->get_recurring_interval();
346
    $period             = $subscription_item->get_recurring_period();
347
    $bill_times         = (int)$subscription_item->get_recurring_limit();
348
    $bill_times         = $bill_times > 0 ? $bill_times : 9999;
349
350
    $time_period        = wpinv_authorizenet_get_time_period( $interval, $period );
351
    $interval           = $time_period['interval'];
352
    $period             = $time_period['period'];
353
354
    $current_tz = date_default_timezone_get();
355
    date_default_timezone_set( 'America/Denver' ); // Set same timezone as Authorize's server (Mountain Time) to prevent conflicts.
356
    $today = date( 'Y-m-d' );
357
    date_default_timezone_set( $current_tz );
358
359
    $free_trial = $invoice->is_free_trial();
360
    if ( $free_trial && $subscription_item->has_free_trial() ) {
361
        $trial_interval    = $subscription_item->get_trial_interval();
0 ignored issues
show
Unused Code introduced by
$trial_interval 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...
362
        $trial_period      = $subscription_item->get_trial_period( true );
0 ignored issues
show
Unused Code introduced by
$trial_period 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...
363
    }
364
365
    $subscription = array();
366
    $subscription['name'] = $subscription_name;
367
368
    $subscription['paymentSchedule'] = array(
369
        'interval'         => array( 'length' => $interval, 'unit' => $period ),
370
        'startDate'        => $today,
371
        'totalOccurrences' => $bill_times,
372
        'trialOccurrences' => $free_trial || ( $initial_amount != $recurring_amount ) ? 1 : 0,
373
    );
374
375
    $subscription['amount'] = $recurring_amount;
376
    $subscription['trialAmount'] = $initial_amount;
377
    $subscription['payment'] = array( 'creditCard' => $card_details );
378
    $subscription['order'] = array( 'invoiceNumber' => $invoice->ID, 'description' => '#' . $invoice->get_number() );
379
    $subscription['customer'] = array( 'id' => $invoice->get_user_id(), 'email' => $invoice->get_email(), 'phoneNumber' => $invoice->phone );
380
381
    $subscription['billTo'] = array(
382
        'firstName' => $invoice->get_first_name(),
383
        'lastName'  => $invoice->get_last_name(),
384
        'company'   => $invoice->company,
385
        'address'   => wp_strip_all_tags( $invoice->get_address(), true ),
386
        'city'      => $invoice->city,
387
        'state'     => $invoice->state,
388
        'zip'       => $invoice->zip,
389
        'country'   => $invoice->country,
390
    );
391
392
    $params = array( 'subscription' => $subscription );
393
394
    return apply_filters( 'wpinv_authorizenet_generate_subscription_params', $params, $invoice, $card_info, $response );
395
}
396
397
function wpinv_authorizenet_generate_card_info( $card_info = array() ) {
398
    $card_defaults      = array(
399
        'cc_owner'          => null,
400
        'cc_number'         => null,
401
        'cc_expire_month'   => null,
402
        'cc_expire_year'    => null,
403
        'cc_cvv2'           => null,
404
    );
405
    $card_info = wp_parse_args( $card_info, $card_defaults );
406
407
    $card_details = array(
408
        'cardNumber'     => str_replace( ' ', '', sanitize_text_field( $card_info['cc_number'] ) ),
409
        'expirationDate' => sanitize_text_field( $card_info['cc_expire_month'] ) . sanitize_text_field( $card_info['cc_expire_year'] ),
410
        'cardCode'       => sanitize_text_field( $card_info['cc_cvv2'] ),
411
    );
412
413
    return $card_details;
414
}
415
416
function wpinv_authorizenet_subscription_record_signup( $subscription, $invoice ) {
417
    $parent_invoice_id = absint( $invoice->ID );
418
419
    if( empty( $parent_invoice_id ) ) {
420
        return;
421
    }
422
423
    $invoice = wpinv_get_invoice( $parent_invoice_id );
424
    if ( empty( $invoice ) ) {
425
        return;
426
    }
427
428
    $subscriptionId     = (array)$subscription->subscriptionId;
429
    $subscription_id    = !empty( $subscriptionId[0] ) ? $subscriptionId[0] : $parent_invoice_id;
430
431
    wpinv_insert_payment_note( $parent_invoice_id, sprintf( __( 'Authorize.Net Invoice ID: %s', 'invoicing' ) , $parent_invoice_id ), '', '', true );
0 ignored issues
show
Documentation introduced by
'' is of type string, 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...
432
    wpinv_set_payment_transaction_id( $parent_invoice_id, $subscription_id );
433
434
    $subscription = wpinv_get_authorizenet_subscription( $subscription, $parent_invoice_id );
435
436
    if ( false === $subscription ) {
437
        return;
438
    }
439
440
    // Set payment to complete
441
    wpinv_update_payment_status( $subscription->parent_payment_id, 'publish' );
442
    sleep(1);
443
    wpinv_insert_payment_note( $parent_invoice_id, sprintf( __( 'Authorize.Net Subscription ID: %s', 'invoicing' ) , $subscription_id ), '', '', true );
0 ignored issues
show
Documentation introduced by
'' is of type string, 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...
444
    update_post_meta($parent_invoice_id,'_wpinv_subscr_profile_id', $subscription_id);
445
446
    $status = 'trialling' == $subscription->status ? 'trialling' : 'active';
447
448
    // Retrieve pending subscription from database and update it's status to active and set proper profile ID
449
    $subscription->update( array( 'profile_id' => $subscription_id, 'status' => $status ) );
450
}
451
452
function wpinv_authorizenet_validate_checkout( $valid_data, $post ) {
0 ignored issues
show
Unused Code introduced by
The parameter $valid_data 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...
453
    if ( !empty( $post['wpi-gateway'] ) && $post['wpi-gateway'] == 'authorizenet' ) {
454
        $error = false;
455
456
        if ( empty( $post['authorizenet']['cc_owner'] ) ) {
457
            $error = true;
458
            wpinv_set_error( 'empty_card_name', __( 'You must enter the name on your card!', 'invoicing'));
459
        }
460
        if ( empty( $post['authorizenet']['cc_number'] ) ) {
461
            $error = true;
462
            wpinv_set_error( 'empty_card', __( 'You must enter a card number!', 'invoicing'));
463
        }
464
        if ( empty( $post['authorizenet']['cc_expire_month'] ) ) {
465
            $error = true;
466
            wpinv_set_error( 'empty_month', __( 'You must enter an card expiration month!', 'invoicing'));
467
        }
468
        if ( empty( $post['authorizenet']['cc_expire_year'] ) ) {
469
            $error = true;
470
            wpinv_set_error( 'empty_year', __( 'You must enter an card expiration year!', 'invoicing'));
471
        }
472
        if ( empty( $post['authorizenet']['cc_cvv2'] ) ) {
473
            $error = true;
474
            wpinv_set_error( 'empty_cvv2', __( 'You must enter a valid CVV2!', 'invoicing' ) );
475
        }
476
477
        if ( $error ) {
478
            return;
479
        }
480
481
        $invoice = wpinv_get_invoice_cart();
482
483
        if ( !empty( $invoice ) && $subscription_item = $invoice->get_recurring( true ) ) {
484
            $subscription_item = $invoice->get_recurring( true );
485
486
            $interval   = $subscription_item->get_recurring_interval();
487
            $period     = $subscription_item->get_recurring_period();
488
489
            if ( $period == 'D' && ( $interval < 7 || $interval > 365 ) ) {
490
                wpinv_set_error( 'authorizenet_subscription_error', __( 'Interval Length must be a value from 7 through 365 for day based subscriptions.', 'invoicing' ) );
491
            }
492
        }
493
    }
494
}
495
add_action( 'wpinv_checkout_error_checks', 'wpinv_authorizenet_validate_checkout', 11, 2 );
496
497
function wpinv_authorizenet_get_time_period( $subscription_interval, $subscription_period ) {
498
    $subscription_interval = absint( $subscription_interval );
499
500
    switch( $subscription_period ) {
501
        case 'W':
502
        case 'week':
503
        case 'weeks':
504
            $interval = $subscription_interval * 7;
505
            $period   = 'days';
506
            break;
507
        case 'M':
508
        case 'month':
509
        case 'months':
510
            if ( $subscription_interval > 12 ) {
511
                $subscription_interval = 12;
512
            }
513
514
            $interval = $subscription_interval;
515
            $period   = 'months';
516
517
            if ( !( $subscription_interval === 1 || $subscription_interval === 2 || $subscription_interval === 3 || $subscription_interval === 6 || $subscription_interval === 12 ) ) {
518
                $interval = $subscription_interval * 30;
519
                $period   = 'days';
520
            }
521
            break;
522
        case 'Y':
523
        case 'year':
524
        case 'years':
525
            $interval = 12;
526
            $period   = 'months';
527
            break;
528
        default :
529
            $interval = $subscription_interval;
530
            $period   = 'days';
531
            break;
532
    }
533
534
    return compact( 'interval', 'period' );
535
}
536
537
function wpinv_authorizenet_process_ipn() {
538
    if ( !( !empty( $_REQUEST['wpi-gateway'] ) && $_REQUEST['wpi-gateway'] == 'authorizenet' ) ) {
539
        return;
540
    }
541
542
    $subscription_id = !empty($_POST['x_subscription_id']) ? intval( $_POST['x_subscription_id'] ) : false;
543
544
    if ( $subscription_id ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $subscription_id of type integer|false is loosely compared to true; this is ambiguous if the integer can be zero. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
545
546
        $response_code  = intval( $_POST['x_response_code'] );
547
        $reason_code    = intval( $_POST['x_response_reason_code'] );
548
549
        $subscription = new WPInv_Subscription( $subscription_id, true );
550
551
        if ( !$subscription->id ) {
552
            return;
553
        }
554
555
        if ( 1 == $response_code ) {
556
557
            // Approved
558
            $transaction_id = sanitize_text_field( $_POST['x_trans_id'] );
559
            $renewal_amount = sanitize_text_field( $_POST['x_amount'] );
560
561
            $args = array(
562
                'amount'         => $renewal_amount,
563
                'transaction_id' => $transaction_id,
564
                'gateway'        => 'authorizenet'
565
            );
566
567
            $subscription->add_payment( $args );
568
            $subscription->renew();
569
570
            do_action( 'wpinv_recurring_authorizenet_silent_post_payment', $subscription );
571
            do_action( 'wpinv_authorizenet_renewal_payment', $subscription );
572
573
        } else if ( 2 == $response_code ) {
574
575
            // Declined
576
            $subscription->failing();
577
            do_action( 'wpinv_authorizenet_renewal_payment_failed', $subscription );
578
            do_action( 'wpinv_authorizenet_renewal_error', $subscription );
579
580
        } else if ( 3 == $response_code || 8 == $reason_code ) {
581
582
            // An expired card
583
            $subscription->failing();
584
            do_action( 'wpinv_authorizenet_renewal_payment_failed', $subscription );
585
            do_action( 'wpinv_authorizenet_renewal_error', $subscription );
586
587
        } else {
588
589
            // Other Error
590
            do_action( 'wpinv_authorizenet_renewal_payment_error', $subscription );
591
592
        }
593
594
        exit;
595
    }
596
}
597
add_action( 'wpinv_verify_authorizenet_ipn', 'wpinv_authorizenet_process_ipn' );
598
599
/**
600
 * Retrieve the subscription
601
 */
602
function wpinv_get_authorizenet_subscription( $subscription_data = array(), $invoice_id ) {
603
    $parent_invoice_id = absint( $invoice_id );
604
605
    if( empty( $subscription_data ) ) {
606
        return false;
607
    }
608
609
    if( empty( $parent_invoice_id ) ) {
610
        return false;
611
    }
612
613
    $invoice = wpinv_get_invoice( $parent_invoice_id );
614
    if ( empty( $invoice ) ) {
615
        return false;
616
    }
617
618
    $subscriptionId     = (array)$subscription_data->subscriptionId;
619
    $subscription_id    = !empty( $subscriptionId[0] ) ? $subscriptionId[0] : $parent_invoice_id;
620
621
    $subscription = new WPInv_Subscription( $subscription_id, true );
622
623 View Code Duplication
    if( ! $subscription || $subscription->id < 1 ) {
624
625
        $subs_db      = new WPInv_Subscriptions_DB;
626
        $subs         = $subs_db->get_subscriptions( array( 'parent_payment_id' => $parent_invoice_id, 'number' => 1 ) );
627
        $subscription = reset( $subs );
628
629
        if( $subscription && $subscription->id > 0 ) {
630
631
            // Update the profile ID so it is set for future renewals
632
            $subscription->update( array( 'profile_id' => sanitize_text_field( $subscription_id ) ) );
633
634
        } else {
635
636
            // No subscription found with a matching payment ID, bail
637
            return false;
638
639
        }
640
641
    }
642
643
    return $subscription;
644
645
}