Completed
Branch master (a35590)
by Anton
04:28 queued 01:35
created

ValidatorV1::validate()   D

Complexity

Conditions 28
Paths 16

Size

Total Lines 101
Code Lines 65

Duplication

Lines 27
Ratio 26.73 %

Importance

Changes 0
Metric Value
dl 27
loc 101
c 0
b 0
f 0
rs 4.4803
cc 28
eloc 65
nc 16
nop 1

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace Covery\Client\Envelopes;
4
5
use Covery\Client\EnvelopeInterface;
6
use Covery\Client\EnvelopeValidationException;
7
8
class ValidatorV1
9
{
10
    private static $dataTypes = array(
11
        'billing_address' => 'string',
12
        'billing_city' => 'string',
13
        'billing_country' => 'string',
14
        'billing_firstname' => 'string',
15
        'billing_lastname' => 'string',
16
        'billing_fullname' => 'string',
17
        'billing_state' => 'string',
18
        'billing_zip' => 'string',
19
        'card_id' => 'string',
20
        'card_last4' => 'string',
21
        'country' => 'string',
22
        'cpu_class' => 'string',
23
        'device_fingerprint' => 'string',
24
        'firstname' => 'string',
25
        'gender' => 'string',
26
        'language' => 'string',
27
        'language_browser' => 'string',
28
        'language_system' => 'string',
29
        'language_user' => 'string',
30
        'languages' => 'string',
31
        'lastname' => 'string',
32
        'login_user_agent' => 'string',
33
        'os' => 'string',
34
        'payment_method' => 'string',
35
        'payment_mid' => 'string',
36
        'payment_system' => 'string',
37
        'product_description' => 'string',
38
        'product_name' => 'string',
39
        'registration_useragent' => 'string',
40
        'screen_orientation' => 'string',
41
        'screen_resolution' => 'string',
42
        'social_type' => 'string',
43
        'transaction_currency' => 'string',
44
        'transaction_id' => 'string',
45
        'transaction_mode' => 'string',
46
        'transaction_type' => 'string',
47
        'user_agent' => 'string',
48
        'user_merchant_id' => 'string',
49
        'user_name' => 'string',
50
        'website_url' => 'string',
51
        'transaction_source' => 'string',
52
        'ip' => 'string',
53
        'merchant_ip' => 'string',
54
        'real_ip' => 'string',
55
        'email' => 'string',
56
        'phone' => 'string',
57
        'age' => 'int',
58
        'card_bin' => 'int',
59
        'confirmation_timestamp' => 'int',
60
        'expiration_month' => 'int',
61
        'expiration_year' => 'int',
62
        'login_timestamp' => 'int',
63
        'registration_timestamp' => 'int',
64
        'timezone_offset' => 'int',
65
        'transaction_timestamp' => 'int',
66
        'product_quantity' => 'float',
67
        'transaction_amount' => 'float',
68
        'transaction_amount_converted' => 'float',
69
        'ajax_validation' => 'bool',
70
        'cookie_enabled' => 'bool',
71
        'do_not_track' => 'bool',
72
        'email_confirmed' => 'bool',
73
        'login_failed' => 'bool',
74
        'phone_confirmed' => 'bool',
75
    );
76
77
    private static $types = array(
78
        'confirmation' => array(
79
            'mandatory' => array('confirmation_timestamp', 'user_merchant_id'),
80
            'optional' => array('email_confirmed', 'phone_confirmed'),
81
        ),
82
        'login' => array(
83
            'mandatory' => array('login_timestamp', 'user_merchant_id'),
84
            'optional' => array('email', 'login_failed', 'phone')
85
        ),
86
        'registration' => array(
87
            'mandatory' => array('registration_timestamp', 'user_merchant_id'),
88
            'optional' => array(
89
                'age',
90
                'country',
91
                'email',
92
                'firstname',
93
                'gender',
94
                'lastname',
95
                'phone',
96
                'social_type',
97
                'user_name',
98
            ),
99
        ),
100
        'transaction' => array(
101
            'mandatory' => array(
102
                'transaction_amount',
103
                'transaction_currency',
104
                'transaction_id',
105
                'transaction_mode',
106
                'transaction_timestamp',
107
                'transaction_type',
108
                'card_bin',
109
                'card_id',
110
                'card_last4',
111
                'expiration_month',
112
                'expiration_year',
113
                'user_merchant_id',
114
            ),
115
            'optional' => array(
116
                'age',
117
                'country',
118
                'email',
119
                'firstname',
120
                'gender',
121
                'lastname',
122
                'phone',
123
                'user_name',
124
                'payment_method',
125
                'payment_mid',
126
                'payment_system',
127
                'transaction_amount_converted',
128
                'transaction_source',
129
                'billing_address',
130
                'billing_city',
131
                'billing_country',
132
                'billing_firstname',
133
                'billing_lastname',
134
                'billing_fullname',
135
                'billing_state',
136
                'billing_zip',
137
                'product_description',
138
                'product_name',
139
                'product_quantity',
140
                'website_url',
141
                'merchant_ip',
142
            )
143
        ),
144
    );
145
146
    /**
147
     * Checks envelope validity and throws an exception on error
148
     *
149
     * @param EnvelopeInterface $envelope
150
     * @throws EnvelopeValidationException
151
     */
152
    public function validate(EnvelopeInterface $envelope)
153
    {
154
        $details = [];
155
156
        // Checking sequenceId
157
        if (strlen($envelope->getSequenceId()) < 6 || strlen($envelope->getSequenceId()) > 40) {
158
            $details[] = sprintf(
159
                'Invalid SequenceID length. It must be in range [6, 40], but %d received.',
160
                strlen($envelope->getSequenceId())
161
            );
162
        }
163
164
        // Checking identity nodes
165
        if (count($envelope->getIdentities()) === 0) {
166
            $details[] = 'At least one Identity must be supplied';
167
        }
168
169
        // Checking envelope type
170
        if (!isset(self::$types[$envelope->getType()])) {
171
            $details[] = sprintf('Envelope type "%s" not supported by this client version', $envelope->getType());
172
        } else {
173
            $typeInfo = self::$types[$envelope->getType()];
174
            // Mandatory fields check
175
            foreach ($typeInfo['mandatory'] as $name) {
176
                if (!isset($envelope[$name]) || empty($envelope[$name])) {
177
                    $details[] = sprintf(
178
                        'Field "%s" is mandatory for "%s", but not provided',
179
                        $name,
180
                        $envelope->getType()
181
                    );
182
                }
183
            }
184
185
            // Per field check
186
            $fields = array_merge($typeInfo['mandatory'], $typeInfo['optional']);
187
            $customCount = 0;
188
            foreach ($envelope as $key => $value) {
189
                // Is custom?
190
                if (strlen($key) >= 7 && substr($key, 0, 7) === 'custom_') {
191
                    $customCount++;
192
                    if (!is_string($value)) {
193
                        $details[] = sprintf(
194
                            'All custom values must be string, but for "%s" %s was provided',
195
                            $key,
196
                            $value === null ? 'null' : gettype($value)
197
                        );
198
                    }
199
                } else {
200
                    if (!in_array($key, $fields)) {
201
                        $details[] = sprintf('Field "%s" not found in "%s"', $key, $envelope->getType());
202
                    } else {
203
                        // Checking type
204
                        switch (self::$dataTypes[$key]) {
205
                            case 'string':
206
                                if (!is_string($value)) {
207
                                    $details[] = sprintf(
208
                                        'Field "%s" must be string, but %s provided',
209
                                        $key,
210
                                        $value === null ? 'null' : gettype($value)
211
                                    );
212
                                }
213
                                break;
214 View Code Duplication
                            case 'int':
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
215
                                if (!is_int($value)) {
216
                                    $details[] = sprintf(
217
                                        'Field "%s" must be int, but %s provided',
218
                                        $key,
219
                                        $value === null ? 'null' : gettype($value)
220
                                    );
221
                                }
222
                                break;
223 View Code Duplication
                            case 'float':
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
224
                                if (!is_float($value) && !is_int($value)) {
225
                                    $details[] = sprintf(
226
                                        'Field "%s" must be float/double, but %s provided',
227
                                        $key,
228
                                        $value === null ? 'null' : gettype($value)
229
                                    );
230
                                }
231
                                break;
232 View Code Duplication
                            case 'bool':
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
233
                                if (!is_bool($value)) {
234
                                    $details[] = sprintf(
235
                                        'Field "%s" must be boolean, but %s provided',
236
                                        $key,
237
                                        $value === null ? 'null' : gettype($value)
238
                                    );
239
                                }
240
                                break;
241
                            default:
242
                                $details[] = sprintf('Unknown type for "%s"', $key);
243
                        }
244
                    }
245
                }
246
            }
247
        }
248
249
        if (count($details) > 0) {
250
            throw new EnvelopeValidationException($details);
251
        }
252
    }
253
}
254