Completed
Push — master ( 1f45e9...809a75 )
by recca
08:05
created

ECPay_AioCapture   A

Complexity

Total Complexity 3

Size/Duplication

Total Lines 29
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 2

Importance

Changes 0
Metric Value
wmc 3
lcom 0
cbo 2
dl 0
loc 29
rs 10
c 0
b 0
f 0

1 Method

Rating   Name   Duplication   Size   Complexity  
B Capture() 0 26 3
1
<?php
2
3
/**
4
 * 付款方式。
5
 */
6
abstract class ECPay_PaymentMethod {
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...
7
8
    /**
9
     * 不指定付款方式。
10
     */
11
    const ALL = 'ALL';
12
13
    /**
14
     * 信用卡付費。
15
     */
16
    const Credit = 'Credit';
17
18
    /**
19
     * 網路 ATM。
20
     */
21
    const WebATM = 'WebATM';
22
23
    /**
24
     * 自動櫃員機。
25
     */
26
    const ATM = 'ATM';
27
28
    /**
29
     * 超商代碼。
30
     */
31
    const CVS = 'CVS';
32
33
    /**
34
     * 超商條碼。
35
     */
36
    const BARCODE = 'BARCODE';
37
38
}
39
40
/**
41
 * 付款方式子項目。
42
 */
43
abstract class ECPay_PaymentMethodItem {
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...
44
45
    /**
46
     * 不指定。
47
     */
48
    const None = '';
49
    // WebATM 類(001~100)
0 ignored issues
show
Unused Code Comprehensibility introduced by
45% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
50
    /**
51
     * 台新銀行。
52
     */
53
    const WebATM_TAISHIN = 'TAISHIN';
54
55
    /**
56
     * 玉山銀行。
57
     */
58
    const WebATM_ESUN = 'ESUN';
59
60
    /**
61
     * 華南銀行。
62
     */
63
    const WebATM_HUANAN = 'HUANAN';
64
65
    /**
66
     * 台灣銀行。
67
     */
68
    const WebATM_BOT = 'BOT';
69
70
    /**
71
     * 台北富邦。
72
     */
73
    const WebATM_FUBON = 'FUBON';
74
75
    /**
76
     * 中國信託。
77
     */
78
    const WebATM_CHINATRUST = 'CHINATRUST';
79
80
    /**
81
     * 第一銀行。
82
     */
83
    const WebATM_FIRST = 'FIRST';
84
85
    /**
86
     * 國泰世華。
87
     */
88
    const WebATM_CATHAY = 'CATHAY';
89
90
    /**
91
     * 兆豐銀行。
92
     */
93
    const WebATM_MEGA = 'MEGA';
94
95
    /**
96
     * 元大銀行。
97
     */
98
    const WebATM_YUANTA = 'YUANTA';
99
100
    /**
101
     * 土地銀行。
102
     */
103
    const WebATM_LAND = 'LAND';
104
    // ATM 類(101~200)
0 ignored issues
show
Unused Code Comprehensibility introduced by
45% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
105
    /**
106
     * 台新銀行。
107
     */
108
    const ATM_TAISHIN = 'TAISHIN';
109
110
    /**
111
     * 玉山銀行。
112
     */
113
    const ATM_ESUN = 'ESUN';
114
115
    /**
116
     * 華南銀行。
117
     */
118
    const ATM_HUANAN = 'HUANAN';
119
120
    /**
121
     * 台灣銀行。
122
     */
123
    const ATM_BOT = 'BOT';
124
125
    /**
126
     * 台北富邦。
127
     */
128
    const ATM_FUBON = 'FUBON';
129
130
    /**
131
     * 中國信託。
132
     */
133
    const ATM_CHINATRUST = 'CHINATRUST';
134
135
    /**
136
     * 土地銀行。
137
     */
138
    const ATM_LAND = 'LAND';
139
140
    /**
141
     * 國泰世華銀行。
142
     */
143
    const ATM_CATHAY = 'CATHAY';
144
145
    /**
146
     * 大眾銀行。
147
     */
148
    const ATM_Tachong = 'Tachong';
149
150
    /**
151
     * 永豐銀行。
152
     */
153
    const ATM_Sinopac = 'Sinopac';
154
155
    /**
156
     * 彰化銀行。
157
     */
158
    const ATM_CHB = 'CHB';
159
160
    /**
161
     * 第一銀行。
162
     */
163
    const ATM_FIRST = 'FIRST';
164
165
    // 超商類(201~300)
0 ignored issues
show
Unused Code Comprehensibility introduced by
58% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
166
    /**
167
     * 超商代碼繳款。
168
     */
169
    const CVS = 'CVS';
170
171
    /**
172
     * OK超商代碼繳款。
173
     */
174
    const CVS_OK = 'OK';
175
176
    /**
177
     * 全家超商代碼繳款。
178
     */
179
    const CVS_FAMILY = 'FAMILY';
180
181
    /**
182
     * 萊爾富超商代碼繳款。
183
     */
184
    const CVS_HILIFE = 'HILIFE';
185
186
    /**
187
     * 7-11 ibon代碼繳款。
188
     */
189
    const CVS_IBON = 'IBON';
190
191
    // 其他類(901~999)
0 ignored issues
show
Unused Code Comprehensibility introduced by
58% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
192
    /**
193
     * 超商條碼繳款。
194
     */
195
    const BARCODE = 'BARCODE';
196
197
    /**
198
     * 信用卡(MasterCard/JCB/VISA)。
199
     */
200
    const Credit = 'Credit';
201
202
    /**
203
     * 貨到付款。
204
     */
205
    const COD = 'COD';
206
207
}
208
209
/**
210
 * 額外付款資訊。
211
 */
212
abstract class ECPay_ExtraPaymentInfo {
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...
213
214
    /**
215
     * 需要額外付款資訊。
216
     */
217
    const Yes = 'Y';
218
219
    /**
220
     * 不需要額外付款資訊。
221
     */
222
    const No = 'N';
223
224
}
225
226
/**
227
 * 額外付款資訊。
228
 */
229
abstract class ECPay_DeviceType {
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...
230
231
    /**
232
     * 桌機版付費頁面。
233
     */
234
    const PC = 'P';
235
236
    /**
237
     * 行動裝置版付費頁面。
238
     */
239
    const Mobile = 'M';
240
241
}
242
243
/**
244
 * 信用卡訂單處理動作資訊。
245
 */
246
abstract class ECPay_ActionType {
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...
247
248
    /**
249
     * 關帳
250
     */
251
    const C = 'C';
252
253
    /**
254
     * 退刷
255
     */
256
    const R = 'R';
257
258
    /**
259
     * 取消
260
     */
261
    const E = 'E';
262
263
    /**
264
     * 放棄
265
     */
266
    const N = 'N';
267
268
}
269
270
/**
271
 * 定期定額的週期種類。
272
 */
273
abstract class ECPay_PeriodType {
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...
274
275
    /**
276
     * 無
277
     */
278
    const None = '';
279
280
    /**
281
     * 年
282
     */
283
    const Year = 'Y';
284
285
    /**
286
     * 月
287
     */
288
    const Month = 'M';
289
290
    /**
291
     * 日
292
     */
293
    const Day = 'D';
294
295
}
296
297
/**
298
 * 電子發票開立註記。
299
 */
300
abstract class ECPay_InvoiceState {
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...
301
    /**
302
     * 需要開立電子發票。
303
     */
304
    const Yes = 'Y';
305
306
    /**
307
     * 不需要開立電子發票。
308
     */
309
    const No = '';
310
}
311
312
/**
313
 * 電子發票載具類別
314
 */
315
abstract class ECPay_CarrierType {
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...
316
  // 無載具
317
  const None = '';
318
319
  // 會員載具
320
  const Member = '1';
321
322
  // 買受人自然人憑證
323
  const Citizen = '2';
324
325
  // 買受人手機條碼
326
  const Cellphone = '3';
327
}
328
329
/**
330
 * 電子發票列印註記
331
 */
332
abstract class ECPay_PrintMark {
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...
333
  // 不列印
334
  const No = '0';
335
336
  // 列印
337
  const Yes = '1';
338
}
339
340
/**
341
 * 電子發票捐贈註記
342
 */
343
abstract class ECPay_Donation {
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...
344
  // 捐贈
345
  const Yes = '1';
346
347
  // 不捐贈
348
  const No = '2';
349
}
350
351
/**
352
 * 通關方式
353
 */
354
abstract class ECPay_ClearanceMark {
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...
355
  // 經海關出口
356
  const Yes = '1';
357
358
  // 非經海關出口
359
  const No = '2';
360
}
361
362
/**
363
 * 課稅類別
364
 */
365
abstract class ECPay_TaxType {
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...
366
  // 應稅
367
  const Dutiable = '1';
368
369
  // 零稅率
370
  const Zero = '2';
371
372
  // 免稅
373
  const Free = '3';
374
375
  // 應稅與免稅混合(限收銀機發票無法分辦時使用,且需通過申請核可)
376
  const Mix = '9';
377
}
378
379
/**
380
 * 字軌類別
381
 */
