1: <?php
2: 3: 4: 5: 6: 7:
8: class Horde_Form_Type
9: {
10: function getProperty($property)
11: {
12: $prop = '_' . $property;
13: return isset($this->$prop) ? $this->$prop : null;
14: }
15:
16: function __get($property)
17: {
18: return $this->getProperty($property);
19: }
20:
21: function setProperty($property, $value)
22: {
23: $prop = '_' . $property;
24: $this->$prop = $value;
25: }
26:
27: function __set($property, $value)
28: {
29: return $this->setProperty($property, $value);
30: }
31:
32: function init()
33: {
34: }
35:
36: function onSubmit()
37: {
38: }
39:
40: function isValid(&$var, &$vars, $value, &$message)
41: {
42: $message = '<strong>Error:</strong> Horde_Form_Type::isValid() called - should be overridden<br />';
43: return false;
44: }
45:
46: function getTypeName()
47: {
48: return str_replace('horde_form_type_', '', Horde_String::lower(get_class($this)));
49: }
50:
51: function getValues()
52: {
53: return null;
54: }
55:
56: function getInfo(&$vars, &$var, &$info)
57: {
58: $info = $var->getValue($vars);
59: }
60:
61: }
62:
63: class Horde_Form_Type_spacer extends Horde_Form_Type {
64:
65: function isValid(&$var, &$vars, $value, &$message)
66: {
67: return true;
68: }
69:
70: 71: 72:
73: function about()
74: {
75: return array('name' => Horde_Form_Translation::t("Spacer"));
76: }
77:
78: }
79:
80: class extends Horde_Form_Type {
81:
82: function isValid(&$var, &$vars, $value, &$message)
83: {
84: return true;
85: }
86:
87: 88: 89:
90: function about()
91: {
92: return array('name' => Horde_Form_Translation::t("Header"));
93: }
94:
95: }
96:
97: class Horde_Form_Type_description extends Horde_Form_Type {
98:
99: function isValid(&$var, &$vars, $value, &$message)
100: {
101: return true;
102: }
103:
104: 105: 106:
107: function about()
108: {
109: return array('name' => Horde_Form_Translation::t("Description"));
110: }
111:
112: }
113:
114: 115: 116:
117: class Horde_Form_Type_html extends Horde_Form_Type {
118:
119: function isValid(&$var, &$vars, $value, &$message)
120: {
121: return true;
122: }
123:
124: 125: 126:
127: function about()
128: {
129: return array('name' => Horde_Form_Translation::t("HTML"));
130: }
131:
132: }
133:
134: class Horde_Form_Type_number extends Horde_Form_Type {
135:
136: var $_fraction;
137:
138: function init($fraction = null)
139: {
140: $this->_fraction = $fraction;
141: }
142:
143: function isValid(&$var, &$vars, $value, &$message)
144: {
145: if ($var->isRequired() && empty($value) && ((string)(double)$value !== $value)) {
146: $message = Horde_Form_Translation::t("This field is required.");
147: return false;
148: } elseif (empty($value)) {
149: return true;
150: }
151:
152:
153: if (preg_match($this->_getValidationPattern(), $value)) {
154: return true;
155: }
156:
157: $message = Horde_Form_Translation::t("This field must be a valid number.");
158: return false;
159: }
160:
161: function _getValidationPattern()
162: {
163: static $pattern = '';
164: if (!empty($pattern)) {
165: return $pattern;
166: }
167:
168:
169: $linfo = Horde_Nls::getLocaleInfo();
170:
171:
172: $pattern = '(-)?';
173:
174:
175: if (!empty($linfo['mon_thousands_sep'])) {
176:
177: $pattern .= '((\d+)|((\d{0,3}?)([' . $linfo['mon_thousands_sep'] . ']\d{3})*?))';
178: } else {
179:
180: $pattern .= '(\d+)';
181: }
182:
183: if (empty($linfo['mon_decimal_point'])) {
184: $linfo['mon_decimal_point'] = '.';
185: }
186:
187: if (empty($this->_fraction)) {
188: $fraction = '*';
189: } else {
190: $fraction = '{0,' . $this->_fraction . '}';
191: }
192: $pattern .= '([' . $linfo['mon_decimal_point'] . '](\d' . $fraction . '))?';
193:
194:
195: $pattern = '/^' . $pattern . '$/';
196:
197: return $pattern;
198: }
199:
200: function getInfo(&$vars, &$var, &$info)
201: {
202: $value = $vars->get($var->getVarName());
203: $linfo = Horde_Nls::getLocaleInfo();
204: $value = str_replace($linfo['mon_thousands_sep'], '', $value);
205: $info = str_replace($linfo['mon_decimal_point'], '.', $value);
206: }
207:
208: 209: 210:
211: function about()
212: {
213: return array('name' => Horde_Form_Translation::t("Number"));
214: }
215:
216: }
217:
218: class Horde_Form_Type_int extends Horde_Form_Type {
219:
220: function isValid(&$var, &$vars, $value, &$message)
221: {
222: if ($var->isRequired() && empty($value) && ((string)(int)$value !== $value)) {
223: $message = Horde_Form_Translation::t("This field is required.");
224: return false;
225: }
226:
227: if (empty($value) || preg_match('/^[0-9]+$/', $value)) {
228: return true;
229: }
230:
231: $message = Horde_Form_Translation::t("This field may only contain integers.");
232: return false;
233: }
234:
235: 236: 237:
238: function about()
239: {
240: return array('name' => Horde_Form_Translation::t("Integer"));
241: }
242:
243: }
244:
245: class Horde_Form_Type_octal extends Horde_Form_Type {
246:
247: function isValid(&$var, &$vars, $value, &$message)
248: {
249: if ($var->isRequired() && empty($value) && ((string)(int)$value !== $value)) {
250: $message = Horde_Form_Translation::t("This field is required.");
251: return false;
252: }
253:
254: if (empty($value) || preg_match('/^[0-7]+$/', $value)) {
255: return true;
256: }
257:
258: $message = Horde_Form_Translation::t("This field may only contain octal values.");
259: return false;
260: }
261:
262: 263: 264:
265: function about()
266: {
267: return array('name' => Horde_Form_Translation::t("Octal"));
268: }
269:
270: }
271:
272: class Horde_Form_Type_intlist extends Horde_Form_Type {
273:
274: function isValid(&$var, &$vars, $value, &$message)
275: {
276: if (empty($value) && $var->isRequired()) {
277: $message = Horde_Form_Translation::t("This field is required.");
278: return false;
279: }
280:
281: if (empty($value) || preg_match('/^[0-9 ,]+$/', $value)) {
282: return true;
283: }
284:
285: $message = Horde_Form_Translation::t("This field must be a comma or space separated list of integers");
286: return false;
287: }
288:
289: 290: 291:
292: function about()
293: {
294: return array('name' => Horde_Form_Translation::t("Integer list"));
295: }
296:
297: }
298:
299: class Horde_Form_Type_text extends Horde_Form_Type {
300:
301: var $_regex;
302: var $_size;
303: var $_maxlength;
304:
305: 306: 307: 308: 309: 310: 311: 312: 313: 314: 315: 316: 317: 318: 319: 320: 321: 322: 323:
324: function init($regex = '', $size = 40, $maxlength = null)
325: {
326: $this->_regex = $regex;
327: $this->_size = $size;
328: $this->_maxlength = $maxlength;
329: }
330:
331: function isValid(&$var, &$vars, $value, &$message)
332: {
333: $valid = true;
334:
335: if (!empty($this->_maxlength) && Horde_String::length($value) > $this->_maxlength) {
336: $valid = false;
337: $message = sprintf(Horde_Form_Translation::t("Value is over the maximum length of %d."), $this->_maxlength);
338: } elseif ($var->isRequired() && empty($this->_regex)) {
339: $valid = strlen(trim($value)) > 0;
340:
341: if (!$valid) {
342: $message = Horde_Form_Translation::t("This field is required.");
343: }
344: } elseif (!empty($this->_regex)) {
345: $valid = preg_match($this->_regex, $value);
346:
347: if (!$valid) {
348: $message = Horde_Form_Translation::t("You must enter a valid value.");
349: }
350: }
351:
352: return $valid;
353: }
354:
355: function getSize()
356: {
357: return $this->_size;
358: }
359:
360: function getMaxLength()
361: {
362: return $this->_maxlength;
363: }
364:
365: 366: 367:
368: function about()
369: {
370: return array(
371: 'name' => Horde_Form_Translation::t("Text"),
372: 'params' => array(
373: 'regex' => array('label' => Horde_Form_Translation::t("Regex"),
374: 'type' => 'text'),
375: 'size' => array('label' => Horde_Form_Translation::t("Size"),
376: 'type' => 'int'),
377: 'maxlength' => array('label' => Horde_Form_Translation::t("Maximum length"),
378: 'type' => 'int')));
379: }
380:
381: }
382:
383: class Horde_Form_Type_stringlist extends Horde_Form_Type_text {
384:
385: 386: 387:
388: function about()
389: {
390: return array(
391: 'name' => Horde_Form_Translation::t("String list"),
392: 'params' => array(
393: 'regex' => array('label' => Horde_Form_Translation::t("Regex"),
394: 'type' => 'text'),
395: 'size' => array('label' => Horde_Form_Translation::t("Size"),
396: 'type' => 'int'),
397: 'maxlength' => array('label' => Horde_Form_Translation::t("Maximum length"),
398: 'type' => 'int')),
399: );
400: }
401:
402: }
403:
404: class Horde_Form_Type_stringarray extends Horde_Form_Type_stringlist {
405:
406: function getInfo(&$vars, &$var, &$info)
407: {
408: $info = array_map('trim', explode(',', $vars->get($var->getVarName())));
409: }
410:
411: 412: 413:
414: function about()
415: {
416: return array(
417: 'name' => Horde_Form_Translation::t("String list returning an array"),
418: 'params' => array(
419: 'regex' => array('label' => Horde_Form_Translation::t("Regex"),
420: 'type' => 'text'),
421: 'size' => array('label' => Horde_Form_Translation::t("Size"),
422: 'type' => 'int'),
423: 'maxlength' => array('label' => Horde_Form_Translation::t("Maximum length"),
424: 'type' => 'int')),
425: );
426: }
427:
428: }
429:
430: class Horde_Form_Type_phone extends Horde_Form_Type {
431:
432: 433: 434: 435: 436:
437: var $_size;
438:
439: 440: 441:
442: function init($size = 15)
443: {
444: $this->_size = $size;
445: }
446:
447: function isValid(&$var, &$vars, $value, &$message)
448: {
449: if (!strlen(trim($value))) {
450: if ($var->isRequired()) {
451: $message = Horde_Form_Translation::t("This field is required.");
452: return false;
453: }
454: } elseif (!preg_match('/^\+?[\d()\-\/. ]*$/', $value)) {
455: $message = Horde_Form_Translation::t("You must enter a valid phone number, digits only with an optional '+' for the international dialing prefix.");
456: return false;
457: }
458:
459: return true;
460: }
461:
462: function getSize()
463: {
464: return $this->_size;
465: }
466:
467: 468: 469:
470: function about()
471: {
472: return array(
473: 'name' => Horde_Form_Translation::t("Phone number"),
474: 'params' => array(
475: 'size' => array('label' => Horde_Form_Translation::t("Size"),
476: 'type' => 'int'),
477: ),
478: );
479: }
480:
481: }
482:
483: class Horde_Form_Type_cellphone extends Horde_Form_Type_phone {
484:
485: 486: 487:
488: function about()
489: {
490: return array('name' => Horde_Form_Translation::t("Mobile phone number"));
491: }
492:
493: }
494:
495: class Horde_Form_Type_ipaddress extends Horde_Form_Type_text {
496:
497: function isValid(&$var, &$vars, $value, &$message)
498: {
499: $valid = true;
500:
501: if (strlen(trim($value)) > 0) {
502: $ip = explode('.', $value);
503: $valid = (count($ip) == 4);
504: if ($valid) {
505: foreach ($ip as $part) {
506: if (!is_numeric($part) ||
507: $part > 255 ||
508: $part < 0) {
509: $valid = false;
510: break;
511: }
512: }
513: }
514:
515: if (!$valid) {
516: $message = Horde_Form_Translation::t("Please enter a valid IP address.");
517: }
518: } elseif ($var->isRequired()) {
519: $valid = false;
520: $message = Horde_Form_Translation::t("This field is required.");
521: }
522:
523: return $valid;
524: }
525:
526: 527: 528:
529: function about()
530: {
531: return array('name' => Horde_Form_Translation::t("IP address"));
532: }
533:
534: }
535:
536: class Horde_Form_Type_ip6address extends Horde_Form_Type_text {
537:
538: function isValid(&$var, &$vars, $value, &$message)
539: {
540: $valid = true;
541:
542: if (strlen(trim($value)) > 0) {
543: $valid = @inet_pton($value);
544:
545: if ($valid === false) {
546: $message = Horde_Form_Translation::t("Please enter a valid IP address.");
547: }
548: } elseif ($var->isRequired()) {
549: $valid = false;
550: $message = Horde_Form_Translation::t("This field is required.");
551: }
552:
553: return true;
554: }
555:
556: 557: 558:
559: function about()
560: {
561: return array('name' => Horde_Form_Translation::t("IPv6 address"));
562: }
563:
564: }
565:
566: class Horde_Form_Type_longtext extends Horde_Form_Type_text {
567:
568: var $_rows;
569: var $_cols;
570: var $_helper = array();
571:
572: function init($rows = 8, $cols = 80, $helper = array())
573: {
574: if (!is_array($helper)) {
575: $helper = array($helper);
576: }
577:
578: $this->_rows = $rows;
579: $this->_cols = $cols;
580: $this->_helper = $helper;
581: }
582:
583: function getRows()
584: {
585: return $this->_rows;
586: }
587:
588: function getCols()
589: {
590: return $this->_cols;
591: }
592:
593: function hasHelper($option = '')
594: {
595: if (empty($option)) {
596: 597:
598: return !empty($this->_helper);
599: } elseif (empty($this->_helper)) {
600:
601: return false;
602: } else {
603:
604: return in_array($option, $this->_helper);
605: }
606: }
607:
608: 609: 610:
611: function about()
612: {
613: return array(
614: 'name' => Horde_Form_Translation::t("Long text"),
615: 'params' => array(
616: 'rows' => array('label' => Horde_Form_Translation::t("Number of rows"),
617: 'type' => 'int'),
618: 'cols' => array('label' => Horde_Form_Translation::t("Number of columns"),
619: 'type' => 'int'),
620: 'helper' => array('label' => Horde_Form_Translation::t("Helpers"),
621: 'type' => 'stringarray')));
622: }
623:
624: }
625:
626: class Horde_Form_Type_countedtext extends Horde_Form_Type_longtext {
627:
628: var $_chars;
629:
630: function init($rows = null, $cols = null, $chars = 1000)
631: {
632: parent::init($rows, $cols);
633: $this->_chars = $chars;
634: }
635:
636: function isValid(&$var, &$vars, $value, &$message)
637: {
638: $valid = true;
639:
640: $length = Horde_String::length(trim($value));
641:
642: if ($var->isRequired() && $length <= 0) {
643: $valid = false;
644: $message = Horde_Form_Translation::t("This field is required.");
645: } elseif ($length > $this->_chars) {
646: $valid = false;
647: $message = sprintf(Horde_Form_Translation::ngettext("There are too many characters in this field. You have entered %d character; ", "There are too many characters in this field. You have entered %d characters; ", $length), $length)
648: . sprintf(Horde_Form_Translation::t("you must enter less than %d."), $this->_chars);
649: }
650:
651: return $valid;
652: }
653:
654: function getChars()
655: {
656: return $this->_chars;
657: }
658:
659: 660: 661:
662: function about()
663: {
664: return array(
665: 'name' => Horde_Form_Translation::t("Counted text"),
666: 'params' => array(
667: 'rows' => array('label' => Horde_Form_Translation::t("Number of rows"),
668: 'type' => 'int'),
669: 'cols' => array('label' => Horde_Form_Translation::t("Number of columns"),
670: 'type' => 'int'),
671: 'chars' => array('label' => Horde_Form_Translation::t("Number of characters"),
672: 'type' => 'int')));
673: }
674:
675: }
676:
677: class Horde_Form_Type_address extends Horde_Form_Type_longtext {
678:
679: function parse($address)
680: {
681: $info = array();
682: $aus_state_regex = '(?:ACT|NSW|NT|QLD|SA|TAS|VIC|WA)';
683:
684: if (preg_match('/(?s)(.*?)(?-s)\r?\n(?:(.*?)\s+)?((?:A[BL]|B[ABDHLNRST]?|C[ABFHMORTVW]|D[ADEGHLNTY]|E[CHNX]?|F[KY]|G[LUY]?|H[ADGPRSUX]|I[GMPV]|JE|K[ATWY]|L[ADELNSU]?|M[EKL]?|N[EGNPRW]?|O[LX]|P[AEHLOR]|R[GHM]|S[AEGKLMNOPRSTWY]?|T[ADFNQRSW]|UB|W[ACDFNRSV]?|YO|ZE)\d(?:\d|[A-Z])? \d[A-Z]{2})/', $address, $addressParts)) {
685:
686: $info = array('country' => 'uk', 'zip' => $addressParts[3]);
687: if (!empty($addressParts[1])) {
688: $info['street'] = $addressParts[1];
689: }
690: if (!empty($addressParts[2])) {
691: $info['city'] = $addressParts[2];
692: }
693: } elseif (preg_match('/\b' . $aus_state_regex . '\b/', $address)) {
694:
695:
696: $addressLines = preg_split('/\r?\n/', $address);
697: $info = array('country' => 'au');
698: for ($i = 0; $i < count($addressLines); $i++) {
699:
700: if (preg_match('/(\d+\s*\/\s*)?(\d+|\d+[a-zA-Z])\s+([a-zA-Z ]*)/', $addressLines[$i], $lineParts)) {
701: $info['street'] = $addressLines[$i];
702: $info['streetNumber'] = $lineParts[2];
703: $info['streetName'] = $lineParts[3];
704: }
705:
706: if (preg_match('/([a-zA-Z ]*),?\s+(' . $aus_state_regex . ')/', $addressLines[$i], $lineParts)) {
707: $info['city'] = $lineParts[1];
708: $info['state'] = $lineParts[2];
709: }
710:
711: if (preg_match('/(' . $aus_state_regex . ')\s+(\d{4})/', $addressLines[$i], $lineParts)) {
712: $info['state'] = $lineParts[1];
713: $info['zip'] = $lineParts[2];
714: }
715: }
716: } elseif (preg_match('/(?s)(.*?)(?-s)\r?\n(.*)\s*,\s*(\w+)\.?\s+(\d+|[a-zA-Z]\d[a-zA-Z]\s?\d[a-zA-Z]\d)/', $address, $addressParts)) {
717:
718: $info = array('country' => 'us');
719: if (!empty($addressParts[4]) &&
720: preg_match('|[a-zA-Z]\d[a-zA-Z]\s?\d[a-zA-Z]\d|', $addressParts[4])) {
721: $info['country'] = 'ca';
722: }
723: if (!empty($addressParts[1])) {
724: $info['street'] = $addressParts[1];
725: }
726: if (!empty($addressParts[2])) {
727: $info['city'] = $addressParts[2];
728: }
729: if (!empty($addressParts[3])) {
730: $info['state'] = $addressParts[3];
731: }
732: if (!empty($addressParts[4])) {
733: $info['zip'] = $addressParts[4];
734: }
735: } elseif (preg_match('/(?:(?s)(.*?)(?-s)(?:\r?\n|,\s*))?(?:([A-Z]{1,3})-)?(\d{4,5})\s+(.*)(?:\r?\n(.*))?/i', $address, $addressParts)) {
736:
737: $info = array();
738: if (!empty($addressParts[1])) {
739: $info['street'] = $addressParts[1];
740: }
741: if (!empty($addressParts[2])) {
742: include 'Horde/Nls/Carsigns.php';
743: $country = array_search(Horde_String::upper($addressParts[2]), $carsigns);
744: if ($country) {
745: $info['country'] = $country;
746: }
747: }
748: if (!empty($addressParts[5])) {
749: include 'Horde/Nls/Countries.php';
750: $country = array_search($addressParts[5], $countries);
751: if ($country) {
752: $info['country'] = Horde_String::lower($country);
753: } elseif (!isset($info['street'])) {
754: $info['street'] = trim($addressParts[5]);
755: } else {
756: $info['street'] .= "\n" . $addressParts[5];
757: }
758: }
759: if (!empty($addressParts[3])) {
760: $info['zip'] = $addressParts[3];
761: }
762: if (!empty($addressParts[4])) {
763: $info['city'] = trim($addressParts[4]);
764: }
765: }
766:
767: return $info;
768: }
769:
770: 771: 772:
773: function about()
774: {
775: return array(
776: 'name' => Horde_Form_Translation::t("Address"),
777: 'params' => array(
778: 'rows' => array('label' => Horde_Form_Translation::t("Number of rows"),
779: 'type' => 'int'),
780: 'cols' => array('label' => Horde_Form_Translation::t("Number of columns"),
781: 'type' => 'int')));
782: }
783:
784: }
785:
786: class Horde_Form_Type_addresslink extends Horde_Form_Type_address {
787:
788: function isValid(&$var, &$vars, $value, &$message)
789: {
790: return true;
791: }
792:
793: 794: 795:
796: function about()
797: {
798: return array('name' => Horde_Form_Translation::t("Address Link"));
799: }
800:
801: }
802:
803: class Horde_Form_Type_pgp extends Horde_Form_Type_longtext {
804:
805: 806: 807: 808: 809:
810: var $_gpg;
811:
812: 813: 814: 815: 816:
817: var $_temp;
818:
819: function init($gpg, $temp_dir = null, $rows = null, $cols = null)
820: {
821: $this->_gpg = $gpg;
822: $this->_temp = $temp_dir;
823: parent::init($rows, $cols);
824: }
825:
826: 827: 828: 829: 830:
831: function getPGPParams()
832: {
833: return array('program' => $this->_gpg, 'temp' => $this->_temp);
834: }
835:
836: 837: 838:
839: function about()
840: {
841: return array(
842: 'name' => Horde_Form_Translation::t("PGP Key"),
843: 'params' => array(
844: 'gpg' => array('label' => Horde_Form_Translation::t("Path to the GnuPG binary"),
845: 'type' => 'string'),
846: 'temp_dir' => array('label' => Horde_Form_Translation::t("A temporary directory"),
847: 'type' => 'string'),
848: 'rows' => array('label' => Horde_Form_Translation::t("Number of rows"),
849: 'type' => 'int'),
850: 'cols' => array('label' => Horde_Form_Translation::t("Number of columns"),
851: 'type' => 'int')));
852: }
853:
854: }
855:
856: class Horde_Form_Type_smime extends Horde_Form_Type_longtext {
857:
858: 859: 860: 861: 862:
863: var $_temp;
864:
865: function init($temp_dir = null, $rows = null, $cols = null)
866: {
867: $this->_temp = $temp_dir;
868: parent::init($rows, $cols);
869: }
870:
871: 872: 873: 874: 875:
876: function getSMIMEParams()
877: {
878: return array('temp' => $this->_temp);
879: }
880:
881: 882: 883:
884: function about()
885: {
886: return array(
887: 'name' => Horde_Form_Translation::t("S/MIME Key"),
888: 'params' => array(
889: 'temp_dir' => array('label' => Horde_Form_Translation::t("A temporary directory"),
890: 'type' => 'string'),
891: 'rows' => array('label' => Horde_Form_Translation::t("Number of rows"),
892: 'type' => 'int'),
893: 'cols' => array('label' => Horde_Form_Translation::t("Number of columns"),
894: 'type' => 'int')));
895: }
896:
897: }
898:
899: class Horde_Form_Type_country extends Horde_Form_Type_enum {
900:
901: function init($prompt = null)
902: {
903: parent::init(Horde_Nls::getCountryISO(), $prompt);
904: }
905:
906: 907: 908:
909: function about()
910: {
911: return array(
912: 'name' => Horde_Form_Translation::t("Country drop down list"),
913: 'params' => array(
914: 'prompt' => array('label' => Horde_Form_Translation::t("Prompt text"),
915: 'type' => 'text')));
916: }
917:
918: }
919:
920: class Horde_Form_Type_file extends Horde_Form_Type {
921:
922: function isValid(&$var, &$vars, $value, &$message)
923: {
924: if ($var->isRequired()) {
925: try {
926: $GLOBALS['browser']->wasFileUploaded($var->getVarName());
927: } catch (Horde_Browser_Exception $e) {
928: $message = $e->getMessage();
929: return false;
930: }
931: }
932:
933: return true;
934: }
935:
936: function getInfo(&$vars, &$var, &$info)
937: {
938: $name = $var->getVarName();
939: try {
940: $GLOBALS['browser']->wasFileUploaded($name);
941: $info['name'] = Horde_Util::dispelMagicQuotes($_FILES[$name]['name']);
942: $info['type'] = $_FILES[$name]['type'];
943: $info['tmp_name'] = $_FILES[$name]['tmp_name'];
944: $info['file'] = $_FILES[$name]['tmp_name'];
945: $info['error'] = $_FILES[$name]['error'];
946: $info['size'] = $_FILES[$name]['size'];
947: } catch (Horde_Browser_Exception $e) {}
948: }
949:
950: 951: 952:
953: function about()
954: {
955: return array('name' => Horde_Form_Translation::t("File upload"));
956: }
957:
958: }
959:
960: class Horde_Form_Type_image extends Horde_Form_Type {
961:
962: 963: 964: 965: 966:
967: var $_uploaded = null;
968:
969: 970: 971: 972: 973:
974: var $_show_upload = true;
975:
976: 977: 978: 979: 980:
981: var $_show_keeporig = false;
982:
983: 984: 985: 986: 987:
988: var $_max_filesize = null;
989:
990: 991: 992: 993: 994:
995: var $_img;
996:
997: 998: 999: 1000: 1001:
1002: var $_random;
1003:
1004: function init($show_upload = true, $show_keeporig = false, $max_filesize = null)
1005: {
1006: $this->_show_upload = $show_upload;
1007: $this->_show_keeporig = $show_keeporig;
1008: $this->_max_filesize = $max_filesize;
1009: }
1010:
1011: function onSubmit(&$var, &$vars)
1012: {
1013:
1014: if ($vars->get('remove_' . $var->getVarName())) {
1015: $GLOBALS['session']->remove('horde', 'form/' . $this->getRandomId());
1016: $this->_img = null;
1017: return;
1018: }
1019:
1020:
1021: $this->getImage($vars, $var);
1022:
1023: 1024:
1025: if ($vars->get('do_' . $var->getVarName())) {
1026: $var->form->setSubmitted(false);
1027: if ($this->_uploaded instanceof Horde_Browser_Exception) {
1028: $this->_img = array('hash' => $this->getRandomId(),
1029: 'error' => $this->_uploaded->getMessage());
1030: }
1031: }
1032: }
1033:
1034: function isValid(&$var, &$vars, $value, &$message)
1035: {
1036:
1037: if ($vars->get('remove_' . $var->getVarName())) {
1038: return true;
1039: }
1040:
1041:
1042: $this->getImage($vars, $var);
1043: $field = $vars->get($var->getVarName());
1044:
1045:
1046: if ($this->_uploaded instanceof Horde_Browser_Exception) {
1047:
1048: if (!$var->isRequired() && empty($field['hash']) &&
1049: $this->_uploaded->getCode() == UPLOAD_ERR_NO_FILE) {
1050: return true;
1051: }
1052:
1053: if (($this->_uploaded->getCode() == UPLOAD_ERR_NO_FILE) &&
1054: empty($field['hash'])) {
1055:
1056: $message = Horde_Form_Translation::t("This field is required.");
1057: return false;
1058: } elseif (!empty($field['hash'])) {
1059: if ($this->_img && isset($this->_img['error'])) {
1060: $message = $this->_img['error'];
1061: return false;
1062: }
1063:
1064: return true;
1065: } else {
1066:
1067: $message = $this->_uploaded->getMessage();
1068: return false;
1069: }
1070: } elseif (empty($this->_img['img']['size'])) {
1071: $message = Horde_Form_Translation::t("The image file size could not be determined or it was 0 bytes. The upload may have been interrupted.");
1072: return false;
1073: } elseif ($this->_max_filesize &&
1074: $this->_img['img']['size'] > $this->_max_filesize) {
1075: $message = sprintf(Horde_Form_Translation::t("The image file was larger than the maximum allowed size (%d bytes)."), $this->_max_filesize);
1076: return false;
1077: }
1078:
1079: return true;
1080: }
1081:
1082: function getInfo(&$vars, &$var, &$info)
1083: {
1084:
1085: $this->getImage($vars, $var);
1086:
1087:
1088: $value = $var->getValue($vars);
1089: $info = $this->_img['img'];
1090: if (empty($info['file'])) {
1091: unset($info['file']);
1092: return;
1093: }
1094: if ($this->_show_keeporig) {
1095: $info['keep_orig'] = !empty($value['keep_orig']);
1096: }
1097:
1098:
1099: $info['uploaded'] = &$this->_uploaded;
1100:
1101:
1102: if ($this->_show_keeporig && $info['keep_orig']) {
1103:
1104: $info['orig_file'] = Horde::getTempDir() . '/' . $info['file'];
1105: $info['file'] = Horde::getTempDir() . '/mod_' . $info['file'];
1106:
1107: if (!file_exists($info['file'])) {
1108: $info['file'] = $info['orig_file'];
1109: unset($info['orig_file']);
1110: }
1111: } else {
1112:
1113: $mod_file = Horde::getTempDir() . '/mod_' . $info['file'];
1114: $info['file'] = Horde::getTempDir() . '/' . $info['file'];
1115:
1116: if (file_exists($mod_file)) {
1117:
1118: unlink($info['file']);
1119: rename($mod_file, $info['file']);
1120: }
1121: }
1122: }
1123:
1124: 1125: 1126: 1127: 1128:
1129: function _getUpload(&$vars, &$var)
1130: {
1131: global $session;
1132:
1133: 1134:
1135: if (!empty($this->_img)) {
1136: return true;
1137: }
1138:
1139:
1140: $varname = $var->getVarName();
1141:
1142: try {
1143: $GLOBALS['browser']->wasFileUploaded($varname . '[new]');
1144: $this->_uploaded = true;
1145:
1146: 1147:
1148: $this->_img['img']['type'] = $this->getUploadedFileType($varname . '[new]');
1149:
1150:
1151: Horde_Array::getArrayParts($varname . '[new]', $base, $keys);
1152:
1153:
1154: $keys_path = array_merge(array($base, 'tmp_name'), $keys);
1155: $this->_img['img']['file'] = Horde_Array::getElement($_FILES, $keys_path);
1156:
1157:
1158: $keys_path = array_merge(array($base, 'name'), $keys);
1159: $this->_img['img']['name'] = Horde_Array::getElement($_FILES, $keys_path);
1160:
1161:
1162: $keys_path = array_merge(array($base, 'size'), $keys);
1163: $this->_img['img']['size'] = Horde_Array::getElement($_FILES, $keys_path);
1164:
1165:
1166: $upload = $vars->get($var->getVarName());
1167: if (!empty($upload['hash'])) {
1168: $upload['img'] = $session->get('horde', 'form/' . $upload['hash']);
1169: $session->remove('horde', 'form/' . $upload['hash']);
1170: }
1171:
1172: 1173:
1174: if (!empty($upload['img']['file'])) {
1175: $tmp_file = Horde::getTempDir() . '/' . $upload['img']['file'];
1176: } else {
1177: $tmp_file = Horde::getTempFile('Horde', false);
1178: }
1179:
1180:
1181: move_uploaded_file($this->_img['img']['file'], $tmp_file);
1182: $this->_img['img']['file'] = basename($tmp_file);
1183: } catch (Horde_Browser_Exception $e) {
1184: $this->_uploaded = $e;
1185:
1186:
1187: $upload = $vars->get($var->getVarName());
1188:
1189:
1190: if ($vars->get('remove_' . $var->getVarName())) {
1191: $this->_img = null;
1192: $session->remove('horde', 'form/' . $upload['hash']);
1193: return;
1194: }
1195:
1196: if ($this->_uploaded->getCode() == 4 &&
1197: !empty($upload['hash']) &&
1198: $session->exists('horde', 'form/' . $upload['hash'])) {
1199: $this->_img['img'] = $session->get('horde', 'form/' . $upload['hash']);
1200: $session->remove('horde', 'form/' . $upload['hash']);
1201: if (isset($this->_img['error'])) {
1202: $this->_uploaded = PEAR::raiseError($this->_img['error']);
1203: }
1204: }
1205: }
1206: if (isset($this->_img['img'])) {
1207: $session->set('horde', 'form/' . $this->getRandomId(), $this->_img['img']);
1208: }
1209: }
1210:
1211: function getUploadedFileType($field)
1212: {
1213:
1214: $index = Horde_Array::getArrayParts($field, $base, $keys);
1215:
1216: if ($index) {
1217:
1218: $keys_path = array_merge(array($base, 'type'), $keys);
1219: $type = Horde_Array::getElement($_FILES, $keys_path);
1220: $keys_path = array_merge(array($base, 'tmp_name'), $keys);
1221: $tmp_name = Horde_Array::getElement($_FILES, $keys_path);
1222: } else {
1223:
1224: $type = $_FILES[$field]['type'];
1225: $tmp_name = $_FILES[$field]['tmp_name'];
1226: }
1227:
1228: if (empty($type) || ($type == 'application/octet-stream')) {
1229:
1230: if (!($type = Horde_Mime_Magic::analyzeFile($tmp_name, isset($GLOBALS['conf']['mime']['magic_db']) ? $GLOBALS['conf']['mime']['magic_db'] : null))) {
1231: if ($index) {
1232:
1233: $keys_path = array_merge(array($base, 'name'), $keys);
1234: $name = Horde_Array::getElement($_FILES, $keys_path);
1235:
1236:
1237: $type = Horde_Mime_Magic::filenameToMime($name);
1238:
1239:
1240: $keys_path = array_merge(array($base, 'type'), $keys);
1241: Horde_Array::getElement($_FILES, $keys_path, $type);
1242: } else {
1243:
1244: $type = Horde_Mime_Magic::filenameToMime($_FILES[$field]['name']);
1245:
1246:
1247: $_FILES[$field]['type'] = Horde_Mime_Magic::filenameToMime($_FILES[$field]['name']);
1248: }
1249: }
1250: }
1251:
1252: return $type;
1253: }
1254:
1255: 1256: 1257: 1258: 1259:
1260: function getImage($vars, $var)
1261: {
1262: $this->_getUpload($vars, $var);
1263: if (!isset($this->_img)) {
1264: $image = $vars->get($var->getVarName());
1265: if ($image) {
1266: $this->loadImageData($image);
1267: if (isset($image['img'])) {
1268: $this->_img = $image;
1269: $GLOBALS['session']->set('horde', 'form/' . $this->getRandomId(), $this->_img['img']);
1270: }
1271: }
1272: }
1273: return $this->_img;
1274: }
1275:
1276: 1277: 1278: 1279: 1280: 1281: 1282: 1283:
1284: function loadImageData(&$image)
1285: {
1286:
1287: if (!isset($image['load'])) {
1288: return;
1289: }
1290:
1291:
1292: $tmp_file = Horde::getTempDir() . '/' . $image['load']['file'];
1293: if ($fd = fopen($tmp_file, 'w')) {
1294: fwrite($fd, $image['load']['data']);
1295: fclose($fd);
1296: }
1297:
1298: $image['img'] = array('file' => $image['load']['file']);
1299: unset($image['load']);
1300: }
1301:
1302: function getRandomId()
1303: {
1304: if (!isset($this->_random)) {
1305: $this->_random = uniqid(mt_rand());
1306: }
1307: return $this->_random;
1308: }
1309:
1310: 1311: 1312:
1313: function about()
1314: {
1315: return array(
1316: 'name' => Horde_Form_Translation::t("Image upload"),
1317: 'params' => array(
1318: 'show_upload' => array('label' => Horde_Form_Translation::t("Show upload?"),
1319: 'type' => 'boolean'),
1320: 'show_keeporig' => array('label' => Horde_Form_Translation::t("Show option to keep original?"),
1321: 'type' => 'boolean'),
1322: 'max_filesize' => array('label' => Horde_Form_Translation::t("Maximum file size in bytes"),
1323: 'type' => 'int')));
1324: }
1325:
1326: }
1327:
1328: class Horde_Form_Type_boolean extends Horde_Form_Type {
1329:
1330: function isValid(&$var, &$vars, $value, &$message)
1331: {
1332: return true;
1333: }
1334:
1335: function getInfo(&$vars, &$var, &$info)
1336: {
1337: $info = is_bool($var->getValue($vars)) ? $var->getValue($vars) : Horde_String::lower($vars->get($var->getVarName())) == 'on';
1338: }
1339:
1340: 1341: 1342:
1343: function about()
1344: {
1345: return array('name' => Horde_Form_Translation::t("True or false"));
1346: }
1347:
1348: }
1349:
1350: class Horde_Form_Type_link extends Horde_Form_Type {
1351:
1352: 1353: 1354: 1355: 1356: 1357:
1358: var $values;
1359:
1360: function init($values)
1361: {
1362: $this->values = $values;
1363: }
1364:
1365: function isValid(&$var, &$vars, $value, &$message)
1366: {
1367: return true;
1368: }
1369:
1370: 1371: 1372:
1373: function about()
1374: {
1375: return array(
1376: 'name' => Horde_Form_Translation::t("Link"),
1377: 'params' => array(
1378: 'url' => array(
1379: 'label' => Horde_Form_Translation::t("Link URL"),
1380: 'type' => 'text'),
1381: 'text' => array(
1382: 'label' => Horde_Form_Translation::t("Link text"),
1383: 'type' => 'text'),
1384: 'target' => array(
1385: 'label' => Horde_Form_Translation::t("Link target"),
1386: 'type' => 'text'),
1387: 'onclick' => array(
1388: 'label' => Horde_Form_Translation::t("Onclick event"),
1389: 'type' => 'text'),
1390: 'title' => array(
1391: 'label' => Horde_Form_Translation::t("Link title attribute"),
1392: 'type' => 'text'),
1393: 'accesskey' => array(
1394: 'label' => Horde_Form_Translation::t("Link access key"),
1395: 'type' => 'text')));
1396: }
1397:
1398: }
1399:
1400: class Horde_Form_Type_email extends Horde_Form_Type {
1401:
1402: 1403: 1404: 1405: 1406:
1407: var $_allow_multi = false;
1408:
1409: 1410: 1411: 1412: 1413:
1414: var $_strip_domain = false;
1415:
1416: 1417: 1418: 1419: 1420:
1421: var $_link_compose = false;
1422:
1423: 1424: 1425: 1426: 1427:
1428: var $_check_smtp = false;
1429:
1430: 1431: 1432: 1433: 1434:
1435: var $_link_name;
1436:
1437: 1438: 1439: 1440: 1441:
1442: var $_delimiters = ',';
1443:
1444: 1445: 1446: 1447: 1448:
1449: var $_size;
1450:
1451: 1452: 1453: 1454: 1455: 1456: 1457: 1458: 1459: 1460:
1461: function init($allow_multi = false, $strip_domain = false,
1462: $link_compose = false, $link_name = null,
1463: $delimiters = ',', $size = null)
1464: {
1465: $this->_allow_multi = $allow_multi;
1466: $this->_strip_domain = $strip_domain;
1467: $this->_link_compose = $link_compose;
1468: $this->_link_name = $link_name;
1469: $this->_delimiters = $delimiters;
1470: $this->_size = $size;
1471: }
1472:
1473: 1474:
1475: function isValid(&$var, &$vars, $value, &$message)
1476: {
1477:
1478: $emails = $this->splitEmailAddresses($value);
1479:
1480:
1481: if (!$this->_allow_multi && count($emails) > 1) {
1482: $message = Horde_Form_Translation::t("Only one email address is allowed.");
1483: return false;
1484: }
1485:
1486:
1487: $nonEmpty = 0;
1488: foreach ($emails as $email) {
1489: if (!strlen($email)) {
1490: continue;
1491: }
1492: if (!$this->validateEmailAddress($email)) {
1493: $message = sprintf(Horde_Form_Translation::t("\"%s\" is not a valid email address."), htmlspecialchars($email));
1494: return false;
1495: }
1496: ++$nonEmpty;
1497: }
1498:
1499: if (!$nonEmpty && $var->isRequired()) {
1500: if ($this->_allow_multi) {
1501: $message = Horde_Form_Translation::t("You must enter at least one email address.");
1502: } else {
1503: $message = Horde_Form_Translation::t("You must enter an email address.");
1504: }
1505: return false;
1506: }
1507:
1508: return true;
1509: }
1510:
1511: 1512: 1513: 1514: 1515: 1516: 1517: 1518: 1519:
1520: function splitEmailAddresses($string)
1521: {
1522: $quotes = array('"', "'");
1523: $emails = array();
1524: $pos = 0;
1525: $in_quote = null;
1526: $in_group = false;
1527: $prev = null;
1528:
1529: if (!strlen($string)) {
1530: return array();
1531: }
1532:
1533: $char = $string[0];
1534: if (in_array($char, $quotes)) {
1535: $in_quote = $char;
1536: } elseif ($char == ':') {
1537: $in_group = true;
1538: } elseif (strpos($this->_delimiters, $char) !== false) {
1539: $emails[] = '';
1540: $pos = 1;
1541: }
1542:
1543: for ($i = 1, $iMax = strlen($string); $i < $iMax; ++$i) {
1544: $char = $string[$i];
1545: if (in_array($char, $quotes)) {
1546: if ($prev !== '\\') {
1547: if ($in_quote === $char) {
1548: $in_quote = null;
1549: } elseif (is_null($in_quote)) {
1550: $in_quote = $char;
1551: }
1552: }
1553: } elseif ($in_group) {
1554: if ($char == ';') {
1555: $emails[] = substr($string, $pos, $i - $pos + 1);
1556: $pos = $i + 1;
1557: $in_group = false;
1558: }
1559: } elseif ($char == ':') {
1560: $in_group = true;
1561: } elseif (strpos($this->_delimiters, $char) !== false &&
1562: $prev !== '\\' &&
1563: is_null($in_quote)) {
1564: $emails[] = substr($string, $pos, $i - $pos);
1565: $pos = $i + 1;
1566: }
1567: $prev = $char;
1568: }
1569:
1570: if ($pos != $i) {
1571:
1572: $emails[] = substr($string, $pos, $i - $pos);
1573: }
1574:
1575: return $emails;
1576: }
1577:
1578: 1579: 1580: 1581: 1582:
1583: function validateEmailAddress($email)
1584: {
1585: $result = $this->_isRfc3696ValidEmailAddress($email);
1586: if ($result && $this->_check_smtp) {
1587: $result = $this->validateEmailAddressSmtp($email);
1588: }
1589:
1590: return $result;
1591: }
1592:
1593: 1594: 1595: 1596: 1597: 1598: 1599:
1600: function validateEmailAddressSmtp($email)
1601: {
1602: list(, $maildomain) = explode('@', $email, 2);
1603:
1604:
1605: if (function_exists('getmxrr') &&
1606: @getmxrr($maildomain, $mxhosts, $mxpriorities)) {
1607:
1608: array_multisort($mxpriorities, $mxhosts);
1609: $mailhost = $mxhosts[0];
1610: } else {
1611:
1612:
1613: $mailhost = $maildomain;
1614: }
1615:
1616: $fp = @fsockopen($mailhost, 25, $errno, $errstr, 5);
1617: if (!$fp) {
1618: return false;
1619: }
1620:
1621:
1622: fgets($fp, 4096);
1623:
1624:
1625: fputs($fp, "HELO $mailhost\r\n");
1626: fgets($fp, 4096);
1627:
1628:
1629: fputs($fp, "MAIL FROM: <root@example.com>\r\n");
1630: fgets($fp, 4096);
1631:
1632:
1633: fputs($fp, "RCPT TO: <$email>\r\n");
1634: $result = trim(fgets($fp, 4096));
1635:
1636:
1637: fputs($fp, "QUIT\r\n");
1638: fgets($fp, 4096);
1639: fclose($fp);
1640:
1641: return substr($result, 0, 1) == '2';
1642: }
1643:
1644: function getSize()
1645: {
1646: return $this->_size;
1647: }
1648:
1649: 1650: 1651:
1652: function about()
1653: {
1654: return array(
1655: 'name' => Horde_Form_Translation::t("Email"),
1656: 'params' => array(
1657: 'allow_multi' => array(
1658: 'label' => Horde_Form_Translation::t("Allow multiple addresses?"),
1659: 'type' => 'boolean'),
1660: 'strip_domain' => array(
1661: 'label' => Horde_Form_Translation::t("Protect address from spammers?"),
1662: 'type' => 'boolean'),
1663: 'link_compose' => array(
1664: 'label' => Horde_Form_Translation::t("Link the email address to the compose page when displaying?"),
1665: 'type' => 'boolean'),
1666: 'link_name' => array(
1667: 'label' => Horde_Form_Translation::t("The name to use when linking to the compose page"),
1668: 'type' => 'text'),
1669: 'delimiters' => array(
1670: 'label' => Horde_Form_Translation::t("Character to split multiple addresses with"),
1671: 'type' => 'text'),
1672: 'size' => array(
1673: 'label' => Horde_Form_Translation::t("Size"),
1674: 'type' => 'int'),
1675: ),
1676: );
1677: }
1678:
1679: 1680: 1681: 1682: 1683: 1684: 1685: 1686: 1687:
1688: protected function _isRfc3696ValidEmailAddress($email)
1689: {
1690:
1691:
1692:
1693:
1694:
1695:
1696:
1697:
1698:
1699:
1700: $no_ws_ctl = "[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]";
1701: $alpha = "[\\x41-\\x5a\\x61-\\x7a]";
1702: $digit = "[\\x30-\\x39]";
1703: $cr = "\\x0d";
1704: $lf = "\\x0a";
1705: $crlf = "(?:$cr$lf)";
1706:
1707:
1708:
1709:
1710:
1711:
1712:
1713:
1714:
1715:
1716:
1717:
1718:
1719:
1720:
1721: $obs_char = "[\\x00-\\x09\\x0b\\x0c\\x0e-\\x7f]";
1722: $obs_text = "(?:$lf*$cr*(?:$obs_char$lf*$cr*)*)";
1723: $text = "(?:[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f]|$obs_text)";
1724:
1725:
1726:
1727:
1728:
1729:
1730:
1731:
1732: $text = "(?:$lf*$cr*$obs_char$lf*$cr*)";
1733: $obs_qp = "(?:\\x5c[\\x00-\\x7f])";
1734: $quoted_pair = "(?:\\x5c$text|$obs_qp)";
1735:
1736:
1737:
1738:
1739:
1740:
1741:
1742:
1743:
1744:
1745:
1746:
1747:
1748:
1749:
1750:
1751:
1752:
1753:
1754:
1755:
1756:
1757: $wsp = "[\\x20\\x09]";
1758: $obs_fws = "(?:$wsp+(?:$crlf$wsp+)*)";
1759: $fws = "(?:(?:(?:$wsp*$crlf)?$wsp+)|$obs_fws)";
1760: $ctext = "(?:$no_ws_ctl|[\\x21-\\x27\\x2A-\\x5b\\x5d-\\x7e])";
1761: $ccontent = "(?:$ctext|$quoted_pair)";
1762: $comment = "(?:\\x28(?:$fws?$ccontent)*$fws?\\x29)";
1763: $cfws = "(?:(?:$fws?$comment)*(?:$fws?$comment|$fws))";
1764:
1765:
1766:
1767:
1768:
1769:
1770:
1771:
1772: $outer_ccontent_dull = "(?:$fws?$ctext|$quoted_pair)";
1773: $outer_ccontent_nest = "(?:$fws?$comment)";
1774: $outer_comment = "(?:\\x28$outer_ccontent_dull*(?:$outer_ccontent_nest$outer_ccontent_dull*)+$fws?\\x29)";
1775:
1776:
1777:
1778:
1779:
1780:
1781:
1782:
1783:
1784:
1785:
1786:
1787:
1788:
1789:
1790:
1791:
1792: $atext = "(?:$alpha|$digit|[\\x21\\x23-\\x27\\x2a\\x2b\\x2d\\x2f\\x3d\\x3f\\x5e\\x5f\\x60\\x7b-\\x7e])";
1793: $atom = "(?:$cfws?(?:$atext)+$cfws?)";
1794:
1795:
1796:
1797:
1798:
1799:
1800:
1801:
1802:
1803:
1804:
1805:
1806:
1807:
1808: $qtext = "(?:$no_ws_ctl|[\\x21\\x23-\\x5b\\x5d-\\x7e])";
1809: $qcontent = "(?:$qtext|$quoted_pair)";
1810: $quoted_string = "(?:$cfws?\\x22(?:$fws?$qcontent)*$fws?\\x22$cfws?)";
1811:
1812:
1813:
1814:
1815:
1816: $quoted_string = "(?:$cfws?\\x22(?:$fws?$qcontent)+$fws?\\x22$cfws?)";
1817: $word = "(?:$atom|$quoted_string)";
1818:
1819:
1820:
1821:
1822:
1823:
1824:
1825: $obs_local_part = "(?:$word(?:\\x2e$word)*)";
1826: $obs_domain = "(?:$atom(?:\\x2e$atom)*)";
1827:
1828:
1829:
1830:
1831:
1832:
1833:
1834: $dot_atom_text = "(?:$atext+(?:\\x2e$atext+)*)";
1835: $dot_atom = "(?:$cfws?$dot_atom_text$cfws?)";
1836:
1837:
1838:
1839:
1840:
1841:
1842:
1843:
1844:
1845:
1846:
1847:
1848: $dtext = "(?:$no_ws_ctl|[\\x21-\\x5a\\x5e-\\x7e])";
1849: $dcontent = "(?:$dtext|$quoted_pair)";
1850: $domain_literal = "(?:$cfws?\\x5b(?:$fws?$dcontent)*$fws?\\x5d$cfws?)";
1851:
1852:
1853:
1854:
1855:
1856:
1857:
1858:
1859: $local_part = "(($dot_atom)|($quoted_string)|($obs_local_part))";
1860: $domain = "(($dot_atom)|($domain_literal)|($obs_domain))";
1861: $addr_spec = "$local_part\\x40$domain";
1862:
1863:
1864:
1865:
1866:
1867:
1868:
1869: if (strlen($email) > 256) return 0;
1870:
1871:
1872:
1873:
1874:
1875:
1876: $email = $this->_rfc3696StripComments($outer_comment, $email, "(x)");
1877:
1878:
1879:
1880:
1881:
1882:
1883: if (!preg_match("!^$addr_spec$!", $email, $m)){
1884:
1885: return 0;
1886: }
1887:
1888: $bits = array(
1889: 'local' => isset($m[1]) ? $m[1] : '',
1890: 'local-atom' => isset($m[2]) ? $m[2] : '',
1891: 'local-quoted' => isset($m[3]) ? $m[3] : '',
1892: 'local-obs' => isset($m[4]) ? $m[4] : '',
1893: 'domain' => isset($m[5]) ? $m[5] : '',
1894: 'domain-atom' => isset($m[6]) ? $m[6] : '',
1895: 'domain-literal' => isset($m[7]) ? $m[7] : '',
1896: 'domain-obs' => isset($m[8]) ? $m[8] : '',
1897: );
1898:
1899:
1900:
1901:
1902:
1903:
1904:
1905:
1906: $bits['local'] = $this->_rfc3696StripComments($comment, $bits['local']);
1907: $bits['domain'] = $this->_rfc3696StripComments($comment, $bits['domain']);
1908:
1909:
1910:
1911:
1912:
1913:
1914: if (strlen($bits['local']) > 64) return 0;
1915: if (strlen($bits['domain']) > 255) return 0;
1916:
1917:
1918:
1919:
1920:
1921:
1922: if (strlen($bits['domain-literal'])){
1923:
1924: $Snum = "(\d{1,3})";
1925: $IPv4_address_literal = "$Snum\.$Snum\.$Snum\.$Snum";
1926:
1927: $IPv6_hex = "(?:[0-9a-fA-F]{1,4})";
1928:
1929: $IPv6_full = "IPv6\:$IPv6_hex(:?\:$IPv6_hex){7}";
1930:
1931: $IPv6_comp_part = "(?:$IPv6_hex(?:\:$IPv6_hex){0,5})?";
1932: $IPv6_comp = "IPv6\:($IPv6_comp_part\:\:$IPv6_comp_part)";
1933:
1934: $IPv6v4_full = "IPv6\:$IPv6_hex(?:\:$IPv6_hex){5}\:$IPv4_address_literal";
1935:
1936: $IPv6v4_comp_part = "$IPv6_hex(?:\:$IPv6_hex){0,3}";
1937: $IPv6v4_comp = "IPv6\:((?:$IPv6v4_comp_part)?\:\:(?:$IPv6v4_comp_part\:)?)$IPv4_address_literal";
1938:
1939:
1940:
1941:
1942:
1943:
1944: if (preg_match("!^\[$IPv4_address_literal\]$!", $bits['domain'], $m)) {
1945: if (intval($m[1]) > 255) return 0;
1946: if (intval($m[2]) > 255) return 0;
1947: if (intval($m[3]) > 255) return 0;
1948: if (intval($m[4]) > 255) return 0;
1949: } else {
1950:
1951:
1952:
1953:
1954: while (1) {
1955:
1956: if (preg_match("!^\[$IPv6_full\]$!", $bits['domain'])){
1957: break;
1958: }
1959:
1960: if (preg_match("!^\[$IPv6_comp\]$!", $bits['domain'], $m)){
1961: list($a, $b) = explode('::', $m[1]);
1962: $folded = (strlen($a) && strlen($b)) ? "$a:$b" : "$a$b";
1963: $groups = explode(':', $folded);
1964: if (count($groups) > 6) return 0;
1965: break;
1966: }
1967:
1968: if (preg_match("!^\[$IPv6v4_full\]$!", $bits['domain'], $m)) {
1969: if (intval($m[1]) > 255) return 0;
1970: if (intval($m[2]) > 255) return 0;
1971: if (intval($m[3]) > 255) return 0;
1972: if (intval($m[4]) > 255) return 0;
1973: break;
1974: }
1975:
1976: if (preg_match("!^\[$IPv6v4_comp\]$!", $bits['domain'], $m)) {
1977: list($a, $b) = explode('::', $m[1]);
1978: $b = substr($b, 0, -1);
1979: $folded = (strlen($a) && strlen($b)) ? "$a:$b" : "$a$b";
1980: $groups = explode(':', $folded);
1981: if (count($groups) > 4) return 0;
1982: break;
1983: }
1984:
1985: return 0;
1986: }
1987: }
1988: } else {
1989:
1990:
1991:
1992:
1993:
1994: $labels = explode('.', $bits['domain']);
1995:
1996:
1997:
1998:
1999:
2000:
2001:
2002: if (count($labels) == 1) return 0;
2003:
2004:
2005:
2006:
2007:
2008:
2009: foreach ($labels as $label) {
2010: if (strlen($label) > 63) return 0;
2011: if (substr($label, 0, 1) == '-') return 0;
2012: if (substr($label, -1) == '-') return 0;
2013: }
2014:
2015:
2016:
2017:
2018:
2019:
2020: if (preg_match('!^[0-9]+$!', array_pop($labels))) return 0;
2021: }
2022:
2023: return 1;
2024: }
2025:
2026: 2027: 2028: 2029: 2030: 2031: 2032: 2033: 2034: 2035: 2036:
2037: protected function ($comment, $email, $replace = '')
2038: {
2039: while (1) {
2040: $new = preg_replace("!$comment!", $replace, $email);
2041: if (strlen($new) == strlen($email)) {
2042: return $email;
2043: }
2044: $email = $new;
2045: }
2046: }
2047: }
2048:
2049: class Horde_Form_Type_matrix extends Horde_Form_Type {
2050:
2051: var $_cols;
2052: var $_rows;
2053: var $_matrix;
2054: var $_new_input;
2055:
2056: 2057: 2058: 2059: 2060: 2061: 2062: 2063: 2064: 2065: 2066: 2067: 2068: 2069: 2070: 2071: 2072: 2073: 2074: 2075: 2076: 2077:
2078: function init($cols, $rows = array(), $matrix = array(), $new_input = false)
2079: {
2080: $this->_cols = $cols;
2081: $this->_rows = $rows;
2082: $this->_matrix = $matrix;
2083: $this->_new_input = $new_input;
2084: }
2085:
2086: function isValid(&$var, &$vars, $value, &$message)
2087: {
2088: return true;
2089: }
2090:
2091: function getCols() { return $this->_cols; }
2092: function getRows() { return $this->_rows; }
2093: function getMatrix() { return $this->_matrix; }
2094: function getNewInput() { return $this->_new_input; }
2095:
2096: function getInfo(&$vars, &$var, &$info)
2097: {
2098: $values = $vars->get($var->getVarName());
2099: if (!empty($values['n']['r']) && isset($values['n']['v'])) {
2100: $new_row = $values['n']['r'];
2101: $values['r'][$new_row] = $values['n']['v'];
2102: unset($values['n']);
2103: }
2104:
2105: $info = (isset($values['r']) ? $values['r'] : array());
2106: }
2107:
2108: function about()
2109: {
2110: return array(
2111: 'name' => Horde_Form_Translation::t("Field matrix"),
2112: 'params' => array(
2113: 'cols' => array('label' => Horde_Form_Translation::t("Column titles"),
2114: 'type' => 'stringarray')));
2115: }
2116:
2117: }
2118:
2119: class Horde_Form_Type_emailConfirm extends Horde_Form_Type {
2120:
2121: function isValid(&$var, &$vars, $value, &$message)
2122: {
2123: if ($var->isRequired() && empty($value['original'])) {
2124: $message = Horde_Form_Translation::t("This field is required.");
2125: return false;
2126: }
2127:
2128: if ($value['original'] != $value['confirm']) {
2129: $message = Horde_Form_Translation::t("Email addresses must match.");
2130: return false;
2131: } else {
2132: try {
2133: $parsed_email = Horde_Mime_Address::parseAddressList($value['original'], array('validate' => true));
2134: } catch (Horde_Mime_Exception $e) {
2135: $message = $e->getMessage();
2136: return false;
2137: }
2138: if (count($parsed_email) > 1) {
2139: $message = Horde_Form_Translation::t("Only one email address allowed.");
2140: return false;
2141: }
2142: if (empty($parsed_email[0]->mailbox)) {
2143: $message = Horde_Form_Translation::t("You did not enter a valid email address.");
2144: return false;
2145: }
2146: }
2147:
2148: return true;
2149: }
2150:
2151: 2152: 2153:
2154: function about()
2155: {
2156: return array('name' => Horde_Form_Translation::t("Email with confirmation"));
2157: }
2158:
2159: }
2160:
2161: class Horde_Form_Type_password extends Horde_Form_Type {
2162:
2163: function isValid(&$var, &$vars, $value, &$message)
2164: {
2165: $valid = true;
2166:
2167: if ($var->isRequired()) {
2168: $valid = strlen(trim($value)) > 0;
2169:
2170: if (!$valid) {
2171: $message = Horde_Form_Translation::t("This field is required.");
2172: }
2173: }
2174:
2175: return $valid;
2176: }
2177:
2178: 2179: 2180:
2181: function about()
2182: {
2183: return array('name' => Horde_Form_Translation::t("Password"));
2184: }
2185:
2186: }
2187:
2188: class Horde_Form_Type_passwordconfirm extends Horde_Form_Type {
2189:
2190: function isValid(&$var, &$vars, $value, &$message)
2191: {
2192: if ($var->isRequired() && empty($value['original'])) {
2193: $message = Horde_Form_Translation::t("This field is required.");
2194: return false;
2195: }
2196:
2197: if ($value['original'] != $value['confirm']) {
2198: $message = Horde_Form_Translation::t("Passwords must match.");
2199: return false;
2200: }
2201:
2202: return true;
2203: }
2204:
2205: function getInfo(&$vars, &$var, &$info)
2206: {
2207: $value = $vars->get($var->getVarName());
2208: $info = $value['original'];
2209: }
2210:
2211: 2212: 2213:
2214: function about()
2215: {
2216: return array('name' => Horde_Form_Translation::t("Password with confirmation"));
2217: }
2218:
2219: }
2220:
2221: class Horde_Form_Type_enum extends Horde_Form_Type {
2222:
2223: var $_values;
2224: var $_prompt;
2225:
2226: function init($values, $prompt = null)
2227: {
2228: $this->setValues($values);
2229:
2230: if ($prompt === true) {
2231: $this->_prompt = Horde_Form_Translation::t("-- select --");
2232: } else {
2233: $this->_prompt = $prompt;
2234: }
2235: }
2236:
2237: function isValid(&$var, &$vars, $value, &$message)
2238: {
2239: if ($var->isRequired() && $value == '' && !isset($this->_values[$value])) {
2240: $message = Horde_Form_Translation::t("This field is required.");
2241: return false;
2242: }
2243:
2244: if (count($this->_values) == 0 || isset($this->_values[$value]) ||
2245: ($this->_prompt && empty($value))) {
2246: return true;
2247: }
2248:
2249: $message = Horde_Form_Translation::t("Invalid data submitted.");
2250: return false;
2251: }
2252:
2253: function getValues()
2254: {
2255: return $this->_values;
2256: }
2257:
2258: function setValues($values)
2259: {
2260: $this->_values = $values;
2261: }
2262:
2263: function getPrompt()
2264: {
2265: return $this->_prompt;
2266: }
2267:
2268: 2269: 2270:
2271: function about()
2272: {
2273: return array(
2274: 'name' => Horde_Form_Translation::t("Drop down list"),
2275: 'params' => array(
2276: 'values' => array('label' => Horde_Form_Translation::t("Values to select from"),
2277: 'type' => 'stringarray'),
2278: 'prompt' => array('label' => Horde_Form_Translation::t("Prompt text"),
2279: 'type' => 'text')));
2280: }
2281:
2282: }
2283:
2284: class Horde_Form_Type_mlenum extends Horde_Form_Type {
2285:
2286: var $_values;
2287: var $_prompts;
2288:
2289: function init(&$values, $prompts = null)
2290: {
2291: $this->_values = &$values;
2292:
2293: if ($prompts === true) {
2294: $this->_prompts = array(Horde_Form_Translation::t("-- select --"), Horde_Form_Translation::t("-- select --"));
2295: } elseif (!is_array($prompts)) {
2296: $this->_prompts = array($prompts, $prompts);
2297: } else {
2298: $this->_prompts = $prompts;
2299: }
2300: }
2301:
2302: function onSubmit(&$var, &$vars)
2303: {
2304: $varname = $var->getVarName();
2305: $value = $vars->get($varname);
2306:
2307: if ($value['1'] != $value['old']) {
2308: $var->form->setSubmitted(false);
2309: }
2310: }
2311:
2312: function isValid(&$var, &$vars, $value, &$message)
2313: {
2314: if ($var->isRequired() && (empty($value['1']) || empty($value['2']))) {
2315: $message = Horde_Form_Translation::t("This field is required.");
2316: return false;
2317: }
2318:
2319: if (!count($this->_values) || isset($this->_values[$value['1']]) ||
2320: (!empty($this->_prompts) && empty($value['1']))) {
2321: return true;
2322: }
2323:
2324: $message = Horde_Form_Translation::t("Invalid data submitted.");
2325: return false;
2326: }
2327:
2328: function getValues()
2329: {
2330: return $this->_values;
2331: }
2332:
2333: function getPrompts()
2334: {
2335: return $this->_prompts;
2336: }
2337:
2338: function getInfo(&$vars, &$var, &$info)
2339: {
2340: $info = $vars->get($var->getVarName());
2341: return $info['2'];
2342: }
2343:
2344: 2345: 2346:
2347: function about()
2348: {
2349: return array(
2350: 'name' => Horde_Form_Translation::t("Multi-level drop down lists"),
2351: 'params' => array(
2352: 'values' => array('label' => Horde_Form_Translation::t("Values to select from"),
2353: 'type' => 'stringarray'),
2354: 'prompt' => array('label' => Horde_Form_Translation::t("Prompt text"),
2355: 'type' => 'text')));
2356: }
2357:
2358: }
2359:
2360: class Horde_Form_Type_multienum extends Horde_Form_Type_enum {
2361:
2362: var $size = 5;
2363:
2364: function init($values, $size = null)
2365: {
2366: if (!is_null($size)) {
2367: $this->size = (int)$size;
2368: }
2369:
2370: parent::init($values);
2371: }
2372:
2373: function isValid(&$var, &$vars, $value, &$message)
2374: {
2375: if (is_array($value)) {
2376: foreach ($value as $val) {
2377: if (!$this->isValid($var, $vars, $val, $message)) {
2378: return false;
2379: }
2380: }
2381: return true;
2382: }
2383:
2384: if (empty($value) && ((string)(int)$value !== $value)) {
2385: if ($var->isRequired()) {
2386: $message = Horde_Form_Translation::t("This field is required.");
2387: return false;
2388: } else {
2389: return true;
2390: }
2391: }
2392:
2393: if (count($this->_values) == 0 || isset($this->_values[$value])) {
2394: return true;
2395: }
2396:
2397: $message = Horde_Form_Translation::t("Invalid data submitted.");
2398: return false;
2399: }
2400:
2401: 2402: 2403:
2404: function about()
2405: {
2406: return array(
2407: 'name' => Horde_Form_Translation::t("Multiple selection"),
2408: 'params' => array(
2409: 'values' => array('label' => Horde_Form_Translation::t("Values"),
2410: 'type' => 'stringarray'),
2411: 'size' => array('label' => Horde_Form_Translation::t("Size"),
2412: 'type' => 'int'))
2413: );
2414: }
2415:
2416: }
2417:
2418: class Horde_Form_Type_keyval_multienum extends Horde_Form_Type_multienum {
2419:
2420: function getInfo(&$vars, &$var, &$info)
2421: {
2422: $value = $vars->get($var->getVarName());
2423: $info = array();
2424: foreach ($value as $key) {
2425: $info[$key] = $this->_values[$key];
2426: }
2427: }
2428:
2429: 2430: 2431:
2432: function about()
2433: {
2434: $about = parent::about();
2435: $about['name'] = Horde_Form_Translation::t("Multiple selection, preserving keys");
2436: }
2437:
2438: }
2439:
2440: class Horde_Form_Type_radio extends Horde_Form_Type_enum {
2441:
2442: 2443:
2444:
2445: 2446: 2447:
2448: function about()
2449: {
2450: return array(
2451: 'name' => Horde_Form_Translation::t("Radio selection"),
2452: 'params' => array(
2453: 'values' => array('label' => Horde_Form_Translation::t("Values"),
2454: 'type' => 'stringarray')));
2455: }
2456:
2457: }
2458:
2459: class Horde_Form_Type_set extends Horde_Form_Type {
2460:
2461: var $_values;
2462: var $_checkAll = false;
2463:
2464: function init($values, $checkAll = false)
2465: {
2466: $this->_values = $values;
2467: $this->_checkAll = $checkAll;
2468: }
2469:
2470: function isValid(&$var, &$vars, $value, &$message)
2471: {
2472: if (count($this->_values) == 0 || count($value) == 0) {
2473: return true;
2474: }
2475: foreach ($value as $item) {
2476: if (!isset($this->_values[$item])) {
2477: $error = true;
2478: break;
2479: }
2480: }
2481: if (!isset($error)) {
2482: return true;
2483: }
2484:
2485: $message = Horde_Form_Translation::t("Invalid data submitted.");
2486: return false;
2487: }
2488:
2489: function getValues()
2490: {
2491: return $this->_values;
2492: }
2493:
2494: 2495: 2496:
2497: function about()
2498: {
2499: return array(
2500: 'name' => Horde_Form_Translation::t("Set"),
2501: 'params' => array(
2502: 'values' => array('label' => Horde_Form_Translation::t("Values"),
2503: 'type' => 'stringarray')));
2504: }
2505:
2506: }
2507:
2508: class Horde_Form_Type_date extends Horde_Form_Type {
2509:
2510: var $_format;
2511:
2512: function init($format = '%a %d %B')
2513: {
2514: $this->_format = $format;
2515: }
2516:
2517: function isValid(&$var, &$vars, $value, &$message)
2518: {
2519: $valid = true;
2520:
2521: if ($var->isRequired()) {
2522: $valid = strlen(trim($value)) > 0;
2523:
2524: if (!$valid) {
2525: $message = sprintf(Horde_Form_Translation::t("%s is required"), $var->getHumanName());
2526: }
2527: }
2528:
2529: return $valid;
2530: }
2531:
2532: 2533: 2534: 2535: 2536: 2537: 2538: 2539: 2540:
2541: function getAgo($date)
2542: {
2543: if ($date === null) {
2544: return '';
2545: }
2546:
2547: try {
2548: $today = new Horde_Date(time());
2549: $date = new Horde_Date($date);
2550: $ago = $date->toDays() - $today->toDays();
2551: } catch (Horde_Date_Exception $e) {
2552: return '';
2553: }
2554:
2555: if ($ago < -1) {
2556: return sprintf(Horde_Form_Translation::t(" (%s days ago)"), abs($ago));
2557: } elseif ($ago == -1) {
2558: return Horde_Form_Translation::t(" (yesterday)");
2559: } elseif ($ago == 0) {
2560: return Horde_Form_Translation::t(" (today)");
2561: } elseif ($ago == 1) {
2562: return Horde_Form_Translation::t(" (tomorrow)");
2563: } else {
2564: return sprintf(Horde_Form_Translation::t(" (in %s days)"), $ago);
2565: }
2566: }
2567:
2568: function getFormattedTime($timestamp, $format = null, $showago = true)
2569: {
2570: if (empty($format)) {
2571: $format = $this->_format;
2572: }
2573: if (!empty($timestamp)) {
2574: return strftime($format, $timestamp) . ($showago ? Horde_Form_Type_date::getAgo($timestamp) : '');
2575: } else {
2576: return '';
2577: }
2578: }
2579:
2580: 2581: 2582:
2583: function about()
2584: {
2585: return array('name' => Horde_Form_Translation::t("Date"));
2586: }
2587:
2588: }
2589:
2590: class Horde_Form_Type_time extends Horde_Form_Type {
2591:
2592: function isValid(&$var, &$vars, $value, &$message)
2593: {
2594: if ($var->isRequired() && empty($value) && ((string)(double)$value !== $value)) {
2595: $message = Horde_Form_Translation::t("This field is required.");
2596: return false;
2597: }
2598:
2599: if (empty($value) || preg_match('/^[0-2]?[0-9]:[0-5][0-9]$/', $value)) {
2600: return true;
2601: }
2602:
2603: $message = Horde_Form_Translation::t("This field may only contain numbers and the colon.");
2604: return false;
2605: }
2606:
2607: 2608: 2609:
2610: function about()
2611: {
2612: return array('name' => Horde_Form_Translation::t("Time"));
2613: }
2614:
2615: }
2616:
2617: class Horde_Form_Type_hourminutesecond extends Horde_Form_Type {
2618:
2619: var $_show_seconds;
2620:
2621: function init($show_seconds = false)
2622: {
2623: $this->_show_seconds = $show_seconds;
2624: }
2625:
2626: function isValid(&$var, &$vars, $value, &$message)
2627: {
2628: $time = $vars->get($var->getVarName());
2629: if (!$this->_show_seconds && count($time) && !isset($time['second'])) {
2630: $time['second'] = 0;
2631: }
2632:
2633: if (!$this->emptyTimeArray($time) && !$this->checktime($time['hour'], $time['minute'], $time['second'])) {
2634: $message = Horde_Form_Translation::t("Please enter a valid time.");
2635: return false;
2636: } elseif ($this->emptyTimeArray($time) && $var->isRequired()) {
2637: $message = Horde_Form_Translation::t("This field is required.");
2638: return false;
2639: }
2640:
2641: return true;
2642: }
2643:
2644: function checktime($hour, $minute, $second)
2645: {
2646: if (!isset($hour) || $hour == '' || ($hour < 0 || $hour > 23)) {
2647: return false;
2648: }
2649: if (!isset($minute) || $minute == '' || ($minute < 0 || $minute > 60)) {
2650: return false;
2651: }
2652: if (!isset($second) || $second === '' || ($second < 0 || $second > 60)) {
2653: return false;
2654: }
2655:
2656: return true;
2657: }
2658:
2659: 2660: 2661: 2662: 2663: 2664: 2665: 2666: 2667: 2668:
2669: function getTimeOb($time_in)
2670: {
2671: if (is_array($time_in)) {
2672: if (!$this->emptyTimeArray($time_in)) {
2673: $time_in = sprintf('1970-01-01 %02d:%02d:%02d', $time_in['hour'], $time_in['minute'], $this->_show_seconds ? $time_in['second'] : 0);
2674: }
2675: }
2676:
2677: return new Horde_Date($time_in);
2678: }
2679:
2680: 2681: 2682: 2683: 2684: 2685: 2686: 2687: 2688: 2689:
2690: function getTimeParts($time_in)
2691: {
2692: if (is_array($time_in)) {
2693: 2694:
2695: return $time_in;
2696: } elseif (empty($time_in)) {
2697:
2698: return array('hour' => '', 'minute' => '', 'second' => '');
2699: }
2700: $time = $this->getTimeOb($time_in);
2701: return array('hour' => $time->hour,
2702: 'minute' => $time->min,
2703: 'second' => $time->sec);
2704: }
2705:
2706: function emptyTimeArray($time)
2707: {
2708: return (is_array($time)
2709: && (!isset($time['hour']) || !strlen($time['hour']))
2710: && (!isset($time['minute']) || !strlen($time['minute']))
2711: && (!$this->_show_seconds || !strlen($time['second'])));
2712: }
2713:
2714: 2715: 2716:
2717: function about()
2718: {
2719: return array(
2720: 'name' => Horde_Form_Translation::t("Time selection"),
2721: 'params' => array(
2722: 'seconds' => array('label' => Horde_Form_Translation::t("Show seconds?"),
2723: 'type' => 'boolean')));
2724: }
2725:
2726: }
2727:
2728: class Horde_Form_Type_monthyear extends Horde_Form_Type {
2729:
2730: var $_start_year;
2731: var $_end_year;
2732:
2733: function init($start_year = null, $end_year = null)
2734: {
2735: if (empty($start_year)) {
2736: $start_year = 1920;
2737: }
2738: if (empty($end_year)) {
2739: $end_year = date('Y');
2740: }
2741:
2742: $this->_start_year = $start_year;
2743: $this->_end_year = $end_year;
2744: }
2745:
2746: function isValid(&$var, &$vars, $value, &$message)
2747: {
2748: if (!$var->isRequired()) {
2749: return true;
2750: }
2751:
2752: if (!$vars->get($this->getMonthVar($var)) ||
2753: !$vars->get($this->getYearVar($var))) {
2754: $message = Horde_Form_Translation::t("Please enter a month and a year.");
2755: return false;
2756: }
2757:
2758: return true;
2759: }
2760:
2761: function getMonthVar($var)
2762: {
2763: return $var->getVarName() . '[month]';
2764: }
2765:
2766: function getYearVar($var)
2767: {
2768: return $var->getVarName() . '[year]';
2769: }
2770:
2771: 2772: 2773:
2774: function about()
2775: {
2776: return array('name' => Horde_Form_Translation::t("Month and year"),
2777: 'params' => array(
2778: 'start_year' => array('label' => Horde_Form_Translation::t("Start year"),
2779: 'type' => 'int'),
2780: 'end_year' => array('label' => Horde_Form_Translation::t("End year"),
2781: 'type' => 'int')));
2782: }
2783:
2784: }
2785:
2786: class Horde_Form_Type_monthdayyear extends Horde_Form_Type {
2787:
2788: var $_start_year;
2789: var $_end_year;
2790: var $_picker;
2791: var $_format_in = null;
2792: var $_format_out = '%x';
2793:
2794: 2795: 2796: 2797: 2798: 2799: 2800: 2801: 2802: 2803: 2804: 2805:
2806: function init($start_year = '', $end_year = '', $picker = true,
2807: $format_in = null, $format_out = '%x')
2808: {
2809: if (empty($start_year)) {
2810: $start_year = date('Y');
2811: }
2812: if (empty($end_year)) {
2813: $end_year = date('Y') + 10;
2814: }
2815:
2816: $this->_start_year = $start_year;
2817: $this->_end_year = $end_year;
2818: $this->_picker = $picker;
2819: $this->_format_in = $format_in;
2820: $this->_format_out = $format_out;
2821: }
2822:
2823: function isValid(&$var, &$vars, $value, &$message)
2824: {
2825: $date = $vars->get($var->getVarName());
2826: $empty = $this->emptyDateArray($date);
2827:
2828: if ($empty == 1 && $var->isRequired()) {
2829: $message = Horde_Form_Translation::t("This field is required.");
2830: return false;
2831: } elseif ($empty == 0 && !checkdate($date['month'],
2832: $date['day'],
2833: $date['year'])) {
2834: $message = Horde_Form_Translation::t("Please enter a valid date, check the number of days in the month.");
2835: return false;
2836: } elseif ($empty == -1) {
2837: $message = Horde_Form_Translation::t("Select all date components.");
2838: return false;
2839: }
2840:
2841: return true;
2842: }
2843:
2844: 2845: 2846: 2847: 2848: 2849: 2850: 2851: 2852:
2853: function emptyDateArray($date)
2854: {
2855: if (!is_array($date)) {
2856: return (int)empty($date);
2857: }
2858: $empty = 0;
2859:
2860: foreach (array('day', 'month', 'year') as $key) {
2861: if (empty($date[$key])) {
2862: $empty++;
2863: }
2864: }
2865:
2866:
2867: if ($empty == 0) {
2868:
2869: return 0;
2870: } elseif ($empty == 3) {
2871:
2872: return 1;
2873: } else {
2874:
2875: return -1;
2876: }
2877: }
2878:
2879: 2880: 2881: 2882: 2883: 2884: 2885: 2886: 2887: 2888:
2889: function getDateParts($date_in)
2890: {
2891: if (is_array($date_in)) {
2892: 2893:
2894: return $date_in;
2895: } elseif (empty($date_in)) {
2896:
2897: return array('year' => '', 'month' => '', 'day' => '');
2898: }
2899:
2900: $date = $this->getDateOb($date_in);
2901: return array('year' => $date->year,
2902: 'month' => $date->month,
2903: 'day' => $date->mday);
2904: }
2905:
2906: 2907: 2908: 2909: 2910: 2911: 2912: 2913: 2914: 2915:
2916: function getDateOb($date_in)
2917: {
2918: if (is_array($date_in)) {
2919:
2920: if ($this->emptyDateArray($date_in) == 0) {
2921: $date_in = sprintf('%04d-%02d-%02d 00:00:00',
2922: $date_in['year'],
2923: $date_in['month'],
2924: $date_in['day']);
2925: }
2926: } elseif (preg_match('/^\d{4}-?\d{2}-?\d{2}$/', $date_in)) {
2927:
2928: $date_in = $date_in . ' 00:00:00';
2929: }
2930:
2931: return new Horde_Date($date_in);
2932: }
2933:
2934: 2935: 2936: 2937: 2938: 2939: 2940: 2941: 2942: 2943: 2944: 2945:
2946: function formatDate($date)
2947: {
2948: if (!($date instanceof Horde_Date)) {
2949: $date = $this->getDateOb($date);
2950: }
2951:
2952: return $date->strftime($this->_format_out);
2953: }
2954:
2955: 2956: 2957: 2958: 2959:
2960: function getInfo(&$vars, &$var, &$info)
2961: {
2962: $info = $this->_validateAndFormat($var->getValue($vars), $var);
2963: }
2964:
2965: 2966: 2967:
2968: function _validateAndFormat($value, &$var)
2969: {
2970: 2971:
2972: if ($this->emptyDateArray($value) == 1) {
2973: return $var->getDefault();
2974: } else {
2975: $date = $this->getDateOb($value);
2976: if ($this->_format_in === null) {
2977: return $date->timestamp();
2978: } else {
2979: return $date->strftime($this->_format_in);
2980: }
2981: }
2982: }
2983:
2984: 2985: 2986:
2987: function about()
2988: {
2989: return array(
2990: 'name' => Horde_Form_Translation::t("Date selection"),
2991: 'params' => array(
2992: 'start_year' => array('label' => Horde_Form_Translation::t("Start year"),
2993: 'type' => 'int'),
2994: 'end_year' => array('label' => Horde_Form_Translation::t("End year"),
2995: 'type' => 'int'),
2996: 'picker' => array('label' => Horde_Form_Translation::t("Show picker?"),
2997: 'type' => 'boolean'),
2998: 'format_in' => array('label' => Horde_Form_Translation::t("Storage format"),
2999: 'type' => 'text'),
3000: 'format_out' => array('label' => Horde_Form_Translation::t("Display format"),
3001: 'type' => 'text')));
3002: }
3003:
3004: }
3005:
3006: class Horde_Form_Type_datetime extends Horde_Form_Type {
3007:
3008: var $_mdy;
3009: var $_hms;
3010: var $_show_seconds;
3011:
3012: 3013: 3014: 3015: 3016: 3017: 3018: 3019: 3020: 3021: 3022: 3023: 3024:
3025: function init($start_year = '', $end_year = '', $picker = true,
3026: $format_in = null, $format_out = '%x', $show_seconds = false)
3027: {
3028: $this->_mdy = new Horde_Form_Type_monthdayyear();
3029: $this->_mdy->init($start_year, $end_year, $picker, $format_in, $format_out);
3030:
3031: $this->_hms = new Horde_Form_Type_hourminutesecond();
3032: $this->_hms->init($show_seconds);
3033: $this->_show_seconds = $show_seconds;
3034: }
3035:
3036: function isValid(&$var, &$vars, $value, &$message)
3037: {
3038: $date = $vars->get($var->getVarName());
3039: if (!$this->_show_seconds && !isset($date['second'])) {
3040: $date['second'] = '';
3041: }
3042: $mdy_empty = $this->emptyDateArray($date);
3043: $hms_empty = $this->emptyTimeArray($date);
3044:
3045: $valid = true;
3046:
3047:
3048: if ($var->isRequired() || $mdy_empty != 1 || !$hms_empty) {
3049: $old_required = $var->required;
3050: $var->required = true;
3051:
3052: $mdy_valid = $this->_mdy->isValid($var, $vars, $value, $message);
3053: $hms_valid = $this->_hms->isValid($var, $vars, $value, $message);
3054: $var->required = $old_required;
3055:
3056: $valid = $mdy_valid && $hms_valid;
3057: if ($mdy_valid && !$hms_valid) {
3058: $message = Horde_Form_Translation::t("You must choose a time.");
3059: } elseif ($hms_valid && !$mdy_valid) {
3060: $message = Horde_Form_Translation::t("You must choose a date.");
3061: }
3062: }
3063:
3064: return $valid;
3065: }
3066:
3067: function getInfo(&$vars, &$var, &$info)
3068: {
3069: 3070:
3071: $value = $var->getValue($vars);
3072: if ($this->emptyDateArray($value) == 1 || $this->emptyTimeArray($value)) {
3073: $info = $var->getDefault();
3074: return;
3075: }
3076:
3077: $date = $this->getDateOb($value);
3078: $time = $this->getTimeOb($value);
3079: $date->hour = $time->hour;
3080: $date->min = $time->min;
3081: $date->sec = $time->sec;
3082: if ($this->getProperty('format_in') === null) {
3083: $info = $date->timestamp();
3084: } else {
3085: $info = $date->strftime($this->getProperty('format_in'));
3086: }
3087: }
3088:
3089: function getProperty($property)
3090: {
3091: if ($property == 'show_seconds') {
3092: return $this->_hms->getProperty($property);
3093: } else {
3094: return $this->_mdy->getProperty($property);
3095: }
3096: }
3097:
3098: function setProperty($property, $value)
3099: {
3100: if ($property == 'show_seconds') {
3101: $this->_hms->setProperty($property, $value);
3102: } else {
3103: $this->_mdy->setProperty($property, $value);
3104: }
3105: }
3106:
3107: function checktime($hour, $minute, $second)
3108: {
3109: return $this->_hms->checktime($hour, $minute, $second);
3110: }
3111:
3112: function getTimeOb($time_in)
3113: {
3114: return $this->_hms->getTimeOb($time_in);
3115: }
3116:
3117: function getTimeParts($time_in)
3118: {
3119: return $this->_hms->getTimeParts($time_in);
3120: }
3121:
3122: function emptyTimeArray($time)
3123: {
3124: return $this->_hms->emptyTimeArray($time);
3125: }
3126:
3127: function emptyDateArray($date)
3128: {
3129: return $this->_mdy->emptyDateArray($date);
3130: }
3131:
3132: function getDateParts($date_in)
3133: {
3134: return $this->_mdy->getDateParts($date_in);
3135: }
3136:
3137: function getDateOb($date_in)
3138: {
3139: return $this->_mdy->getDateOb($date_in);
3140: }
3141:
3142: function formatDate($date)
3143: {
3144: if ($this->_mdy->emptyDateArray($date)) {
3145: return '';
3146: }
3147: return $this->_mdy->formatDate($date);
3148: }
3149:
3150: function about()
3151: {
3152: return array(
3153: 'name' => Horde_Form_Translation::t("Date and time selection"),
3154: 'params' => array(
3155: 'start_year' => array('label' => Horde_Form_Translation::t("Start year"),
3156: 'type' => 'int'),
3157: 'end_year' => array('label' => Horde_Form_Translation::t("End year"),
3158: 'type' => 'int'),
3159: 'picker' => array('label' => Horde_Form_Translation::t("Show picker?"),
3160: 'type' => 'boolean'),
3161: 'format_in' => array('label' => Horde_Form_Translation::t("Storage format"),
3162: 'type' => 'text'),
3163: 'format_out' => array('label' => Horde_Form_Translation::t("Display format"),
3164: 'type' => 'text'),
3165: 'seconds' => array('label' => Horde_Form_Translation::t("Show seconds?"),
3166: 'type' => 'boolean')));
3167: }
3168:
3169: }
3170:
3171: class Horde_Form_Type_colorpicker extends Horde_Form_Type {
3172:
3173: function isValid(&$var, &$vars, $value, &$message)
3174: {
3175: if ($var->isRequired() && empty($value)) {
3176: $message = Horde_Form_Translation::t("This field is required.");
3177: return false;
3178: }
3179:
3180: if (empty($value) || preg_match('/^#([0-9a-z]){6}$/i', $value)) {
3181: return true;
3182: }
3183:
3184: $message = Horde_Form_Translation::t("This field must contain a color code in the RGB Hex format, for example '#1234af'.");
3185: return false;
3186: }
3187:
3188: 3189: 3190:
3191: function about()
3192: {
3193: return array('name' => Horde_Form_Translation::t("Colour selection"));
3194: }
3195:
3196: }
3197:
3198: class Horde_Form_Type_sound extends Horde_Form_Type {
3199:
3200: var $_sounds = array();
3201:
3202: function init()
3203: {
3204: $this->_sounds = array_keys(Horde_Themes::soundList());
3205: }
3206:
3207: function getSounds()
3208: {
3209: return $this->_sounds;
3210: }
3211:
3212: function isValid(&$var, &$vars, $value, &$message)
3213: {
3214: if ($var->isRequired() && empty($value)) {
3215: $message = Horde_Form_Translation::t("This field is required.");
3216: return false;
3217: }
3218:
3219: if (empty($value) || in_array($value, $this->_sounds)) {
3220: return true;
3221: }
3222:
3223: $message = Horde_Form_Translation::t("Please choose a sound.");
3224: return false;
3225: }
3226:
3227: 3228: 3229:
3230: function about()
3231: {
3232: return array('name' => Horde_Form_Translation::t("Sound selection"));
3233: }
3234:
3235: }
3236:
3237: class Horde_Form_Type_sorter extends Horde_Form_Type {
3238:
3239: var $_instance;
3240: var $_values;
3241: var $_size;
3242: var ;
3243:
3244: function init($values, $size = 8, $header = '')
3245: {
3246: static $horde_sorter_instance = 0;
3247:
3248: 3249:
3250: $horde_sorter_instance++;
3251: $this->_instance = 'horde_sorter_' . $horde_sorter_instance;
3252: $this->_values = $values;
3253: $this->_size = $size;
3254: $this->_header = $header;
3255: }
3256:
3257: function isValid(&$var, &$vars, $value, &$message)
3258: {
3259: return true;
3260: }
3261:
3262: function getValues()
3263: {
3264: return $this->_values;
3265: }
3266:
3267: function getSize()
3268: {
3269: return $this->_size;
3270: }
3271:
3272: function ()
3273: {
3274: if (!empty($this->_header)) {
3275: return $this->_header;
3276: }
3277: return '';
3278: }
3279:
3280: function getOptions($keys = null)
3281: {
3282: $html = '';
3283: if ($this->_header) {
3284: $html .= '<option value="">' . htmlspecialchars($this->_header) . '</option>';
3285: }
3286:
3287: if (empty($keys)) {
3288: $keys = array_keys($this->_values);
3289: } else {
3290: $keys = explode("\t", $keys['array']);
3291: }
3292: foreach ($keys as $sl_key) {
3293: $html .= '<option value="' . $sl_key . '">' . htmlspecialchars($this->_values[$sl_key]) . '</option>';
3294: }
3295:
3296: return $html;
3297: }
3298:
3299: function getInfo(&$vars, &$var, &$info)
3300: {
3301: $value = $vars->get($var->getVarName());
3302: $info = explode("\t", $value['array']);
3303: }
3304:
3305: 3306: 3307:
3308: function about()
3309: {
3310: return array(
3311: 'name' => Horde_Form_Translation::t("Sort order selection"),
3312: 'params' => array(
3313: 'values' => array('label' => Horde_Form_Translation::t("Values"),
3314: 'type' => 'stringarray'),
3315: 'size' => array('label' => Horde_Form_Translation::t("Size"),
3316: 'type' => 'int'),
3317: 'header' => array('label' => Horde_Form_Translation::t("Header"),
3318: 'type' => 'text')));
3319: }
3320:
3321: }
3322:
3323: class Horde_Form_Type_selectfiles extends Horde_Form_Type {
3324:
3325: 3326: 3327: 3328: 3329:
3330: var $_link_text;
3331:
3332: 3333: 3334: 3335: 3336:
3337: var $_link_style;
3338:
3339: 3340: 3341: 3342: 3343:
3344: var $_icon;
3345:
3346: 3347: 3348: 3349: 3350:
3351: var $_selectid;
3352:
3353: function init($selectid, $link_text = null, $link_style = '',
3354: $icon = false)
3355: {
3356: $this->_selectid = $selectid;
3357: if (is_null($link_text)) {
3358: $link_text = Horde_Form_Translation::t("Select Files");
3359: }
3360: $this->_link_text = $link_text;
3361: $this->_link_style = $link_style;
3362: $this->_icon = $icon;
3363: }
3364:
3365: function isValid(&$var, &$vars, $value, &$message)
3366: {
3367: return true;
3368: }
3369:
3370: function getInfo(&$var, &$vars, &$info)
3371: {
3372: $value = $vars->getValue($var);
3373: $info = $GLOBALS['registry']->call('files/selectlistResults', array($value));
3374: }
3375:
3376: function about()
3377: {
3378: return array(
3379: 'name' => Horde_Form_Translation::t("File selection"),
3380: 'params' => array(
3381: 'selectid' => array('label' => Horde_Form_Translation::t("Id"),
3382: 'type' => 'text'),
3383: 'link_text' => array('label' => Horde_Form_Translation::t("Link text"),
3384: 'type' => 'text'),
3385: 'link_style' => array('label' => Horde_Form_Translation::t("Link style"),
3386: 'type' => 'text'),
3387: 'icon' => array('label' => Horde_Form_Translation::t("Show icon?"),
3388: 'type' => 'boolean')));
3389: }
3390:
3391: }
3392:
3393: class Horde_Form_Type_assign extends Horde_Form_Type {
3394:
3395: var $_leftValues;
3396: var $_rightValues;
3397: var ;
3398: var ;
3399: var $_size;
3400: var $_width;
3401:
3402: function init($leftValues, $rightValues, $leftHeader = '',
3403: $rightHeader = '', $size = 8, $width = '200px')
3404: {
3405: $this->_leftValues = $leftValues;
3406: $this->_rightValues = $rightValues;
3407: $this->_leftHeader = $leftHeader;
3408: $this->_rightHeader = $rightHeader;
3409: $this->_size = $size;
3410: $this->_width = $width;
3411: }
3412:
3413: function isValid(&$var, &$vars, $value, &$message)
3414: {
3415: return true;
3416: }
3417:
3418: function getValues($side)
3419: {
3420: return $side ? $this->_rightValues : $this->_leftValues;
3421: }
3422:
3423: function setValues($side, $values)
3424: {
3425: if ($side) {
3426: $this->_rightValues = $values;
3427: } else {
3428: $this->_leftValues = $values;
3429: }
3430: }
3431:
3432: function ($side)
3433: {
3434: return $side ? $this->_rightHeader : $this->_leftHeader;
3435: }
3436:
3437: function getSize()
3438: {
3439: return $this->_size;
3440: }
3441:
3442: function getWidth()
3443: {
3444: return $this->_width;
3445: }
3446:
3447: function getOptions($side, $formname, $varname)
3448: {
3449: $html = '';
3450: $headers = false;
3451: if ($side) {
3452: $values = $this->_rightValues;
3453: if (!empty($this->_rightHeader)) {
3454: $values = array('' => $this->_rightHeader) + $values;
3455: $headers = true;
3456: }
3457: } else {
3458: $values = $this->_leftValues;
3459: if (!empty($this->_leftHeader)) {
3460: $values = array('' => $this->_leftHeader) + $values;
3461: $headers = true;
3462: }
3463: }
3464:
3465: foreach ($values as $key => $val) {
3466: $html .= '<option value="' . htmlspecialchars($key) . '"';
3467: if ($headers) {
3468: $headers = false;
3469: } else {
3470: $html .= ' ondblclick="Horde_Form_Assign.move(\'' . $formname . '\', \'' . $varname . '\', ' . (int)$side . ');"';
3471: }
3472: $html .= '>' . htmlspecialchars($val) . '</option>';
3473: }
3474:
3475: return $html;
3476: }
3477:
3478: function getInfo(&$vars, &$var, &$info)
3479: {
3480: $value = $vars->get($var->getVarName() . '__values');
3481: if (strpos($value, "\t\t") === false) {
3482: $left = $value;
3483: $right = '';
3484: } else {
3485: list($left, $right) = explode("\t\t", $value);
3486: }
3487: if (empty($left)) {
3488: $info['left'] = array();
3489: } else {
3490: $info['left'] = explode("\t", $left);
3491: }
3492: if (empty($right)) {
3493: $info['right'] = array();
3494: } else {
3495: $info['right'] = explode("\t", $right);
3496: }
3497: }
3498:
3499: 3500: 3501:
3502: function about()
3503: {
3504: return array(
3505: 'name' => Horde_Form_Translation::t("Assignment columns"),
3506: 'params' => array(
3507: 'leftValues' => array('label' => Horde_Form_Translation::t("Left values"),
3508: 'type' => 'stringarray'),
3509: 'rightValues' => array('label' => Horde_Form_Translation::t("Right values"),
3510: 'type' => 'stringarray'),
3511: 'leftHeader' => array('label' => Horde_Form_Translation::t("Left header"),
3512: 'type' => 'text'),
3513: 'rightHeader' => array('label' => Horde_Form_Translation::t("Right header"),
3514: 'type' => 'text'),
3515: 'size' => array('label' => Horde_Form_Translation::t("Size"),
3516: 'type' => 'int'),
3517: 'width' => array('label' => Horde_Form_Translation::t("Width in CSS units"),
3518: 'type' => 'text')));
3519: }
3520:
3521: }
3522:
3523: class Horde_Form_Type_creditcard extends Horde_Form_Type {
3524:
3525: function isValid(&$var, &$vars, $value, &$message)
3526: {
3527: if (empty($value) && $var->isRequired()) {
3528: $message = Horde_Form_Translation::t("This field is required.");
3529: return false;
3530: }
3531:
3532: if (!empty($value)) {
3533:
3534: $type = $this->getCardType($value);
3535: if ($type === false || $type == 'unknown') {
3536: $message = Horde_Form_Translation::t("This does not seem to be a valid card number.");
3537: return false;
3538: }
3539: }
3540:
3541: return true;
3542: }
3543:
3544: function getChecksum($ccnum)
3545: {
3546: $len = strlen($ccnum);
3547: if (!is_long($len / 2)) {
3548: $weight = 2;
3549: $digit = $ccnum[0];
3550: } elseif (is_long($len / 2)) {
3551: $weight = 1;
3552: $digit = $ccnum[0] * 2;
3553: }
3554: if ($digit > 9) {
3555: $digit = $digit - 9;
3556: }
3557: $i = 1;
3558: $checksum = $digit;
3559: while ($i < $len) {
3560: if ($ccnum[$i] != ' ') {
3561: $digit = $ccnum[$i] * $weight;
3562: $weight = ($weight == 1) ? 2 : 1;
3563: if ($digit > 9) {
3564: $digit = $digit - 9;
3565: }
3566: $checksum += $digit;
3567: }
3568: $i++;
3569: }
3570:
3571: return $checksum;
3572: }
3573:
3574: function getCardType($ccnum)
3575: {
3576: $sum = $this->getChecksum($ccnum);
3577: $l = strlen($ccnum);
3578:
3579:
3580: if (($sum % 10) != 0) {
3581: return false;
3582: }
3583:
3584:
3585: if ((($l == 16) || ($l == 13)) &&
3586: ($ccnum[0] == 4)) {
3587: return 'visa';
3588: }
3589:
3590:
3591: if (($l == 16) &&
3592: ($ccnum[0] == 5) &&
3593: ($ccnum[1] >= 1) &&
3594: ($ccnum[1] <= 5)) {
3595: return 'mastercard';
3596: }
3597:
3598:
3599: if (($l == 15) &&
3600: ($ccnum[0] == 3) &&
3601: (($ccnum[1] == 4) || ($ccnum[1] == 7))) {
3602: return 'amex';
3603: }
3604:
3605:
3606: if (strlen($ccnum) == 16 &&
3607: substr($ccnum, 0, 4) == '6011') {
3608: return 'discover';
3609: }
3610:
3611:
3612: return 'unknown';
3613: }
3614:
3615: 3616: 3617:
3618: function about()
3619: {
3620: return array('name' => Horde_Form_Translation::t("Credit card number"));
3621: }
3622:
3623: }
3624:
3625: class Horde_Form_Type_obrowser extends Horde_Form_Type {
3626:
3627: function isValid(&$var, &$vars, $value, &$message)
3628: {
3629: return true;
3630: }
3631:
3632: 3633: 3634:
3635: function about()
3636: {
3637: return array('name' => Horde_Form_Translation::t("Relationship browser"));
3638: }
3639:
3640: }
3641:
3642: class Horde_Form_Type_dblookup extends Horde_Form_Type_enum {
3643:
3644: function init($db, $sql, $prompt = null)
3645: {
3646: $values = array();
3647: try {
3648: $col = $db->selectValues($sql);
3649: $values = array_combine($col, $col);
3650: } catch (Horde_Db_Exception $e) {
3651: }
3652: parent::init($values, $prompt);
3653: }
3654:
3655: 3656: 3657:
3658: function about()
3659: {
3660: return array(
3661: 'name' => Horde_Form_Translation::t("Database lookup"),
3662: 'params' => array(
3663: 'dsn' => array('label' => Horde_Form_Translation::t("DSN (see http://pear.php.net/manual/en/package.database.db.intro-dsn.php)"),
3664: 'type' => 'text'),
3665: 'sql' => array('label' => Horde_Form_Translation::t("SQL statement for value lookups"),
3666: 'type' => 'text'),
3667: 'prompt' => array('label' => Horde_Form_Translation::t("Prompt text"),
3668: 'type' => 'text'))
3669: );
3670: }
3671:
3672: }
3673:
3674: class Horde_Form_Type_figlet extends Horde_Form_Type {
3675:
3676: var $_text;
3677: var $_font;
3678:
3679: function init($text, $font)
3680: {
3681: $this->_text = $text;
3682: $this->_font = $font;
3683: }
3684:
3685: function isValid(&$var, &$vars, $value, &$message)
3686: {
3687: if (empty($value) && $var->isRequired()) {
3688: $message = Horde_Form_Translation::t("This field is required.");
3689: return false;
3690: }
3691:
3692: if (Horde_String::lower($value) != Horde_String::lower($this->_text)) {
3693: $message = Horde_Form_Translation::t("The text you entered did not match the text on the screen.");
3694: return false;
3695: }
3696:
3697: return true;
3698: }
3699:
3700: function getFont()
3701: {
3702: return $this->_font;
3703: }
3704:
3705: function getText()
3706: {
3707: return $this->_text;
3708: }
3709:
3710: 3711: 3712:
3713: function about()
3714: {
3715: return array(
3716: 'name' => Horde_Form_Translation::t("Figlet CAPTCHA"),
3717: 'params' => array(
3718: 'text' => array('label' => Horde_Form_Translation::t("Text"),
3719: 'type' => 'text'),
3720: 'font' => array('label' => Horde_Form_Translation::t("Figlet font"),
3721: 'type' => 'text'))
3722: );
3723: }
3724:
3725: }
3726:
3727: class Horde_Form_Type_captcha extends Horde_Form_Type_figlet {
3728:
3729: 3730: 3731:
3732: function about()
3733: {
3734: return array(
3735: 'name' => Horde_Form_Translation::t("Image CAPTCHA"),
3736: 'params' => array(
3737: 'text' => array('label' => Horde_Form_Translation::t("Text"),
3738: 'type' => 'text'),
3739: 'font' => array('label' => Horde_Form_Translation::t("Font"),
3740: 'type' => 'text'))
3741: );
3742: }
3743:
3744: }
3745:
3746: class Horde_Form_Type_category extends Horde_Form_Type {
3747:
3748: function getInfo(&$vars, &$var, &$info)
3749: {
3750: $info = $var->getValue($vars);
3751: if ($info == '*new*') {
3752: $info = array('new' => true,
3753: 'value' => $vars->get('new_category'));
3754: } else {
3755: $info = array('new' => false,
3756: 'value' => $info);
3757: }
3758: }
3759:
3760: 3761: 3762:
3763: function about()
3764: {
3765: return array('name' => Horde_Form_Translation::t("Category"));
3766: }
3767:
3768: function isValid(&$var, &$vars, $value, &$message)
3769: {
3770: if (empty($value) && $var->isRequired()) {
3771: $message = Horde_Form_Translation::t("This field is required.");
3772: return false;
3773: }
3774:
3775: return true;
3776: }
3777:
3778: }
3779:
3780: class Horde_Form_Type_invalid extends Horde_Form_Type {
3781:
3782: var $message;
3783:
3784: function init($message)
3785: {
3786: $this->message = $message;
3787: }
3788:
3789: function isValid(&$var, &$vars, $value, &$message)
3790: {
3791: return false;
3792: }
3793:
3794: }
3795: