1
|
|
|
<?php |
2
|
|
|
// Include CForm |
3
|
|
|
include('../../autoloader.php'); |
4
|
|
|
|
5
|
|
|
// Adapted from Java code at http://www.merriampark.com/anatomycc.htm |
6
|
|
|
// by Andy Frey, onesandzeros.biz |
7
|
|
|
// Checks for valid credit card number using Luhn algorithm |
8
|
|
|
// Source from: http://onesandzeros.biz/notebook/ccvalidation.php |
9
|
|
|
// |
10
|
|
|
// Try the following numbers, they should be valid according to the check: |
11
|
|
|
// 4408 0412 3456 7893 |
12
|
|
|
// 4417 1234 5678 9113 |
13
|
|
|
// |
14
|
|
|
function isValidCCNumber( $ccNum ) { |
15
|
|
|
$digitsOnly = ""; |
16
|
|
|
// Filter out non-digit characters |
17
|
|
|
for( $i = 0; $i < strlen( $ccNum ); $i++ ) { |
18
|
|
|
if( is_numeric( substr( $ccNum, $i, 1 ) ) ) { |
19
|
|
|
$digitsOnly .= substr( $ccNum, $i, 1 ); |
20
|
|
|
} |
21
|
|
|
} |
22
|
|
|
// Perform Luhn check |
23
|
|
|
$sum = 0; |
24
|
|
|
$digit = 0; |
|
|
|
|
25
|
|
|
$addend = 0; |
|
|
|
|
26
|
|
|
$timesTwo = false; |
27
|
|
|
for( $i = strlen( $digitsOnly ) - 1; $i >= 0; $i-- ) { |
28
|
|
|
$digit = substr( $digitsOnly, $i, 1 ); |
29
|
|
|
if( $timesTwo ) { |
30
|
|
|
$addend = $digit * 2; |
31
|
|
|
if( $addend > 9 ) { |
32
|
|
|
$addend -= 9; |
33
|
|
|
} |
34
|
|
|
} else { |
35
|
|
|
$addend = $digit; |
36
|
|
|
} |
37
|
|
|
$sum += $addend; |
38
|
|
|
$timesTwo = !$timesTwo; |
39
|
|
|
} |
40
|
|
|
return $sum % 10 == 0; |
41
|
|
|
} |
42
|
|
|
|
43
|
|
|
/* |
44
|
|
|
MII Digit Value Issuer Category |
45
|
|
|
0 ISO/TC 68 and other industry assignments |
46
|
|
|
1 Airlines |
47
|
|
|
2 Airlines and other industry assignments |
48
|
|
|
3 Travel and entertainment |
49
|
|
|
4 Banking and financial |
50
|
|
|
5 Banking and financial |
51
|
|
|
6 Merchandizing and banking |
52
|
|
|
7 Petroleum |
53
|
|
|
8 Telecommunications and other industry assignments |
54
|
|
|
9 National assignment |
55
|
|
|
*/ |
56
|
|
|
|
57
|
|
|
|
58
|
|
|
/* |
59
|
|
|
Issuer Identifier Card Number Length |
60
|
|
|
Diner's Club/Carte Blanche 300xxx-305xxx, |
61
|
|
|
36xxxx, 38xxxx 14 |
62
|
|
|
American Express 34xxxx, 37xxxx 15 |
63
|
|
|
VISA 4xxxxx 13, 16 |
64
|
|
|
MasterCard 51xxxx-55xxxx 16 |
65
|
|
|
Discover 6011xx 16 |
66
|
|
|
*/ |
67
|
|
|
|
68
|
|
|
|
69
|
|
|
|
70
|
|
|
// ----------------------------------------------------------------------- |
71
|
|
|
// |
72
|
|
|
// Use the form and check it status. |
73
|
|
|
// |
74
|
|
|
session_name('cform_example'); |
75
|
|
|
session_start(); |
76
|
|
|
$currentYear = date('Y'); |
77
|
|
|
$elements = array( |
78
|
|
|
'payment' => array( |
79
|
|
|
'type' => 'hidden', |
80
|
|
|
'value' => 10 |
81
|
|
|
), |
82
|
|
|
'name' => array( |
83
|
|
|
'type' => 'text', |
84
|
|
|
'label' => 'Name on credit card:', |
85
|
|
|
'required' => true, |
86
|
|
|
'autofocus' => true, |
87
|
|
|
'validation' => array('not_empty') |
88
|
|
|
), |
89
|
|
|
'address' => array( |
90
|
|
|
'type' => 'text', |
91
|
|
|
'required' => true, |
92
|
|
|
'validation' => array('not_empty') |
93
|
|
|
), |
94
|
|
|
'zip' => array( |
95
|
|
|
'type' => 'text', |
96
|
|
|
'required' => true, |
97
|
|
|
'validation' => array('not_empty') |
98
|
|
|
), |
99
|
|
|
'city' => array( |
100
|
|
|
'type' => 'text', |
101
|
|
|
'required' => true, |
102
|
|
|
'validation' => array('not_empty') |
103
|
|
|
), |
104
|
|
|
'country' => array( |
105
|
|
|
'type' => 'select', |
106
|
|
|
'options' => array( |
107
|
|
|
'default' => 'Select a country...', |
108
|
|
|
'no' => 'Norway', |
109
|
|
|
'se' => 'Sweden', |
110
|
|
|
), |
111
|
|
|
'validation' => array('not_empty', 'not_equal' => 'default') |
112
|
|
|
), |
113
|
|
|
'cctype' => array( |
114
|
|
|
'type' => 'select', |
115
|
|
|
'label' => 'Credit card type:', |
116
|
|
|
'options' => array( |
117
|
|
|
'default' => 'Select a credit card type...', |
118
|
|
|
'visa' => 'VISA', |
119
|
|
|
'mastercard' => 'Mastercard', |
120
|
|
|
'eurocard' => 'Eurocard', |
121
|
|
|
'amex' => 'American Express', |
122
|
|
|
), |
123
|
|
|
'validation' => array('not_empty', 'not_equal' => 'default') |
124
|
|
|
), |
125
|
|
|
'ccnumber' => array( |
126
|
|
|
'type' => 'text', |
127
|
|
|
'label' => 'Credit card number:', |
128
|
|
|
'validation' => array('not_empty', 'custom_test' => array('message' => 'Credit card number is not valid, try using 4408 0412 3456 7893 or 4417 1234 5678 9113 :-).', 'test' => 'isValidCCNumber')), |
129
|
|
|
), |
130
|
|
|
'expmonth' => array( |
131
|
|
|
'type' => 'select', |
132
|
|
|
'label' => 'Expiration month:', |
133
|
|
|
'options' => array( |
134
|
|
|
'default' => 'Select credit card expiration month...', |
135
|
|
|
'01' => 'January', |
136
|
|
|
'02' => 'February', |
137
|
|
|
'03' => 'March', |
138
|
|
|
'04' => 'April', |
139
|
|
|
'05' => 'May', |
140
|
|
|
'06' => 'June', |
141
|
|
|
'07' => 'July', |
142
|
|
|
'08' => 'August', |
143
|
|
|
'09' => 'September', |
144
|
|
|
'10' => 'October', |
145
|
|
|
'11' => 'November', |
146
|
|
|
'12' => 'December', |
147
|
|
|
), |
148
|
|
|
'validation' => array('not_empty', 'not_equal' => 'default') |
149
|
|
|
), |
150
|
|
|
'expyear' => array( |
151
|
|
|
'type' => 'select', |
152
|
|
|
'label' => 'Expiration year:', |
153
|
|
|
'options' => array( |
154
|
|
|
'default' => 'Select credit card expiration year...', |
155
|
|
|
$currentYear => $currentYear, |
156
|
|
|
++$currentYear => $currentYear, |
157
|
|
|
++$currentYear => $currentYear, |
158
|
|
|
++$currentYear => $currentYear, |
159
|
|
|
++$currentYear => $currentYear, |
160
|
|
|
++$currentYear => $currentYear, |
161
|
|
|
), |
162
|
|
|
'validation' => array('not_empty', 'not_equal' => 'default') |
163
|
|
|
), |
164
|
|
|
'cvc' => array( |
165
|
|
|
'type' => 'text', |
166
|
|
|
'label' => 'CVC:', |
167
|
|
|
'required' => true, |
168
|
|
|
'validation' => array('not_empty', 'numeric') |
169
|
|
|
), |
170
|
|
|
'doPay' => array( |
171
|
|
|
'type' => 'submit', |
172
|
|
|
'value' => 'Perform payment', |
173
|
|
|
'callback' => function($form) { |
|
|
|
|
174
|
|
|
// Taking some money from the creditcard. |
175
|
|
|
return true; |
176
|
|
|
} |
177
|
|
|
), |
178
|
|
|
); |
179
|
|
|
|
180
|
|
|
$form = new \Mos\HTMLForm\CForm(array(), $elements); |
181
|
|
|
|
182
|
|
|
// Check the status of the form |
183
|
|
|
$status = $form->Check(); |
184
|
|
|
|
185
|
|
|
// What to do if the form was submitted? |
186
|
|
View Code Duplication |
if($status === true) { |
|
|
|
|
187
|
|
|
$form->AddOUtput("<p><i>Form was submitted and the callback method returned true.</i></p>"); |
188
|
|
|
header("Location: " . $_SERVER['PHP_SELF']); |
189
|
|
|
} |
190
|
|
|
|
191
|
|
|
// What to do when form could not be processed? |
192
|
|
|
else if($status === false){ |
193
|
|
|
$form->AddOutput("<p><i>Form was submitted and the Check() method returned false.</i></p>"); |
194
|
|
|
header("Location: " . $_SERVER['PHP_SELF']); |
195
|
|
|
} |
196
|
|
|
|
197
|
|
|
$columns = isset($_GET['cols']) && $_GET['cols'] == 2 ? 2 : 1; |
198
|
|
|
?> |
199
|
|
|
|
200
|
|
|
|
201
|
|
|
<!doctype html> |
202
|
|
|
<meta charset=utf8> |
203
|
|
|
<title>CForm Example: Creditcard checkout with two column layout</title> |
204
|
|
|
<style> |
205
|
|
|
.cform-columns-2 .cform-column-1 { float: left; width: 50%; } |
206
|
|
|
.cform-columns-2 .cform-column-2 { float: left; width: 50%; } |
207
|
|
|
.cform-columns-2 .cform-buttonbar { clear: both; background-color: #ccc; padding: 1em; border: 1px solid #aaa; } |
208
|
|
|
.cform-columns-2 .cform-buttonbar p { margin-bottom: 0; } |
209
|
|
|
</style> |
210
|
|
|
<h1>CForm Example: Creditcard checkout with two column layout</h1> |
211
|
|
|
<p>View this form in a <a href='?cols=2'>two-column layout</a> or in a <a href='?'>standard layout</a>.</p> |
212
|
|
|
<?=$form->GetHTML(array('columns' => $columns))?> |
213
|
|
|
|
214
|
|
|
<?php $footer = "footer_mos.php"; if(is_file($footer)) include($footer) ?> |
215
|
|
|
|
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.
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.