382
abstract class ECPay_InvType {
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...
383
  // 一般稅額
384
  const General = '07';
385
386
  // 特種稅額
387
  const Special = '08';
388
}
389
390
abstract class ECPay_EncryptType {
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...
391
    // MD5(預設)
392
    const ENC_MD5 = 0;
393
394
    // SHA256
395
    const ENC_SHA256 = 1;
396
}
397
398
/**
399
 * AllInOne short summary.
400
 *
401
 * AllInOne description.
402
 *
403
 * @version 1.1.0818
404
 * @author charlie
405
 */
406
407
408
class ECPay_AllInOne {
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...
409
410
    public $ServiceURL = 'ServiceURL';
411
    public $ServiceMethod = 'ServiceMethod';
412
    public $HashKey = 'HashKey';
413
    public $HashIV = 'HashIV';
414
    public $MerchantID = 'MerchantID';
415
    public $PaymentType = 'PaymentType';
416
    public $Send = 'Send';
417
    public $SendExtend = 'SendExtend';
418
    public $Query = 'Query';
419
    public $Action = 'Action';
420
    public $EncryptType = ECPay_EncryptType::ENC_MD5;
421
422
    function __construct() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

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

Loading history...
423
424
        $this->PaymentType = 'aio';
425
        $this->Send = array(
0 ignored issues
show
Documentation Bug introduced by
It seems like array('ReturnURL' => '',...y_EncryptType::ENC_MD5) of type array<string,string|arra...ring","Items":"array"}> is incompatible with the declared type string of property $Send.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
426
            "ReturnURL"         => '',
427
            "ClientBackURL"     => '',
428
            "OrderResultURL"    => '',
429
            "MerchantTradeNo"   => '',
430
            "MerchantTradeDate" => '',
431
            "PaymentType"       => 'aio',
432
            "TotalAmount"       => '',
433
            "TradeDesc"         => '',
434
            "ChoosePayment"     => ECPay_PaymentMethod::ALL,
435
            "Remark"            => '',
436
            "ChooseSubPayment"  => ECPay_PaymentMethodItem::None,
437
            "NeedExtraPaidInfo" => ECPay_ExtraPaymentInfo::No,
438
            "DeviceSource"      => '',
439
            "IgnorePayment"     => '',
440
            "PlatformID"        => '',
441
            "InvoiceMark"       => ECPay_InvoiceState::No,
442
            "Items"             => array(),
443
            "EncryptType"       => ECPay_EncryptType::ENC_MD5
444
        );
445
446
        $this->SendExtend = array();
0 ignored issues
show
Documentation Bug introduced by
It seems like array() of type array is incompatible with the declared type string of property $SendExtend.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
447
448
        $this->Query = array(
0 ignored issues
show
Documentation Bug introduced by
It seems like array('MerchantTradeNo' => '', 'TimeStamp' => '') of type array<string,string,{"Me...,"TimeStamp":"string"}> is incompatible with the declared type string of property $Query.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
449
            'MerchantTradeNo' => '', 'TimeStamp' => ''
450
        );
451
        $this->Action = Array(
0 ignored issues
show
Documentation Bug introduced by
It seems like array('MerchantTradeNo' ...:C, 'TotalAmount' => 0) of type array<string,string|inte...otalAmount":"integer"}> is incompatible with the declared type string of property $Action.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
452
            'MerchantTradeNo' => '', 'TradeNo' => '', 'Action' => ECPay_ActionType::C, 'TotalAmount' => 0
453
        );
454
        $this->Capture = array();
0 ignored issues
show
Bug introduced by
The property Capture 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...
455
456
    }
457
458
    //產生訂單
459
    function CheckOut($target = "_self") {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

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

Loading history...
460
        $arParameters = array_merge( array('MerchantID' => $this->MerchantID) ,$this->Send);
461
        ECPay_Send::CheckOut($target,$arParameters,$this->SendExtend,$this->HashKey,$this->HashIV,$this->ServiceURL);
0 ignored issues
show
Documentation introduced by
$this->SendExtend 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...
462
    }
463
464
    //產生訂單html code
465
    function CheckOutString($paymentButton = null, $target = "_self") {
0 ignored issues
show
Unused Code introduced by
The parameter $target 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...
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

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

Loading history...
466
        $arParameters = array_merge( array('MerchantID' => $this->MerchantID) ,$this->Send);
467
        return ECPay_Send::CheckOutString($paymentButton,$target = "_self",$arParameters,$this->SendExtend,$this->HashKey,$this->HashIV,$this->ServiceURL);
0 ignored issues
show
Documentation introduced by
$this->SendExtend 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...
468
    }
469
470
    //取得付款結果通知的方法
471
    function CheckOutFeedback() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

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

Loading history...
Coding Style introduced by
CheckOutFeedback 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...
472
        return $arFeedback = ECPay_CheckOutFeedback::CheckOut($_POST,$this->HashKey,$this->HashIV,0);
0 ignored issues
show
Unused Code introduced by
The call to ECPay_CheckOutFeedback::CheckOut() has too many arguments starting with 0.

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...
Unused Code introduced by
$arFeedback 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...
473
    }
474
475
    //訂單查詢作業
476
    function QueryTradeInfo() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

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

Loading history...
477
        return $arFeedback = ECPay_QueryTradeInfo::CheckOut(array_merge($this->Query,array("MerchantID" => $this->MerchantID)) ,$this->HashKey ,$this->HashIV ,$this->ServiceURL) ;
0 ignored issues
show
Unused Code introduced by
$arFeedback 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...
478
    }
479
480
    //信用卡定期定額訂單查詢的方法
481
    function QueryPeriodCreditCardTradeInfo() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

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

Loading history...
482
        return $arFeedback = ECPay_QueryPeriodCreditCardTradeInfo::CheckOut(array_merge($this->Query,array("MerchantID" => $this->MerchantID)) ,$this->HashKey ,$this->HashIV ,$this->ServiceURL);
0 ignored issues
show
Unused Code introduced by
$arFeedback 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...
483
    }
484
485
    //信用卡關帳/退刷/取消/放棄的方法
486
    function DoAction() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

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

Loading history...
487
        return $arFeedback = ECPay_DoAction::CheckOut(array_merge($this->Action,array("MerchantID" => $this->MerchantID)) ,$this->HashKey ,$this->HashIV ,$this->ServiceURL);
0 ignored issues
show
Unused Code introduced by
$arFeedback 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...
488
    }
489
490
    //合作特店申請撥款
491
	function AioCapture(){
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

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

Loading history...
492
        return $arFeedback = ECPay_AioCapture::Capture(array_merge($this->Capture,array("MerchantID" => $this->MerchantID)) ,$this->HashKey ,$this->HashIV ,$this->ServiceURL);
0 ignored issues
show
Unused Code introduced by
$arFeedback 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...
493
    }
494
495
496
497
498
}
499
500
/**
501
* 抽象類
502
*/
503
abstract class ECPay_Aio
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...
504
{
505
506
    protected static function ServerPost($parameters ,$ServiceURL) {
507
        $ch = curl_init();
508
509
		if (FALSE === $ch) {
510
			throw new Exception('curl failed to initialize');
511
		}
512
513
        curl_setopt($ch, CURLOPT_URL, $ServiceURL);
514
        curl_setopt($ch, CURLOPT_HEADER, FALSE);
515
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
516
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, TRUE);
517
        curl_setopt($ch, CURLOPT_POST, TRUE);
518
        curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($parameters));
519
        $rs = curl_exec($ch);
520
521
		if (FALSE === $rs) {
522
			throw new Exception(curl_error($ch), curl_errno($ch));
523
		}
524
525
        curl_close($ch);
526
527
        return $rs;
528
    }
