Completed
Push — master ( cb9cb0...a2a2e1 )
by
unknown
43:00 queued 13:11
created

AuthorizeNetSIM::__construct()   C

Complexity

Conditions 8
Paths 96

Size

Total Lines 37
Code Lines 27

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 15
CRAP Score 8
Metric Value
dl 0
loc 37
ccs 15
cts 15
cp 1
rs 5.3846
cc 8
eloc 27
nc 96
nop 2
crap 8
1
<?php
2
/**
3
 * Easily use the Authorize.Net Server Integration Method(SIM).
4
 *
5
 * @package    AuthorizeNet
6
 * @subpackage AuthorizeNetSIM
7
 * @link       http://www.authorize.net/support/SIM_guide.pdf SIM Guide
8
 */
9
10
/**
11
 * Easily parse an AuthorizeNet SIM Response.
12
 * @package    AuthorizeNet
13
 * @subpackage AuthorizeNetSIM
14
 */
15
class AuthorizeNetSIM extends AuthorizeNetResponse
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
16
{
17
18
    // For ARB transactions
19
    public $subscription_id;
20
    public $subscription_paynum;
21
22
    /**
23
     * Constructor.
24
     *
25
     * @param string $api_login_id
26
     * @param string $md5_setting For verifying an Authorize.Net message.
27
     */
28 4
    public function __construct($api_login_id = false, $md5_setting = false)
0 ignored issues
show
Coding Style introduced by
__construct uses the super-global variable $_POST which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
29
    {
30 4
        $this->api_login_id = ($api_login_id ? $api_login_id : (defined('AUTHORIZENET_API_LOGIN_ID') ? AUTHORIZENET_API_LOGIN_ID : ""));
0 ignored issues
show
Bug introduced by
The property api_login_id 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...
31 4
        $this->md5_setting = ($md5_setting ? $md5_setting : (defined('AUTHORIZENET_MD5_SETTING') ? AUTHORIZENET_MD5_SETTING : ""));
0 ignored issues
show
Bug introduced by
The property md5_setting 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...
32 4
        $this->response = $_POST;
33
        
34
        // Set fields without x_ prefix
35 4
        foreach ($_POST as $key => $value) {
36 4
            $name = substr($key, 2);
37 4
            $this->$name = $value;
38
        }
39
        
40
        // Set some human readable fields
41
        $map = array(
42 4
            'invoice_number' => 'x_invoice_num',
43
            'transaction_type' => 'x_type',
44
            'zip_code' => 'x_zip',
45
            'email_address' => 'x_email',
46
            'ship_to_zip_code' => 'x_ship_to_zip',
47
            'account_number' => 'x_account_number',
48
            'avs_response' => 'x_avs_code',
49
            'authorization_code' => 'x_auth_code',
50
            'transaction_id' => 'x_trans_id',
51
            'customer_id' => 'x_cust_id',
52
            'md5_hash' => 'x_MD5_Hash',
53
            'card_code_response' => 'x_cvv2_resp_code',
54
            'cavv_response' => 'x_cavv_response',
55
        );
56 4
        foreach ($map as $key => $value) {
57 4
            $this->$key = (isset($_POST[$value]) ? $_POST[$value] : "");
58
        }
59
        
60 4
        $this->approved = ($this->response_code == self::APPROVED);
61 4
        $this->declined = ($this->response_code == self::DECLINED);
62 4
        $this->error    = ($this->response_code == self::ERROR);
63 4
        $this->held     = ($this->response_code == self::HELD);
64 4
    }
65
    
66
    /**
67
     * Verify the request is AuthorizeNet.
68
     *
69
     * @return bool
70
     */
71 1
    public function isAuthorizeNet()
0 ignored issues
show
Coding Style introduced by
isAuthorizeNet uses the super-global variable $_POST which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
72
    {
73 1
        return count($_POST) && $this->md5_hash && ($this->generateHash() == $this->md5_hash);
74
    }
75
    
76
    /**
77
     * Generates an Md5 hash to compare against Authorize.Net's.
78
     *
79
     * @return string Hash
80
     */
81 2
    public function generateHash()
82
    {
83 2
        $amount = ($this->amount ? $this->amount : "0.00");
84 2
        return strtoupper(md5($this->md5_setting . $this->api_login_id . $this->transaction_id . $amount));
85
    }
86
87
}
88
89
/**
90
 * A helper class for using hosted order page.
91
 *
92
 * @package    AuthorizeNet
93
 * @subpackage AuthorizeNetSIM
94
 */
95
class AuthorizeNetSIM_Form
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class should be in its own file to aid autoloaders.

Having each class in a dedicated file usually plays nice with PSR autoloaders and is therefore a well established practice. If you use other autoloaders, you might not want to follow this rule.

