MDL-22388 Added some checks to kill these scripts dead with an unequivocal notice...
[moodle.git] / enrol / authorize / enrol_form.php
1 <?php
3 if (!defined('MOODLE_INTERNAL')) {
4     die('Direct access to this script is forbidden.');    ///  It must be included from a Moodle page
5 }
7 require_once($CFG->libdir.'/formslib.php');
9 class enrol_authorize_form extends moodleform
10 {
11     function definition()
12     {
13         global $CFG, $USER;
15         $paymentmethodsenabled = get_list_of_payment_methods();
16         $paymentmethod = optional_param('paymentmethod', $paymentmethodsenabled[0], PARAM_ALPHA);
17         if (!in_array($paymentmethod, $paymentmethodsenabled)) {
18             print_error('invalidpaymentmethod', '', '', $paymentmethod);
19         }
21         $mform =& $this->_form;
22         $course = $this->_customdata['course'];
24         $mform->addElement('header', 'general', get_string('paymentrequired'));
25         $othermethodstr = $this->other_method_available($paymentmethod);
26         if ($othermethodstr) {
27             $mform->addElement('static', '', '<div class="mdl-right">' . $othermethodstr . '</div>', '');
28         }
30         $mform->addElement('hidden', 'id', $course->id);
31         $mform->setType('id', PARAM_INT);
33         $mform->addElement('hidden', 'paymentmethod', $paymentmethod);
34         $mform->setType('paymentmethod', PARAM_ALPHA);
36         $firstlastnamestr = (AN_METHOD_CC == $paymentmethod) ? get_string('nameoncard', 'enrol_authorize') : get_string('echeckfirslasttname', 'enrol_authorize');
37         $firstlastnamegrp = array();
38         $firstlastnamegrp[] = &$mform->createElement('text', 'firstname', '', 'size="16"');
39         $firstlastnamegrp[] = &$mform->createElement('text', 'lastname', '', 'size="16"');
40         $mform->addGroup($firstlastnamegrp, 'firstlastgrp', $firstlastnamestr, '&nbsp;', false);
41         $firstlastnamegrprules = array();
42         $firstlastnamegrprules['firstname'][] = array(get_string('missingfirstname'), 'required', null, 'client');
43         $firstlastnamegrprules['lastname'][] = array(get_string('missinglastname'), 'required', null, 'client');
44         $mform->addGroupRule('firstlastgrp', $firstlastnamegrprules);
45         $mform->setType('firstname', PARAM_ALPHANUM);
46         $mform->setType('lastname', PARAM_ALPHANUM);
47         $mform->setDefault('firstname', $USER->firstname);
48         $mform->setDefault('lastname', $USER->lastname);
50         if (AN_METHOD_CC == $paymentmethod)
51         {
52             $mform->addElement('passwordunmask', 'cc', get_string('ccno', 'enrol_authorize'), 'size="20"');
53             $mform->setType('cc', PARAM_ALPHANUM);
54             $mform->setDefault('cc', '');
55             $mform->addRule('cc', get_string('missingcc', 'enrol_authorize'), 'required', null, 'client');
56             $mform->addRule('cc', get_string('ccinvalid', 'enrol_authorize'), 'numeric', null, 'client');
58             $monthsmenu = array('' => get_string('choose'));
59             for ($i = 1; $i <= 12; $i++) {
60                 $monthsmenu[$i] = userdate(gmmktime(12, 0, 0, $i, 15, 2000), "%B");
61             }
62             $nowdate = getdate();
63             $startyear = $nowdate["year"] - 1;
64             $endyear = $startyear + 20;
65             $yearsmenu = array('' => get_string('choose'));
66             for ($i = $startyear; $i < $endyear; $i++) {
67                 $yearsmenu[$i] = $i;
68             }
69             $ccexpiregrp = array();
70             $ccexpiregrp[] = &$mform->createElement('select', 'ccexpiremm', '', $monthsmenu);
71             $ccexpiregrp[] = &$mform->createElement('select', 'ccexpireyyyy', '', $yearsmenu);
72             $mform->addGroup($ccexpiregrp, 'ccexpiregrp', get_string('ccexpire', 'enrol_authorize'), '&nbsp;', false);
73             $ccexpiregrprules = array();
74             $ccexpiregrprules['ccexpiremm'][] = array(get_string('missingccexpire', 'enrol_authorize'), 'required', null, 'client');
75             $ccexpiregrprules['ccexpireyyyy'][] = array(get_string('missingccexpire', 'enrol_authorize'), 'required', null, 'client');
76             $mform->addGroupRule('ccexpiregrp', $ccexpiregrprules);
77             $mform->setType('ccexpiremm', PARAM_INT);
78             $mform->setType('ccexpireyyyy', PARAM_INT);
79             $mform->setDefault('ccexpiremm', '');
80             $mform->setDefault('ccexpireyyyy', '');
82             $creditcardsmenu = array('' => get_string('choose')) + get_list_of_creditcards();
83             $mform->addElement('select', 'cctype', get_string('cctype', 'enrol_authorize'), $creditcardsmenu);
84             $mform->setType('cctype', PARAM_ALPHA);
85             $mform->addRule('cctype', get_string('missingcctype', 'enrol_authorize'), 'required', null, 'client');
86             $mform->setDefault('cctype', '');
88             $mform->addElement('text', 'cvv', get_string('ccvv', 'enrol_authorize'), 'size="4"');
89             $mform->setHelpButton('cvv', array('authorize/cvv',get_string('ccvv', 'enrol_authorize'),'enrol'), true);
90             $mform->setType('cvv', PARAM_ALPHANUM);
91             $mform->setDefault('cvv', '');
92             $mform->addRule('cvv', get_string('missingcvv', 'enrol_authorize'), 'required', null, 'client');
93             $mform->addRule('cvv', get_string('missingcvv', 'enrol_authorize'), 'numeric', null, 'client');
95             if (!empty($CFG->an_authcode)) {
96                 $ccauthgrp = array();
97                 $ccauthgrp[] = &$mform->createElement('checkbox', 'haveauth', null, get_string('haveauthcode', 'enrol_authorize'));
98                 $ccauthgrp[] = &$mform->createElement('static', 'nextline', null, '<br />');
99                 $ccauthgrp[] = &$mform->createElement('text', 'ccauthcode', '', 'size="8"');
100                 $mform->addGroup($ccauthgrp, 'ccauthgrp', get_string('authcode', 'enrol_authorize'), '&nbsp;', false);
101                 $mform->setHelpButton('ccauthgrp', array('authorize/authcode',get_string('authcode', 'enrol_authorize'),'enrol'), true);
103                 $ccauthgrprules = array();
104                 $ccauthgrprules['ccauthcode'][] = array(get_string('missingccauthcode', 'enrol_authorize'), 'numeric', null, 'client');
105                 $mform->addGroupRule('ccauthgrp', $ccauthgrprules);
106                 $mform->setDefault('haveauth', '');
107                 $mform->setDefault('ccauthcode', '');
108             }
110             if (!empty($CFG->an_avs)) {
111                 $mform->addElement('header', '', '&nbsp;&nbsp;' . get_string('address'), '');
113                 $mform->addElement('text', 'ccaddress', get_string('address'), 'size="30"');
114                 $mform->setType('ccaddress', PARAM_ALPHANUM);
115                 $mform->setDefault('ccaddress', $USER->address);
116                 $mform->addRule('ccaddress', get_string('missingaddress', 'enrol_authorize'), 'required', null, 'client');
118                 $citystategrp = array();
119                 $citystategrp[] = &$mform->createElement('text', 'cccity', '', 'size="14"');
120                 $citystategrp[] = &$mform->createElement('static', 'sep', null, ' - ');
121                 $citystategrp[] = &$mform->createElement('text', 'ccstate', '', 'size="8"');
122                 $mform->addGroup($citystategrp, 'citystategrp', get_string('city') . ' - ' . get_string('state'), '&nbsp;', false);
123                 $citystategrprules = array();
124                 $citystategrprules['cccity'][] = array(get_string('missingcity'), 'required', null, 'client');
125                 $mform->addGroupRule('citystategrp', $citystategrprules);
126                 $mform->setType('cccity', PARAM_ALPHANUM);
127                 $mform->setType('ccstate', PARAM_ALPHANUM);
128                 $mform->setDefault('cccity', $USER->city);
129                 $mform->setDefault('ccstate', '');
131                 $mform->addElement('select', 'cccountry', get_string('country'), get_string_manager()->get_list_of_countries());
132                 $mform->addRule('cccountry', get_string('missingcountry'), 'required', null, 'client');
133                 $mform->setType('cccountry', PARAM_ALPHA);
134                 $mform->setDefault('cccountry', $USER->country);
135             }
136             else {
137                 $mform->addElement('hidden', 'ccstate', '');
138                 $mform->setType('ccstate', PARAM_ALPHANUM);
139                 $mform->addElement('hidden', 'ccaddress', $USER->address);
140                 $mform->setType('ccaddress', PARAM_ALPHANUM);
141                 $mform->addElement('hidden', 'cccity', $USER->city);
142                 $mform->setType('cccity', PARAM_ALPHANUM);
143                 $mform->addElement('hidden', 'cccountry', $USER->country);
144                 $mform->setType('ccountry', PARAM_ALPHA);
145                 $mform->setDefault('cccountry', $USER->country);
146             }
147         }
148         elseif (AN_METHOD_ECHECK == $paymentmethod)
149         {
150             $mform->addElement('text', 'abacode', get_string('echeckabacode', 'enrol_authorize'), 'size="9" maxlength="9"');
151             $mform->setHelpButton('abacode', array('authorize/aba',get_string('echeckabacode', 'enrol_authorize'),'enrol'), true);
152             $mform->setType('abacode', PARAM_ALPHANUM);
153             $mform->setDefault('abacode', '');
154             $mform->addRule('abacode', get_string('missingaba', 'enrol_authorize'), 'required', null, 'client');
155             $mform->addRule('abacode', get_string('missingaba', 'enrol_authorize'), 'numeric', null, 'client');
157             $mform->addElement('text', 'accnum', get_string('echeckaccnum', 'enrol_authorize'), 'size="20" maxlength="20"');
158             $mform->setType('accnum', PARAM_ALPHANUM);
159             $mform->setDefault('accnum', '');
160             $mform->addRule('accnum', get_string('invalidaccnum', 'enrol_authorize'), 'required', null, 'client');
161             $mform->addRule('accnum', get_string('invalidaccnum', 'enrol_authorize'), 'numeric', null, 'client');
163             $acctypes = array();
164             $acctypesenabled = get_list_of_bank_account_types();
165             foreach ($acctypesenabled as $key) {
166                 $acctypes[$key] = get_string("echeck".strtolower($key), "enrol_authorize");
167             }
168             $acctypes = array('' => get_string('choose')) + $acctypes;
169             $mform->addElement('select', 'acctype', get_string('echeckacctype', 'enrol_authorize'), $acctypes);
170             $mform->setType('acctype', PARAM_ALPHA);
171             $mform->addRule('acctype', get_string('invalidacctype', 'enrol_authorize'), 'required', null, 'client');
172             $mform->setDefault('acctype', '');
174             $mform->addElement('text', 'bankname', get_string('echeckbankname', 'enrol_authorize'), 'size="20" maxlength="50"');
175             $mform->setType('bankname', PARAM_ALPHANUM);
176             $mform->setDefault('bankname', '');
177             $mform->addRule('bankname', get_string('missingbankname', 'enrol_authorize'), 'required', null, 'client');
178         }
180         $mform->addElement('text', 'cczip', get_string('zipcode', 'enrol_authorize'), 'size="5"');
181         $mform->setType('cczip', PARAM_ALPHANUM);
182         $mform->setDefault('cczip', '');
183         $mform->addRule('cczip', get_string('missingzip', 'enrol_authorize'), 'required', null, 'client');
185         $this->add_action_buttons(false, get_string('sendpaymentbutton', 'enrol_authorize'));
186     }
188     function validation($data, $files)
189     {
190         global $CFG;
191         $errors = parent::validation($data, $files);
193         if (AN_METHOD_CC == $data['paymentmethod'])
194         {
195             if (!in_array($data['cctype'], array_keys(get_list_of_creditcards()))) {
196                 $errors['cctype'] = get_string('missingcctype', 'enrol_authorize');
197             }
199             $expdate = sprintf("%02d", intval($data['ccexpiremm'])) . $data['ccexpireyyyy'];
200             $validcc = $this->validate_cc($data['cc'], $data['cctype'], $expdate);
201             if (!$validcc) {
202                 if ($validcc === 0) {
203                     $errors['ccexpiregrp'] = get_string('ccexpired', 'enrol_authorize');
204                 }
205                 else {
206                     $errors['cc'] = get_string('ccinvalid', 'enrol_authorize');
207                 }
208             }
210             if (!empty($CFG->an_authcode) && !empty($data['haveauth']) && empty($data['ccauthcode'])) {
211                 $errors['ccauthgrp'] = get_string('missingccauthcode', 'enrol_authorize');
212             }
213         }
214         elseif (AN_METHOD_ECHECK == $data['paymentmethod'])
215         {
216             if (!$this->validate_aba($data['abacode'])) {
217                 $errors['abacode'] = get_string('invalidaba', 'enrol_authorize');
218             }
220             if (!in_array($data['acctype'], get_list_of_bank_account_types())) {
221                 $errors['acctype'] = get_string('invalidacctype', 'enrol_authorize');
222             }
223         }
225         return $errors;
226     }
228     private function other_method_available($currentmethod)
229     {
230         $course = $this->_customdata['course'];
232         if ($currentmethod == AN_METHOD_CC) {
233             $otheravailable = in_array(AN_METHOD_ECHECK, get_list_of_payment_methods());
234             $url = 'enrol.php?id='.$course->id.'&amp;paymentmethod='.AN_METHOD_ECHECK;
235             $stringtofetch = 'usingecheckmethod';
236         }
237         else {
238             $otheravailable = in_array(AN_METHOD_CC, get_list_of_payment_methods());
239             $url = 'enrol.php?id='.$course->id.'&amp;paymentmethod='.AN_METHOD_CC;
240             $stringtofetch = 'usingccmethod';
241         }
242         if ($otheravailable) {
243             $a = new stdClass;
244             $a->url = $url;
245             return get_string($stringtofetch, "enrol_authorize", $a);
246         }
247         else {
248             return '';
249         }
250     }
252     private function validate_aba($aba)
253     {
254         if (preg_match("/^[0-9]{9}$/", $aba)) {
255             $n = 0;
256             for($i = 0; $i < 9; $i += 3) {
257                 $n += (substr($aba, $i, 1) * 3) + (substr($aba, $i + 1, 1) * 7) + (substr($aba, $i + 2, 1));
258             }
259             if ($n != 0 and $n % 10 == 0) {
260                 return true;
261             }
262         }
263         return false;
264     }
266     private function validate_cc($Num, $Name = "n/a", $Exp = "")
267     {
268         // Check the expiration date first
269         if (strlen($Exp))
270         {
271             $Month = substr($Exp, 0, 2);
272             $Year  = substr($Exp, -2);
273             $WorkDate = "$Month/01/$Year";
274             $WorkDate = strtotime($WorkDate);
275             $LastDay  = date("t", $WorkDate);
276             $Expires  = strtotime("$Month/$LastDay/$Year 11:59:59");
277             if ($Expires < time()) return 0;
278         }
280         //  Innocent until proven guilty
281         $GoodCard = true;
283         //  Get rid of any non-digits
284         $Num = preg_replace("/[^0-9]~/", "", $Num);
286         // Perform card-specific checks, if applicable
287         switch ($Name)
288         {
289             case "mcd" :
290                 $GoodCard = preg_match("/^5[1-5].{14}$/", $Num);
291                 break;
293             case "vis" :
294                 $GoodCard = preg_match("/^4.{15}$|^4.{12}$/", $Num);
295                 break;
297             case "amx" :
298                 $GoodCard = preg_match("/^3[47].{13}$/", $Num);
299                 break;
301             case "dsc" :
302                 $GoodCard = preg_match("/^6011.{12}$/", $Num);
303                 break;
305             case "dnc" :
306                 $GoodCard = preg_match("/^30[0-5].{11}$|^3[68].{12}$/", $Num);
307                 break;
309             case "jcb" :
310                 $GoodCard = preg_match("/^3.{15}$|^2131|1800.{11}$/", $Num);
311                 break;
313             case "dlt" :
314                 $GoodCard = preg_match("/^4.{15}$/", $Num);
315                 break;
317             case "swi" :
318                 $GoodCard = preg_match("/^[456].{15}$|^[456].{17,18}$/", $Num);
319                 break;
321             case "enr" :
322                 $GoodCard = preg_match("/^2014.{11}$|^2149.{11}$/", $Num);
323                 break;
324         }
326         // The Luhn formula works right to left, so reverse the number.
327         $Num = strrev($Num);
328         $Total = 0;
330         for ($x=0; $x < strlen($Num); $x++)
331         {
332             $digit = substr($Num, $x, 1);
334             // If it's an odd digit, double it
335             if ($x/2 != floor($x/2)) {
336                 $digit *= 2;
338                 // If the result is two digits, add them
339                 if (strlen($digit) == 2)
340                 $digit = substr($digit, 0, 1) + substr($digit, 1, 1);
341             }
342             // Add the current digit, doubled and added if applicable, to the Total
343             $Total += $digit;
344         }
346         // If it passed (or bypassed) the card-specific check and the Total is
347         // evenly divisible by 10, it's cool!
348         return ($GoodCard && $Total % 10 == 0);
349     }