529
530
}
531
532
/**
533
*  產生訂單
534
*/
535
class ECPay_Send extends ECPay_Aio
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...
536
{
537
    //付款方式物件
538
    public static $PaymentObj ;
539
540
    protected static function process($arParameters = array(),$arExtend = array())
541
    {
542
        //宣告付款方式物件
543
        $PaymentMethod    = 'ECPay_'.$arParameters['ChoosePayment'];
544
        self::$PaymentObj = new $PaymentMethod;
545
546
        //檢查參數
547
        $arParameters = self::$PaymentObj->check_string($arParameters);
548
549
        //檢查商品
550
        $arParameters = self::$PaymentObj->check_goods($arParameters);
551
552
        //檢查各付款方式的額外參數&電子發票參數
553
        $arExtend = self::$PaymentObj->check_extend_string($arExtend,$arParameters['InvoiceMark']);
554
555
        //過濾
556
        $arExtend = self::$PaymentObj->filter_string($arExtend,$arParameters['InvoiceMark']);
557
558
        //合併共同參數及延伸參數
559
        return array_merge($arParameters,$arExtend) ;
560
    }
561
562
563 View Code Duplication
    static function CheckOut($target = "_self",$arParameters = array(),$arExtend = array(),$HashKey='',$HashIV='',$ServiceURL=''){
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

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

Loading history...
Duplication introduced by
This method seems to be duplicated in your project.

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

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

Loading history...
564
565
        $arParameters = self::process($arParameters,$arExtend);
566
        //產生檢查碼
567
        $szCheckMacValue = ECPay_CheckMacValue::generate($arParameters,$HashKey,$HashIV,$arParameters['EncryptType']);
568
569
        //生成表單,自動送出
570
        $szHtml =  '<!DOCTYPE html>';
571
        $szHtml .= '<html>';
572
        $szHtml .=     '<head>';
573
        $szHtml .=         '<meta charset="utf-8">';
574
        $szHtml .=     '</head>';
575
        $szHtml .=     '<body>';
576
        $szHtml .=         "<form id=\"__ecpayForm\" method=\"post\" target=\"{$target}\" action=\"{$ServiceURL}\">";
577
578
        foreach ($arParameters as $keys => $value) {
579
            $szHtml .=         "<input type=\"hidden\" name=\"{$keys}\" value='{$value}' />";
580
        }
581
582
        $szHtml .=             "<input type=\"hidden\" name=\"CheckMacValue\" value=\"{$szCheckMacValue}\" />";
583
        $szHtml .=         '</form>';
584
        $szHtml .=         '<script type="text/javascript">document.getElementById("__ecpayForm").submit();</script>';
585
        $szHtml .=     '</body>';
586
        $szHtml .= '</html>';
587
588
        echo $szHtml ;
589
        exit;
0 ignored issues
show
Coding Style Compatibility introduced by
The method CheckOut() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
590
    }
591
592 View Code Duplication
    static function CheckOutString($paymentButton,$target = "_self",$arParameters = array(),$arExtend = array(),$HashKey='',$HashIV='',$ServiceURL=''){
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

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

Loading history...
Duplication introduced by
This method seems to be duplicated in your project.

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

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

Loading history...
593
594
        $arParameters = self::process($arParameters,$arExtend);
595
        //產生檢查碼
596
        $szCheckMacValue = ECPay_CheckMacValue::generate($arParameters,$HashKey,$HashIV,$arParameters['EncryptType']);
597
598
        $szHtml =  '<!DOCTYPE html>';
599
        $szHtml .= '<html>';
600
        $szHtml .=     '<head>';
601
        $szHtml .=         '<meta charset="utf-8">';
602
        $szHtml .=     '</head>';
603
        $szHtml .=     '<body>';
604
        $szHtml .=         "<form id=\"__ecpayForm\" method=\"post\" target=\"{$target}\" action=\"{$ServiceURL}\">";
605
606
        foreach ($arParameters as $keys => $value) {
607
            $szHtml .=         "<input type=\"hidden\" name=\"{$keys}\" value='{$value}' />";
608
        }
609
610
        $szHtml .=             "<input type=\"hidden\" name=\"CheckMacValue\" value=\"{$szCheckMacValue}\" />";
611
        $szHtml .=             "<input type=\"submit\" id=\"__paymentButton\" value=\"{$paymentButton}\" />";
612
        $szHtml .=         '</form>';
613
        $szHtml .=     '</body>';
614
        $szHtml .= '</html>';
615
        return  $szHtml ;
616
    }
617
618
}
619
620
621
class ECPay_CheckOutFeedback extends ECPay_Aio
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...
622
{
623
    static function CheckOut($arParameters = array(),$HashKey = '' ,$HashIV = ''){
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

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

Loading history...
624
        // 變數宣告。
625
        $arErrors = array();
626
        $arFeedback = array();
627
        $szCheckMacValue = '';
0 ignored issues
show
Unused Code introduced by
$szCheckMacValue 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...
628
        // 重新整理回傳參數。
629
        foreach ($arParameters as $keys => $value) {
630
            if ($keys != 'CheckMacValue') {
631
                if ($keys == 'PaymentType') {
632
                    $value = str_replace('_CVS', '', $value);
633
                    $value = str_replace('_BARCODE', '', $value);
634
                    $value = str_replace('_CreditCard', '', $value);
635
                }
636
                if ($keys == 'PeriodType') {
637
                    $value = str_replace('Y', 'Year', $value);
638
                    $value = str_replace('M', 'Month', $value);
639
                    $value = str_replace('D', 'Day', $value);
640
                }
641
                $arFeedback[$keys] = $value;
642
            }
643
        }
644
645
        $CheckMacValue = ECPay_CheckMacValue::generate($arParameters,$HashKey,$HashIV,0);
646
647
        if ($CheckMacValue != $arParameters['CheckMacValue']) {
648
            array_push($arErrors, 'CheckMacValue verify fail.');
649
        }
650
651
        if (sizeof($arErrors) > 0) {
652
            throw new Exception(join('- ', $arErrors));
653
        }
654
655
        return $arFeedback;
656
    }
657
}
658
659
660
class ECPay_QueryTradeInfo extends ECPay_Aio
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...
661
{
662
    static function CheckOut($arParameters = array(),$HashKey ='',$HashIV ='',$ServiceURL = ''){
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

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

Loading history...
663
        $arErrors = array();
664
        $arParameters['TimeStamp'] = time();
665
        $arFeedback = array();
666
        $arConfirmArgs = array();
667
        // 呼叫查詢。
668
        if (sizeof($arErrors) == 0) {
669
            $arParameters["CheckMacValue"] = ECPay_CheckMacValue::generate($arParameters,$HashKey,$HashIV,0);
670
            // 送出查詢並取回結果。
671
            $szResult = parent::ServerPost($arParameters,$ServiceURL);
0 ignored issues
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (ServerPost() instead of CheckOut()). Are you sure this is correct? If so, you might want to change this to $this->ServerPost().

This check looks for a call to a parent method whose name is different than the method from which it is called.

Consider the following code:

class Daddy
{
    protected function getFirstName()
    {
        return "Eidur";
    }

    protected function getSurName()
    {
        return "Gudjohnsen";
    }
}

class Son
{
    public function getFirstName()
    {
        return parent::getSurname();
    }
}

The getFirstName() method in the Son calls the wrong method in the parent class.

Loading history...
672
            $szResult = str_replace(' ', '%20', $szResult);
673
            $szResult = str_replace('+', '%2B', $szResult);
674
675
            // 轉結果為陣列。
676
            parse_str($szResult, $arParameters);
677
            // 重新整理回傳參數。
678
            foreach ($arParameters as $keys => $value) {
0 ignored issues
show
Bug introduced by
The expression $arParameters of type null|array is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
679
                if ($keys == 'CheckMacValue') {
680
                    $szCheckMacValue = $value;
681
                } else {
682
                    $arFeedback[$keys] = $value;
683
                    $arConfirmArgs[$keys] = $value;
684
                }
685
            }
686
687
            // 驗證檢查碼。
688
            if (sizeof($arFeedback) > 0) {
689
                $szConfirmMacValue = ECPay_CheckMacValue::generate($arConfirmArgs,$HashKey,$HashIV,0);
690
                if ($szCheckMacValue != $szConfirmMacValue) {
0 ignored issues
show
Bug introduced by
The variable $szCheckMacValue does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
691
                    array_push($arErrors, 'CheckMacValue verify fail.');
692
                }
693
            }
694
        }
695
696
        if (sizeof($arErrors) > 0) {
697
            throw new Exception(join('- ', $arErrors));
698
        }
699
700
        return $arFeedback ;
701
702
    }
703
}
704
705
706
class ECPay_QueryPeriodCreditCardTradeInfo extends ECPay_Aio
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...
707
{
708
    static function CheckOut($arParameters = array(),$HashKey ='',$HashIV ='',$ServiceURL = ''){
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

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

Loading history...
709
        $arErrors = array();
710
        $arParameters['TimeStamp'] = time();
711
        $arFeedback = array();
712
        $arConfirmArgs = array();
0 ignored issues
show
Unused Code introduced by
$arConfirmArgs 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...
713
        // 呼叫查詢。
714
        if (sizeof($arErrors) == 0) {
715
            $arParameters["CheckMacValue"] = ECPay_CheckMacValue::generate($arParameters,$HashKey,$HashIV,0);
716
            // 送出查詢並取回結果。
717
            $szResult = parent::ServerPost($arParameters,$ServiceURL);
0 ignored issues
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (ServerPost() instead of CheckOut()). Are you sure this is correct? If so, you might want to change this to $this->ServerPost().

This check looks for a call to a parent method whose name is different than the method from which it is called.

Consider the following code:

class Daddy
{
    protected function getFirstName()
    {
        return "Eidur";
    }

    protected function getSurName()
    {
        return "Gudjohnsen";
    }
}

class Son
{
    public function getFirstName()
    {
        return parent::getSurname();
    }
}

The getFirstName() method in the Son calls the wrong method in the parent class.

Loading history...
718
            $szResult = str_replace(' ', '%20', $szResult);
719
            $szResult = str_replace('+', '%2B', $szResult);
720
721
            // 轉結果為陣列。
722
            $arParameters = json_decode($szResult,true);
723
            // 重新整理回傳參數。
724
            foreach ($arParameters as $keys => $value) {
725
                $arFeedback[$keys] = $value;
726
            }
727
728
        }
729
730
        if (sizeof($arErrors) > 0) {
731
            throw new Exception(join('- ', $arErrors));
732
        }
733
734
        return $arFeedback ;
735
    }
736
}
737
738
739
class ECPay_DoAction extends ECPay_Aio
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...
740
{
741
    static function CheckOut($arParameters = array(),$HashKey ='',$HashIV ='',$ServiceURL = ''){
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

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

Loading history...
742
                // 變數宣告。
743
        $arErrors = array();
744
        $arFeedback = array();
745
746
        //產生驗證碼
747
        $szCheckMacValue = ECPay_CheckMacValue::generate($arParameters,$HashKey,$HashIV,0);
748
        $arParameters["CheckMacValue"] = $szCheckMacValue;
749
        // 送出查詢並取回結果。
750
        $szResult = self::ServerPost($arParameters,$ServiceURL);
751
        // 轉結果為陣列。
752
        parse_str($szResult, $arParameters);
753
        // 重新整理回傳參數。
754
        foreach ($arParameters as $keys => $value) {
0 ignored issues
show
Bug introduced by
The expression $arParameters of type null|array is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
755
            if ($keys == 'CheckMacValue') {
756
                $szCheckMacValue = $value;
0 ignored issues
show
Unused Code introduced by
$szCheckMacValue 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...
757
            } else {
758
                $arFeedback[$keys] = $value;
759
            }
760
        }
761
762
        if (array_key_exists('RtnCode', $arFeedback) && $arFeedback['RtnCode'] != '1') {
763
            array_push($arErrors, vsprintf('#%s: %s', array($arFeedback['RtnCode'], $arFeedback['RtnMsg'])));
764
        }
765
766
        if (sizeof($arErrors) > 0) {
767
            throw new Exception(join('- ', $arErrors));
768
        }
769
770
        return $arFeedback ;
771
772
    }
773
}
774
775
class ECPay_AioCapture extends ECPay_Aio
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...
776
{
777
    static function Capture($arParameters=array(),$HashKey='',$HashIV='',$ServiceURL=''){
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

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

Loading history...
778
779
        $arErrors   = array();
780
        $arFeedback = array();
781
782
        $szCheckMacValue = ECPay_CheckMacValue::generate($arParameters,$HashKey,$HashIV,0);
783
        $arParameters["CheckMacValue"] = $szCheckMacValue;
784
785
        // 送出查詢並取回結果。
786
        $szResult = self::ServerPost($arParameters,$ServiceURL);
787
788
        // 轉結果為陣列。
789
        parse_str($szResult, $arParameters);
790
791
        // 重新整理回傳參數。
792
        foreach ($arParameters as $keys => $value) {
0 ignored issues
show
Bug introduced by
The expression $arParameters of type null|array is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
793
            $arFeedback[$keys] = $value;
794
        }
795
796
        if (sizeof($arErrors) > 0) {
797
            throw new Exception(join('- ', $arErrors));
798
        }
799
800
        return $arFeedback;
801
802
    }
803
}
804
805
806
807
808
809
810
811
812
813
Abstract class ECPay_Verification
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...
814
{
815
    abstract function check_goods($arParameters = array());
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

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

Loading history...
816
    abstract function filter_string($arExtend = array(),$InvoiceMark = '');
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

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

Loading history...
817
    abstract function check_extend_string($arExtend = array(),$InvoiceMark = '');
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

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

Loading history...
818
819
    // 電子發票延伸參數。
820
    public $arInvoice = array(
821
            "RelateNumber",
822
            "CustomerIdentifier",
823
            "CarrierType" ,
824
            "CustomerID" ,
825
            "Donation" ,
826
            "Print" ,
827
            "TaxType",
828
            "CustomerName" ,
829
            "CustomerAddr" ,
830
            "CustomerPhone" ,
831
            "CustomerEmail" ,
832
            "ClearanceMark" ,
833
            "CarrierNum" ,
834
            "LoveCode" ,
835
            "InvoiceRemark" ,
836
            "DelayDay",
837
            "InvoiceItemName",
838
            "InvoiceItemCount",
839
            "InvoiceItemWord",
840
            "InvoiceItemPrice",
841
            "InvoiceItemTaxType",
842
            "InvType"
843
        );
844
    //檢查共同參數
845
    public function check_string($arParameters = array()){
846
847
        $arErrors = array();
848
        if (strlen($arParameters['MerchantID']) == 0) {
849
            array_push($arErrors, 'MerchantID is required.');
850
        }
851
        if (strlen($arParameters['MerchantID']) > 10) {
852
            array_push($arErrors, 'MerchantID max langth as 10.');
853
        }
854
855
        if (strlen($arParameters['ReturnURL']) == 0) {
856
            array_push($arErrors, 'ReturnURL is required.');
857
        }
858
        if (strlen($arParameters['ClientBackURL']) > 200) {
859
            array_push($arErrors, 'ClientBackURL max langth as 200.');
860
        }
861
        if (strlen($arParameters['OrderResultURL']) > 200) {
862
            array_push($arErrors, 'OrderResultURL max langth as 200.');
863
        }
864
865
        if (strlen($arParameters['MerchantTradeNo']) == 0) {
866
            array_push($arErrors, 'MerchantTradeNo is required.');
867
        }
868
        if (strlen($arParameters['MerchantTradeNo']) > 20) {
869
            array_push($arErrors, 'MerchantTradeNo max langth as 20.');
870
        }
871
        if (strlen($arParameters['MerchantTradeDate']) == 0) {
872
            array_push($arErrors, 'MerchantTradeDate is required.');
873
        }
874
        if (strlen($arParameters['TotalAmount']) == 0) {
875
            array_push($arErrors, 'TotalAmount is required.');
876
        }
877
        if (strlen($arParameters['TradeDesc']) == 0) {
878
            array_push($arErrors, 'TradeDesc is required.');
879
        }
880
        if (strlen($arParameters['TradeDesc']) > 200) {
881
            array_push($arErrors, 'TradeDesc max langth as 200.');
882
        }
883
        if (strlen($arParameters['ChoosePayment']) == 0) {
884
            array_push($arErrors, 'ChoosePayment is required.');
885
        }
886
        if (strlen($arParameters['NeedExtraPaidInfo']) == 0) {
887
            array_push($arErrors, 'NeedExtraPaidInfo is required.');
888
        }
889
        if (sizeof($arParameters['Items']) == 0) {
890
            array_push($arErrors, 'Items is required.');
891
        }
892
893
        // 檢查CheckMacValue加密方式
894
        if (strlen($arParameters['EncryptType']) > 1) {
895
            array_push($arErrors, 'EncryptType max langth as 1.');
896
        }
897
898
        if(sizeof($arErrors)>0) throw new Exception(join('<br>', $arErrors));
899
    }
900
901
    //檢查電子發票參數
902
    public function check_invoiceString($arExtend = array() ){
903
        $arErrors = array();
904
905
        // 廠商自訂編號RelateNumber(不可為空)
906 View Code Duplication
        if(!array_key_exists('RelateNumber', $arExtend)){
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...
907
            array_push($arErrors, 'RelateNumber is required.');
908
        }else{
909
            if (strlen($arExtend['RelateNumber']) > 30) {
910
                array_push($arErrors, "RelateNumber max length as 30.");
911
            }
912
        }
913
914
        // 統一編號CustomerIdentifier(預設為空字串)
915 View Code Duplication
        if(!array_key_exists('CustomerIdentifier', $arExtend)){
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...
916
            $arExtend['CustomerIdentifier'] = '';
917
        }else{
918
            //統編長度只能為8
919
            if(strlen($arExtend['CustomerIdentifier']) != 8){
920
                array_push($arErrors, "CustomerIdentifier length should be 8.");
921
            }
922
        }
923
924
        // 載具類別CarrierType(預設為None)
925
        if(!array_key_exists('CarrierType', $arExtend)){
926
            $arExtend['CarrierType'] = ECPay_CarrierType::None ;
927 View Code Duplication
        }else{
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...
928
            //有設定統一編號的話,載具參數必須是空字串
929
            if(strlen($arExtend['CustomerIdentifier']) > 0 && $arExtend['CarrierType'] != ECPay_CarrierType::None  ){
930
                array_push($arErrors, "CarrierType should be None.");
931
            }
932
        }
933
934
        // 客戶代號CustomerID(預設為空字串)
935
        if(!array_key_exists('CustomerID', $arExtend)) {
936
            $arExtend['CustomerID'] = '';
937 View Code Duplication
        }else{
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...
938
            if($arExtend['CarrierType'] == ECPay_CarrierType::Member && strlen($arExtend['CustomerID'] == 0 )){
939
                array_push($arErrors, "CustomerID is required.");
940
            }
941
        }
942
        // 捐贈註記 Donation(預設為No)
943 View Code Duplication
        if(!array_key_exists('Donation', $arExtend)){
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...
944
            $arExtend['Donation'] = ECPay_Donation::No ;
945
        }else{
946
            //若有帶統一編號,不可捐贈
947
            if(strlen($arExtend['CustomerIdentifier']) > 0 && $arExtend['Donation'] != ECPay_Donation::No){
948
                array_push($arErrors, "Donation should be No.");
949
            }
950
        }
951
952
        // 列印註記Print(預設為No)
953
        if(!array_key_exists('Print', $arExtend)){
954
            $arExtend['Print'] = ECPay_PrintMark::No;
955
        }else{
956
            //捐贈註記為捐贈(Yes)時,請設定不列印(No)
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
957
            if($arExtend['Donation'] == ECPay_Donation::Yes && $arExtend['Print'] != ECPay_PrintMark::No){
958
                array_push($arErrors, "Print should be No.");
959
            }
960
            // 統一編號不為空字串時,請設定列印(Yes)
961
            if(strlen($arExtend['CustomerIdentifier']) > 0 && $arExtend['Print'] != ECPay_PrintMark::Yes){
962
                array_push($arErrors, "Print should be Yes.");
963
            }
964
            // 載具類別為會員載具(Member)、買受人自然人憑證(Citizen)、買受人手機條碼(Cellphone)時,請設定不列印(No)
0 ignored issues
show
Unused Code Comprehensibility introduced by
48% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
965
            $notPrint = array(ECPay_CarrierType::Member, ECPay_CarrierType::Citizen, ECPay_CarrierType::Cellphone);
966
            if (in_array($arExtend['CarrierType'], $notPrint) and $arExtend['Print'] == ECPay_PrintMark::Yes) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using logical operators such as and instead of && is generally not recommended.

PHP has two types of connecting operators (logical operators, and boolean operators):

  Logical Operators Boolean Operator
AND - meaning and &&
OR - meaning or ||

The difference between these is the order in which they are executed. In most cases, you would want to use a boolean operator like &&, or ||.

Let’s take a look at a few examples:

// Logical operators have lower precedence:
$f = false or true;

// is executed like this:
($f = false) or true;


// Boolean operators have higher precedence:
$f = false || true;

// is executed like this:
$f = (false || true);

Logical Operators are used for Control-Flow

One case where you explicitly want to use logical operators is for control-flow such as this:

$x === 5
    or die('$x must be 5.');

// Instead of
if ($x !== 5) {
    die('$x must be 5.');
}

Since die introduces problems of its own, f.e. it makes our code hardly testable, and prevents any kind of more sophisticated error handling; you probably do not want to use this in real-world code. Unfortunately, logical operators cannot be combined with throw at this point:

// The following is currently a parse error.
$x === 5
    or throw new RuntimeException('$x must be 5.');

These limitations lead to logical operators rarely being of use in current PHP code.

Loading history...
967
                array_push($arErrors, "Print should be No.");
968
            }
969
970
        }
971
        // 客戶名稱CustomerName(UrlEncode, 預設為空字串)
0 ignored issues
show
Unused Code Comprehensibility introduced by
38% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
972 View Code Duplication
        if(!array_key_exists('CustomerName', $arExtend)){
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...
973
            $arExtend['CustomerName'] = '';
974
        }else{
975
            if (mb_strlen($arExtend['CustomerName'], 'UTF-8') > 20) {
976
                  array_push($arErrors, "CustomerName max length as 20.");
977
            }
978
            // 列印註記為列印(Yes)時,此參數不可為空字串
979
            if($arExtend['Print'] == ECPay_PrintMark::Yes && strlen($arExtend['CustomerName']) == 0){
980
                array_push($arErrors, "CustomerName is required.");
981
            }
982
        }
983
984
        // 客戶地址CustomerAddr(UrlEncode, 預設為空字串)
0 ignored issues
show
Unused Code Comprehensibility introduced by
38% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
985 View Code Duplication
        if(!array_key_exists('CustomerAddr', $arExtend)){
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...
986
            $arExtend['CustomerAddr'] = '';
987
        }else{
988
            if (mb_strlen($arExtend['CustomerAddr'], 'UTF-8') > 200) {
989
                  array_push($arErrors, "CustomerAddr max length as 200.");
990
            }
991
            // 列印註記為列印(Yes)時,此參數不可為空字串
992
            if($arExtend['Print'] == ECPay_PrintMark::Yes && strlen($arExtend['CustomerAddr']) == 0){
993
                array_push($arErrors, "CustomerAddr is required.");
994
            }
995
        }
996
        // 客戶電話CustomerPhone
997 View Code Duplication
        if(!array_key_exists('CustomerPhone', $arExtend)){
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...
998
            $arExtend['CustomerPhone'] = '';
999
        }else{
1000
            if (strlen($arExtend['CustomerPhone']) > 20) array_push($arErrors, "CustomerPhone max length as 20.");
1001
        }
1002
1003
        // 客戶信箱CustomerEmail
1004 View Code Duplication
        if(!array_key_exists('CustomerEmail', $arExtend)){
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...
1005
            $arExtend['CustomerEmail'] = '';
1006
        }else{
1007
            if (strlen($arExtend['CustomerEmail']) > 200) array_push($arErrors, "CustomerEmail max length as 200.");
1008
        }
1009
1010
        //(CustomerEmail與CustomerPhone擇一不可為空)
1011
        if (strlen($arExtend['CustomerPhone']) == 0 and strlen($arExtend['CustomerEmail']) == 0) array_push($arErrors, "CustomerPhone or CustomerEmail is required.");
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using logical operators such as and instead of && is generally not recommended.

PHP has two types of connecting operators (logical operators, and boolean operators):

  Logical Operators Boolean Operator
AND - meaning and &&
OR - meaning or ||

The difference between these is the order in which they are executed. In most cases, you would want to use a boolean operator like &&, or ||.

Let’s take a look at a few examples:

// Logical operators have lower precedence:
$f = false or true;

// is executed like this:
($f = false) or true;


// Boolean operators have higher precedence:
$f = false || true;

// is executed like this:
$f = (false || true);

Logical Operators are used for Control-Flow

One case where you explicitly want to use logical operators is for control-flow such as this:

$x === 5
    or die('$x must be 5.');

// Instead of
if ($x !== 5) {
    die('$x must be 5.');
}

Since die introduces problems of its own, f.e. it makes our code hardly testable, and prevents any kind of more sophisticated error handling; you probably do not want to use this in real-world code. Unfortunately, logical operators cannot be combined with throw at this point:

// The following is currently a parse error.
$x === 5
    or throw new RuntimeException('$x must be 5.');

These limitations lead to logical operators rarely being of use in current PHP code.

Loading history...
1012
1013
        //課稅類別 TaxType(不可為空)
1014
        if (strlen($arExtend['TaxType']) == 0) array_push($arErrors, "TaxType is required.");
1015
1016
        //通關方式 ClearanceMark(預設為空字串)
1017
        if(!array_key_exists('ClearanceMark', $arExtend)) {
1018
            $arExtend['ClearanceMark'] = '';
1019
        }else{
1020
            //課稅類別為零稅率(Zero)時,ClearanceMark不可為空字串
1021
            if($arExtend['TaxType'] == ECPay_TaxType::Zero && ($arExtend['ClearanceMark'] != ECPay_ClearanceMark::Yes || $arExtend['ClearanceMark'] != ECPay_ClearanceMark::No)) {
1022
                array_push($arErrors, "ClearanceMark is required.");
1023
            }
1024
            if (strlen($arExtend['ClearanceMark']) > 0 && $arExtend['TaxType'] != ECPay_TaxType::Zero) {
1025
                array_push($arErrors, "Please remove ClearanceMark.");
1026
            }
1027
        }
1028
1029
        // CarrierNum(預設為空字串)
1030
        if (!array_key_exists('CarrierNum', $arExtend)) {
1031
            $arExtend['CarrierNum'] = '';
1032
        } else {
1033
            switch ($arExtend['CarrierType']) {
1034
                // 載具類別為無載具(None)或會員載具(Member)時,請設定空字串
0 ignored issues
show
Unused Code Comprehensibility introduced by
40% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
1035
                case ECPay_CarrierType::None:
1036 View Code Duplication
                case ECPay_CarrierType::Member:
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...
1037
                    if (strlen($arExtend['CarrierNum']) > 0) {
1038
                        array_push($arErrors, "Please remove CarrierNum.");
1039
                    }
1040
                break;
1041
                // 載具類別為買受人自然人憑證(Citizen)時,請設定自然人憑證號碼,前2碼為大小寫英文,後14碼為數字
1042 View Code Duplication
                case ECPay_CarrierType::Citizen:
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...
1043
                    if (!preg_match('/^[a-zA-Z]{2}\d{14}$/', $arExtend['CarrierNum'])){
1044
                        array_push($arErrors, "Invalid CarrierNum.");
1045
                    }
1046
                break;
1047
                // 載具類別為買受人手機條碼(Cellphone)時,請設定手機條碼,第1碼為「/」,後7碼為大小寫英文、數字、「+」、「-」或「.」
1048 View Code Duplication
                case ECPay_CarrierType::Cellphone:
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...
1049
                    if (!preg_match('/^\/{1}[0-9a-zA-Z+-.]{7}$/', $arExtend['CarrierNum'])) {
1050
                        array_push($arErrors, "Invalid CarrierNum.");
1051
                    }
1052
                break;
1053
1054
                default:
1055
                    array_push($arErrors, "Please remove CarrierNum.");
1056
            }
1057
        }
1058
1059
        // 愛心碼 LoveCode(預設為空字串)
1060
        if(!array_key_exists('LoveCode', $arExtend)) $arExtend['LoveCode'] = '';
1061
        // 捐贈註記為捐贈(Yes)時,參數長度固定3~7碼,請設定全數字或第1碼大小寫「X」,後2~6碼全數字
1062 View Code Duplication
        if ($arExtend['Donation'] == ECPay_Donation::Yes) {
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...
1063
            if (!preg_match('/^([xX]{1}[0-9]{2,6}|[0-9]{3,7})$/', $arExtend['LoveCode'])) {
1064
                array_push($arErrors, "Invalid LoveCode.");
1065
            }
1066
        } else {
1067
            if (strlen($arExtend['LoveCode']) > 0) {
1068
                array_push($arErrors, "Please remove LoveCode.");
1069
            }
1070
        }
1071
1072
        //備註 InvoiceRemark(UrlEncode, 預設為空字串)
1073
        if(!array_key_exists('InvoiceRemark', $arExtend)) $arExtend['InvoiceRemark'] = '';
1074
1075
        // 延遲天數 DelayDay(不可為空, 預設為0) 延遲天數,範圍0~15,設定為0時,付款完成後立即開立發票
1076
        if(!array_key_exists('DelayDay', $arExtend)) $arExtend['DelayDay'] = 0 ;
1077
        if ($arExtend['DelayDay'] < 0 or $arExtend['DelayDay'] > 15) array_push($arErrors, "DelayDay should be 0 ~ 15.");
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using logical operators such as or instead of || is generally not recommended.

PHP has two types of connecting operators (logical operators, and boolean operators):

  Logical Operators Boolean Operator
AND - meaning and &&
OR - meaning or ||

The difference between these is the order in which they are executed. In most cases, you would want to use a boolean operator like &&, or ||.

Let’s take a look at a few examples:

// Logical operators have lower precedence:
$f = false or true;

// is executed like this:
($f = false) or true;


// Boolean operators have higher precedence:
$f = false || true;

// is executed like this:
$f = (false || true);

Logical Operators are used for Control-Flow

One case where you explicitly want to use logical operators is for control-flow such as this:

$x === 5
    or die('$x must be 5.');

// Instead of
if ($x !== 5) {
    die('$x must be 5.');
}

Since die introduces problems of its own, f.e. it makes our code hardly testable, and prevents any kind of more sophisticated error handling; you probably do not want to use this in real-world code. Unfortunately, logical operators cannot be combined with throw at this point:

// The following is currently a parse error.
$x === 5
    or throw new RuntimeException('$x must be 5.');

These limitations lead to logical operators rarely being of use in current PHP code.

Loading history...
1078
1079
1080
        // 字軌類別 InvType(不可為空)
1081
        if (!array_key_exists('InvType', $arExtend)) array_push($arErrors, "InvType is required.");
1082
1083
        //商品相關整理
1084
        if(!array_key_exists('InvoiceItems', $arExtend)){
1085
            array_push($arErrors, "Invoice Goods information not found.");
1086
        }else{
1087
            $InvSptr = '|';
1088
            $tmpItemName = array();
1089
            $tmpItemCount = array();
1090
            $tmpItemWord = array();
1091
            $tmpItemPrice = array();
1092
            $tmpItemTaxType = array();
1093
            foreach ($arExtend['InvoiceItems'] as $tmpItemInfo) {
1094
                if (mb_strlen($tmpItemInfo['Name'], 'UTF-8') > 0) {
1095
                    array_push($tmpItemName, $tmpItemInfo['Name']);
1096
                }
1097
                if (strlen($tmpItemInfo['Count']) > 0) {
1098
                    array_push($tmpItemCount, $tmpItemInfo['Count']);
1099
                }
1100
                if (mb_strlen($tmpItemInfo['Word'], 'UTF-8') > 0) {
1101
                    array_push($tmpItemWord, $tmpItemInfo['Word']);
1102
                }
1103
                if (strlen($tmpItemInfo['Price']) > 0) {
1104
                    array_push($tmpItemPrice, $tmpItemInfo['Price']);
1105
                }
1106
                if (strlen($tmpItemInfo['TaxType']) > 0) {
1107
                    array_push($tmpItemTaxType, $tmpItemInfo['TaxType']);
1108
                }
1109
            }
1110
1111
            if ($arExtend['TaxType'] == ECPay_TaxType::Mix) {
1112
                if (in_array(ECPay_TaxType::Dutiable, $tmpItemTaxType) and in_array(ECPay_TaxType::Free, $tmpItemTaxType)) {
0 ignored issues
show
Unused Code introduced by
This if statement is empty and can be removed.

This check looks for the bodies of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
Comprehensibility Best Practice introduced by
Using logical operators such as and instead of && is generally not recommended.

PHP has two types of connecting operators (logical operators, and boolean operators):

  Logical Operators Boolean Operator
AND - meaning and &&
OR - meaning or ||

The difference between these is the order in which they are executed. In most cases, you would want to use a boolean operator like &&, or ||.

Let’s take a look at a few examples:

// Logical operators have lower precedence:
$f = false or true;

// is executed like this:
($f = false) or true;


// Boolean operators have higher precedence:
$f = false || true;

// is executed like this:
$f = (false || true);

Logical Operators are used for Control-Flow

One case where you explicitly want to use logical operators is for control-flow such as this:

$x === 5
    or die('$x must be 5.');

// Instead of
if ($x !== 5) {
    die('$x must be 5.');
}

Since die introduces problems of its own, f.e. it makes our code hardly testable, and prevents any kind of more sophisticated error handling; you probably do not want to use this in real-world code. Unfortunately, logical operators cannot be combined with throw at this point:

// The following is currently a parse error.
$x === 5
    or throw new RuntimeException('$x must be 5.');

These limitations lead to logical operators rarely being of use in current PHP code.

Loading history...
1113
                    // Do nothing
1114
                }  else {
1115
                    $tmpItemTaxType = array();
1116
                }
1117
            }
1118
            if ((count($tmpItemName) + count($tmpItemCount) + count($tmpItemWord) + count($tmpItemPrice) + count($tmpItemTaxType)) == (count($tmpItemName) * 5)) {
1119
                $arExtend['InvoiceItemName']    = implode($InvSptr, $tmpItemName);
1120
                $arExtend['InvoiceItemCount']   = implode($InvSptr, $tmpItemCount);
1121
                $arExtend['InvoiceItemWord']    = implode($InvSptr, $tmpItemWord);
1122
                $arExtend['InvoiceItemPrice']   = implode($InvSptr, $tmpItemPrice);
1123
                $arExtend['InvoiceItemTaxType'] = implode($InvSptr, $tmpItemTaxType);
1124
            }
1125
1126
            unset($arExtend['InvoiceItems']);
1127
        }
1128
1129
1130
        $encode_fields = array(
1131
                'CustomerName',
1132
                'CustomerAddr',
1133
                'CustomerEmail',
1134
                'InvoiceItemName',
1135
                'InvoiceItemWord',
1136
                'InvoiceRemark'
1137
            );
1138
        foreach ($encode_fields as $tmp_field) {
1139
            $arExtend[$tmp_field] = urlencode($arExtend[$tmp_field]);
1140
        }
1141
1142
        if (sizeof($arErrors) > 0) {
1143
            throw new Exception(join('<br>', $arErrors));
1144
        }
1145
1146
        return $arExtend ;
1147
1148
1149
    }