Loading history...
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
96
{
97
    public $x_address;
98
    public $x_amount;
99
    public $x_background_url;
100
    public $x_card_num;
101
    public $x_city;
102
    public $x_color_background;
103
    public $x_color_link;
104
    public $x_color_text;
105
    public $x_company;
106
    public $x_country;
107
    public $x_cust_id;
108
    public $x_customer_ip;
109
    public $x_description;
110
    public $x_delim_data;
111
    public $x_duplicate_window;
112
    public $x_duty;
113
    public $x_email;
114
    public $x_email_customer;
115
    public $x_fax;
116
    public $x_first_name;
117
    public $x_footer_email_receipt;
118
    public $x_footer_html_payment_form;
119
    public $x_footer_html_receipt;
120
    public $x_fp_hash;
121
    public $x_fp_sequence;
122
    public $x_fp_timestamp;
123
    public $x_freight;
124
    public $x_header_email_receipt;
125
    public $x_header_html_payment_form;
126
    public $x_header_html_receipt;
127
    public $x_invoice_num;
128
    public $x_last_name;
129
    public $x_line_item;
130
    public $x_login;
131
    public $x_logo_url;
132
    public $x_method;
133
    public $x_phone;
134
    public $x_po_num;
135
    public $x_receipt_link_method;
136
    public $x_receipt_link_text;
137
    public $x_receipt_link_url;
138
    public $x_recurring_billing;
139
    public $x_relay_response;
140
    public $x_relay_url;
141
    public $x_rename;
142
    public $x_ship_to_address;
143
    public $x_ship_to_company;
144
    public $x_ship_to_country;
145
    public $x_ship_to_city;
146
    public $x_ship_to_first_name;
147
    public $x_ship_to_last_name;
148
    public $x_ship_to_state;
149
    public $x_ship_to_zip;
150
    public $x_show_form;
151
    public $x_state;
152
    public $x_tax;
153
    public $x_tax_exempt;
154
    public $x_test_request;
155
    public $x_trans_id;
156
    public $x_type;
157
    public $x_version;
158
    public $x_zip;
159
    
160
    /**
161
     * Constructor
162
     *
163
     * @param array $fields Fields to set.
164
     */
165 1
    public function __construct($fields = false)
166
    {
167
        // Set some best practice fields
168 1
        $this->x_relay_response = "FALSE";
169 1
        $this->x_version = "3.1";
170 1
        $this->x_delim_char = ",";
0 ignored issues
show
Bug introduced by
The property x_delim_char 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...
171 1
        $this->x_delim_data = "TRUE";
172
        
173 1
        if ($fields) {
174 1
            foreach ($fields as $key => $value) {
175 1
                $this->$key = $value;
176
            }
177
        }
178 1
    }
179
    
180
    /**
181
     * Get a string of HTML hidden fields for use in a form.
182
     *
183
     * @return string
184
     */
185 1
    public function getHiddenFieldString()
186
    {
187 1
        $array = (array)$this;
188 1
        $string = "";
189 1
        foreach ($array as $key => $value) {
190 1
            if ($value) {
191 1
                $string .= '<input type="hidden" name="'.$key.'" value="'.$value.'">';
192
            }
193
        }
194 1
        return $string;
195
    }
196
    
197
    /**
198
     * Generates a fingerprint needed for a hosted order form or DPM.
199
     *
200
     * @param string $api_login_id    Login ID.
201
     * @param string $transaction_key API key.
202
     * @param string $amount          Amount of transaction.
203
     * @param string $fp_sequence     An invoice number or random number.
204
     * @param string $fp_timestamp    Timestamp.
205
     *
206
     * @return string The fingerprint.
207
     */
208 2
    public static function getFingerprint($api_login_id, $transaction_key, $amount, $fp_sequence, $fp_timestamp)
209
    {
210 2
        $api_login_id = ($api_login_id ? $api_login_id : (defined('AUTHORIZENET_API_LOGIN_ID') ? AUTHORIZENET_API_LOGIN_ID : ""));
211 2
        $transaction_key = ($transaction_key ? $transaction_key : (defined('AUTHORIZENET_TRANSACTION_KEY') ? AUTHORIZENET_TRANSACTION_KEY : ""));
212 2
        if (function_exists('hash_hmac')) {
213 2
            return hash_hmac("md5", $api_login_id . "^" . $fp_sequence . "^" . $fp_timestamp . "^" . $amount . "^", $transaction_key); 
214
        }
215
        return bin2hex(mhash(MHASH_MD5, $api_login_id . "^" . $fp_sequence . "^" . $fp_timestamp . "^" . $amount . "^", $transaction_key));
216
    }
217
    
218
}