1150
1151
}
1152
1153
1154
/**
1155
*  付款方式:超商代碼
1156
*/
1157 View Code Duplication
class ECPay_CVS extends ECPay_Verification
0 ignored issues
show
Duplication introduced by
This class seems to be duplicated in your project.

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

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

Loading history...
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...
1158
{
1159
    public  $arPayMentExtend = array(
1160
                            'Desc_1'           =>'',
1161
                            'Desc_2'           =>'',
1162
                            'Desc_3'           =>'',
1163
                            'Desc_4'           =>'',
1164
                            'PaymentInfoURL'   =>'',
1165
                            'ClientRedirectURL'=>'',
1166
                            'StoreExpireDate'  =>''
1167
                        );
1168
    //檢查共同參數
1169
    function check_string($arParameters = array()){
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

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

Loading history...
1170
        parent::check_string($arParameters);
1171
        if (!$arParameters['PlatformID'])  unset($arParameters['PlatformID']);
1172
        unset($arParameters['IgnorePayment']);
1173
        return $arParameters ;
1174
    }
1175
    //檢查CVS的延伸參數
1176
    function check_extend_string($arExtend = array(),$InvoiceMark = ''){
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

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

Loading history...
1177
1178
        //沒設定參數的話,就給預設參數
1179
        foreach ($this->arPayMentExtend as $key => $value) {
1180
            if(!isset($arExtend[$key])) $arExtend[$key] = $value;
1181
        }
1182
1183
        //若有開發票,檢查一下發票參數
1184
        if($InvoiceMark == 'Y') $arExtend = $this->check_invoiceString($arExtend);
1185
        return $arExtend ;
1186
1187
    }
1188
1189
    //過濾多餘參數
1190
    function filter_string($arExtend = array(),$InvoiceMark = '')
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

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

Loading history...
1191
    {
1192
        $arPayMentExtend = ($InvoiceMark == '')? array_keys($this->arPayMentExtend) : array_merge(array_keys($this->arPayMentExtend),$this->arInvoice);
1193
        foreach ($arExtend as $key => $value) {
1194
            if (!in_array($key,$arPayMentExtend )) {
1195
                unset($arExtend[$key]);
1196
            }
1197
        }
1198
        return $arExtend ;
1199
    }
1200
1201
    //檢查商品
1202
    function check_goods($arParameters = array()){
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

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

Loading history...
1203
        // 檢查產品名稱。
1204
        $szItemName = '';
1205
        $arErrors   = array();
1206
        if (sizeof($arParameters['Items']) > 0) {
1207
            foreach ($arParameters['Items'] as $keys => $value) {
1208
                $szItemName .= vsprintf('#%s %d %s x %u', $arParameters['Items'][$keys]);
1209
                if (!array_key_exists('ItemURL', $arParameters)) {
1210
                    $arParameters['ItemURL'] = $arParameters['Items'][$keys]['URL'];
1211
                }
1212
            }
1213
1214
            if (strlen($szItemName) > 0) {
1215
                $szItemName = mb_substr($szItemName, 1, 200);
1216
                $arParameters['ItemName'] = $szItemName ;
1217
            }
1218
        } else {
1219
            array_push($arErrors, "Goods information not found.");
1220
        }
1221
1222
        if(sizeof($arErrors)>0) throw new Exception(join('<br>', $arErrors));
1223
1224
        unset($arParameters['Items']);
1225
        return $arParameters ;
1226
    }
1227
1228
}
1229
1230
1231
/**
1232
* 付款方式 : BARCODE
1233
*/
1234 View Code Duplication
class ECPay_BARCODE extends ECPay_Verification
0 ignored issues
show
Duplication introduced by
This class seems to be duplicated in your project.

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

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

Loading history...
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...
1235
{
1236
    public  $arPayMentExtend = array(
1237
                            'Desc_1'           =>'',
1238
                            'Desc_2'           =>'',
1239
                            'Desc_3'           =>'',
1240
                            'Desc_4'           =>'',
1241
                            'PaymentInfoURL'   =>'',
1242
                            'ClientRedirectURL'=>'',
1243
                            'StoreExpireDate'  =>''
1244
                        );
1245
1246
    //檢查共同參數
1247
    function check_string($arParameters = array()){
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

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

Loading history...
1248
        parent::check_string($arParameters);
1249
        if (!$arParameters['PlatformID'])  unset($arParameters['PlatformID']);
1250
        unset($arParameters['IgnorePayment']);
1251
        return $arParameters ;
1252
    }
1253
1254
    //檢查BARCODE的延伸參數
1255
    function check_extend_string($arExtend = array(),$InvoiceMark = ''){
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

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

Loading history...
1256
1257
        //沒設定參數的話,就給預設參數
1258
        foreach ($this->arPayMentExtend as $key => $value) {
1259
            if(!isset($arExtend[$key])) $arExtend[$key] = $value;
1260
        }
1261
1262
        //若有開發票,檢查一下發票參數
1263
        if($InvoiceMark == 'Y') $arExtend = $this->check_invoiceString($arExtend);
1264
        return $arExtend ;
1265
1266
    }
1267
1268
    //過濾多餘參數
1269
    function filter_string($arExtend = array(),$InvoiceMark = '')
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

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

Loading history...
1270
    {
1271
        $arPayMentExtend = ($InvoiceMark == '')? array_keys($this->arPayMentExtend) : array_merge(array_keys($this->arPayMentExtend),$this->arInvoice);
1272
        foreach ($arExtend as $key => $value) {
1273
            if (!in_array($key,$arPayMentExtend )) {
1274
                unset($arExtend[$key]);
1275
            }
1276
        }
1277
        return $arExtend ;
1278
    }
1279
        //檢查商品
1280
    function check_goods($arParameters = array()){
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

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

Loading history...
1281
        // 檢查產品名稱。
1282
        $szItemName = '';
1283
        $arErrors   = array();
1284
        if (sizeof($arParameters['Items']) > 0) {
1285
            foreach ($arParameters['Items'] as $keys => $value) {
1286
                $szItemName .= vsprintf('#%s %d %s x %u', $arParameters['Items'][$keys]);
1287
                if (!array_key_exists('ItemURL', $arParameters)) {
1288
                    $arParameters['ItemURL'] = $arParameters['Items'][$keys]['URL'];
1289
                }
1290
            }
1291
1292
            if (strlen($szItemName) > 0) {
1293
                $szItemName = mb_substr($szItemName, 1, 200);
1294
                $arParameters['ItemName'] = $szItemName ;
1295
            }
1296
        } else {
1297
            array_push($arErrors, "Goods information not found.");
1298
        }
1299
1300
        if(sizeof($arErrors)>0) throw new Exception(join('<br>', $arErrors));
1301
1302
        unset($arParameters['Items']);
1303
        return $arParameters ;
1304
    }
1305
1306
}
1307
1308
/**
1309
*  付款方式 ATM
1310
*/
1311
1312
class ECPay_ATM extends ECPay_Verification
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...
1313
{
1314
    public  $arPayMentExtend = array(
1315
                            'ExpireDate'       => 3,
1316
                            'PaymentInfoURL'   => '',
1317
                            'ClientRedirectURL'=> '',
1318
                        );
1319
1320
    //檢查共同參數
1321
    function check_string($arParameters = array()){
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

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

Loading history...
1322
        parent::check_string($arParameters);
1323
        if (!$arParameters['PlatformID'])  unset($arParameters['PlatformID']);
1324
        unset($arParameters['IgnorePayment']);
1325
        return $arParameters ;
1326
    }
1327
1328
    //檢查ATM的延伸參數
1329
    function check_extend_string($arExtend = array(),$InvoiceMark = ''){
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

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

Loading history...
1330
        //沒設定參數的話,就給預設參數
1331
        foreach ($this->arPayMentExtend as $key => $value) {
1332
            if(!isset($arExtend[$key])) $arExtend[$key] = $value;
1333
        }
1334
1335
        //若有開發票,檢查一下發票參數
1336
        if($InvoiceMark == 'Y') $arExtend = $this->check_invoiceString($arExtend);
1337
        return $arExtend ;
1338
1339
    }
1340
1341
    //過濾多餘參數
1342
    function filter_string($arExtend = array(),$InvoiceMark = '')
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

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

Loading history...
1343
    {
1344
        $arPayMentExtend = ($InvoiceMark == '')? array_keys($this->arPayMentExtend) : array_merge(array_keys($this->arPayMentExtend),$this->arInvoice);
1345
        foreach ($arExtend as $key => $value) {
1346
            if (!in_array($key,$arPayMentExtend )) {
1347
                unset($arExtend[$key]);
1348
            }
1349
        }
1350
        return $arExtend ;
1351
    }
1352
1353
    //檢查商品
1354
    function check_goods($arParameters = array()){
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

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

Loading history...
1355
        // 檢查產品名稱。
1356
        $szItemName = '';
1357
        $arErrors   = array();
1358
        if (sizeof($arParameters['Items']) > 0) {
1359
            foreach ($arParameters['Items'] as $keys => $value) {
1360
                $szItemName .= vsprintf('#%s %d %s x %u', $arParameters['Items'][$keys]);
1361
                if (!array_key_exists('ItemURL', $arParameters)) {
1362
                    $arParameters['ItemURL'] = $arParameters['Items'][$keys]['URL'];
1363
                }
1364
            }
1365
1366
            if (strlen($szItemName) > 0) {
1367
                $szItemName = mb_substr($szItemName, 1, 200);
1368
                $arParameters['ItemName'] = $szItemName ;
1369
            }
1370
        } else {
1371
            array_push($arErrors, "Goods information not found.");
1372
        }
1373
1374
        if(sizeof($arErrors)>0) throw new Exception(join('<br>', $arErrors));
1375
1376
        unset($arParameters['Items']);
1377
        return $arParameters ;
1378
    }
1379
1380
1381
}
1382
1383
/**
1384
*  付款方式 WebATM
1385
*/
1386
1387
class ECPay_WebATM extends ECPay_Verification
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...
1388
{
1389
    public  $arPayMentExtend = array();
1390
1391
    //檢查共同參數
1392
    function check_string($arParameters = array()){
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

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

Loading history...
1393
        parent::check_string($arParameters);
1394
        if (!$arParameters['PlatformID'])  unset($arParameters['PlatformID']);
1395
        unset($arParameters['IgnorePayment']);
1396
        return $arParameters ;
1397
    }
1398
1399
    //檢查WebATM的延伸參數
1400
    function check_extend_string($arExtend = array(),$InvoiceMark = ''){
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

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

Loading history...
1401
        //沒設定參數的話,就給預設參數
1402
        foreach ($this->arPayMentExtend as $key => $value) {
1403
            if(!isset($arExtend[$key])) $arExtend[$key] = $value;
1404
        }
1405
1406
        //若有開發票,檢查一下發票參數
1407
        if($InvoiceMark == 'Y') $arExtend = $this->check_invoiceString($arExtend);
1408
        return $arExtend ;
1409
1410
    }
1411
1412
    //過濾多餘參數
1413
    function filter_string($arExtend = array(),$InvoiceMark = '')
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

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

Loading history...
1414
    {
1415
        $arPayMentExtend = ($InvoiceMark == '')? array_keys($this->arPayMentExtend) : array_merge(array_keys($this->arPayMentExtend),$this->arInvoice);
1416
        foreach ($arExtend as $key => $value) {
1417
            if (!in_array($key,$arPayMentExtend )) {
1418
                unset($arExtend[$key]);
1419
            }
1420
        }
1421
        return $arExtend ;
1422
    }
1423
    //檢查商品
1424
    function check_goods($arParameters = array()){
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

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

Loading history...
1425
        // 檢查產品名稱。
1426
        $arErrors   = array();
1427
        $szItemName = '';
1428
        if (sizeof($arParameters['Items']) > 0) {
1429
            foreach ($arParameters['Items'] as $keys => $value) {
1430
                $szItemName .= vsprintf('#%s %d %s x %u', $arParameters['Items'][$keys]);
1431
                if (!array_key_exists('ItemURL', $arParameters)) {
1432
                    $arParameters['ItemURL'] = $arParameters['Items'][$keys]['URL'];
1433
                }
1434
            }
1435
1436
            if (strlen($szItemName) > 0) {
1437
                $szItemName = mb_substr($szItemName, 1, 200);
1438
                $arParameters['ItemName'] = $szItemName ;
1439
            }
1440
        } else {
1441
            array_push($arErrors, "Goods information not found.");
1442
        }
1443
1444
        if(sizeof($arErrors)>0) throw new Exception(join('<br>', $arErrors));
1445
1446
        unset($arParameters['Items']);
1447
        return $arParameters ;
1448
    }
1449
1450
1451
}
1452
1453
/**
1454
* 付款方式 : 信用卡
1455
*/
1456
class ECPay_Credit extends ECPay_Verification
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...
1457
{
1458
    public $arPayMentExtend = array(
1459
                                    "CreditInstallment" => 0,
1460
                                    "InstallmentAmount" => 0,
1461
                                    "Redeem"            => FALSE,
1462
                                    "UnionPay"          => FALSE,
1463
                                    "Language"          => '',
1464
                                    "PeriodAmount"      => '',
1465
                                    "PeriodType"        => '',
1466
                                    "Frequency"         => '',
1467
                                    "ExecTimes"         => '',
1468
                                    "PeriodReturnURL"   => ''
1469
                                );
1470
    //檢查共同參數
1471
    function check_string($arParameters = array()){
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

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

Loading history...
1472
        parent::check_string($arParameters);
1473
        if (!$arParameters['PlatformID'])  unset($arParameters['PlatformID']);
1474
        unset($arParameters['IgnorePayment']);
1475
        return $arParameters ;
1476
    }
1477
1478
    function check_extend_string($arExtend = array(),$InvoiceMark = ''){
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

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

Loading history...
1479
        foreach ($this->arPayMentExtend as $key => $value) {
1480
            if(!isset($arExtend[$key])) $arExtend[$key] = $value;
1481
        }
1482
1483
        //若有開發票,檢查一下發票參數
1484
        if($InvoiceMark == 'Y') $arExtend = $this->check_invoiceString($arExtend);
1485
        return $arExtend ;
1486
    }
1487
1488
    function filter_string($arExtend = array(),$InvoiceMark = ''){
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

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

Loading history...
1489
1490
        $arPayMentExtend = ($InvoiceMark == '')? array_keys($this->arPayMentExtend) : array_merge(array_keys($this->arPayMentExtend),$this->arInvoice);
1491
        foreach ($arExtend as $key => $value) {
1492
            if (!in_array($key,$arPayMentExtend )) {
1493
                unset($arExtend[$key]);
1494
            }
1495
        }
1496
        return $arExtend ;
1497
    }
1498
    //檢查商品
1499
    function check_goods($arParameters = array()){
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

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

Loading history...
1500
        // 檢查產品名稱。
1501
        $arErrors   = array();
1502
        $szItemName = '';
1503
        if (sizeof($arParameters['Items']) > 0) {
1504
            foreach ($arParameters['Items'] as $keys => $value) {
1505
                $szItemName .= vsprintf('#%s %d %s x %u', $arParameters['Items'][$keys]);
1506
                if (!array_key_exists('ItemURL', $arParameters)) {
1507
                    $arParameters['ItemURL'] = $arParameters['Items'][$keys]['URL'];
1508
                }
1509
            }
1510
1511
            if (strlen($szItemName) > 0) {
1512
                $szItemName = mb_substr($szItemName, 1, 200);
1513
                $arParameters['ItemName'] = $szItemName ;
1514
            }
1515
        } else {
1516
            array_push($arErrors, "Goods information not found.");
1517
        }
1518
1519
        if(sizeof($arErrors)>0) throw new Exception(join('<br>', $arErrors));
1520
1521
        unset($arParameters['Items']);
1522
        return $arParameters ;
1523
    }
1524
1525
}
1526
1527
/**
1528
*  付款方式:全功能
1529
*/
1530
class ECPay_ALL extends ECPay_Verification
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...
1531
{
1532
    public  $arPayMentExtend = array();
1533
1534
    //檢查共同參數
1535
    function check_string($arParameters = array()){
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

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

Loading history...
1536
        parent::check_string($arParameters);
1537
        if (!$arParameters['PlatformID'])  unset($arParameters['PlatformID']);
1538
        return $arParameters ;
1539
    }
1540
1541
    //檢查ALL的延伸參數
1542
    function check_extend_string($arExtend = array(),$InvoiceMark = ''){
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

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

Loading history...
1543
        //若有開發票,檢查一下發票參數
1544
        if($InvoiceMark == 'Y') $arExtend = $this->check_invoiceString($arExtend);
1545
        return $arExtend ;
1546
    }
1547
1548
    function filter_string($arExtend = array(),$InvoiceMark = ''){
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

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

Loading history...
1549
        return $arExtend ;
1550
    }
1551
    //檢查商品
1552
    function check_goods($arParameters = array()){
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

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

Loading history...
1553
        // 檢查產品名稱。
1554
        $arErrors           = array();
1555
1556
        $szItemName = '';
1557
        if (sizeof($arParameters['Items']) > 0) {
1558
            foreach ($arParameters['Items'] as $keys => $value) {
1559
                $szItemName .= vsprintf('#%s %d %s x %u', $arParameters['Items'][$keys]);
1560
1561
                if (!array_key_exists('ItemURL', $arParameters)) {
1562
                    $arParameters['ItemURL'] = $arParameters['Items'][$keys]['URL'];
1563
                }
1564
            }
1565
1566
            if (strlen($szItemName) > 0) {
1567
                $szItemName = mb_substr($szItemName, 1, 200);
1568
                $arParameters['ItemName'] = $szItemName ;
1569
            }
1570
        } else {
1571
            array_push($arErrors, "Goods information not found.");
1572
        }
1573
1574
        if(sizeof($arErrors)>0) throw new Exception(join('<br>', $arErrors));
1575
        unset($arParameters['Items']);
1576
        return $arParameters ;
1577
    }
1578
1579
}
1580
1581
1582
/**
1583
*  檢查碼
1584
*/
1585
class ECPay_CheckMacValue{
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...
1586
1587
    static function generate($arParameters = array(),$HashKey = '' ,$HashIV = '',$encType = 0){
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

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

Loading history...
1588
        $sMacValue = '' ;
1589
1590
        if(isset($arParameters))
1591
        {
1592
            unset($arParameters['CheckMacValue']);
1593
            uksort($arParameters, array('ECPay_CheckMacValue','merchantSort'));
1594
1595
            // 組合字串
1596
            $sMacValue = 'HashKey=' . $HashKey ;
1597
            foreach($arParameters as $key => $value)
1598
            {
1599
                $sMacValue .= '&' . $key . '=' . $value ;
1600
            }
1601
1602
            $sMacValue .= '&HashIV=' . $HashIV ;
1603
1604
            // URL Encode編碼
1605
            $sMacValue = urlencode($sMacValue);
1606
1607
            // 轉成小寫
1608
            $sMacValue = strtolower($sMacValue);
1609
1610
            // 取代為與 dotNet 相符的字元
1611
            $sMacValue = str_replace('%2d', '-', $sMacValue);
1612
            $sMacValue = str_replace('%5f', '_', $sMacValue);
1613
            $sMacValue = str_replace('%2e', '.', $sMacValue);
1614
            $sMacValue = str_replace('%21', '!', $sMacValue);
1615
            $sMacValue = str_replace('%2a', '*', $sMacValue);
1616
            $sMacValue = str_replace('%28', '(', $sMacValue);
1617
            $sMacValue = str_replace('%29', ')', $sMacValue);
1618
1619
            // 編碼
1620
            switch ($encType) {
1621
                case ECPay_EncryptType::ENC_SHA256:
1622
                    // SHA256 編碼
1623
                    $sMacValue = hash('sha256', $sMacValue);
1624
                break;
1625
1626
                case ECPay_EncryptType::ENC_MD5:
1627
                default:
1628
                // MD5 編碼
1629
                    $sMacValue = md5($sMacValue);
1630
            }
1631
1632
                $sMacValue = strtoupper($sMacValue);
1633
        }
1634
1635
        return $sMacValue ;
1636
    }
1637
    /**
1638
    * 自訂排序使用
1639
    */
1640
    private static function merchantSort($a,$b)
1641
    {
1642
        return strcasecmp($a, $b);
1643
    }
1644
1645
}
1646
1647
1648
?>
0 ignored issues
show
Best Practice introduced by
It is not recommended to use PHP's closing tag ?> in files other than templates.

Using a closing tag in PHP files that only contain PHP code is not recommended as you might accidentally add whitespace after the closing tag which would then be output by PHP. This can cause severe problems, for example headers cannot be sent anymore.

A simple precaution is to leave off the closing tag as it is not required, and it also has no negative effects whatsoever.

Loading history...
1649