PageRenderTime 31ms CodeModel.GetById 31ms RepoModel.GetById 1ms app.codeStats 0ms

/lib/FormHandler.php

https://github.com/reshadf/Library
PHP | 4009 lines | 2382 code | 345 blank | 1282 comment | 334 complexity | 56e41ea1486b68b7f725b436fffcdfe3 MD5 | raw file
Possible License(s): LGPL-2.1
  1. <?php
  2. /**
  3. * FormHandler v3.2
  4. *
  5. * Look for more info at http://www.formhandler.net
  6. * @package FormHandler
  7. */
  8. // make sure this file is not accessed directly
  9. if(strtolower(basename($_SERVER['PHP_SELF'])) == strtolower(basename(__FILE__)))
  10. {
  11. die('This file cannot be accessed directly! Include it in your script instead!');
  12. }
  13. /******* BUILD IN VALIDATOR FUNCTIONS *******/
  14. define('FH_STRING', 'IsString', true); // any string that doesn't have control characters (ASCII 0 - 31) but spaces are allowed
  15. define('FH_ALPHA', 'IsAlpha', true); // only letters a-z and A-Z
  16. define('FH_DIGIT', 'IsDigit', true); // only numbers 0-9
  17. define('FH_ALPHA_NUM', 'IsAlphaNum', true); // letters and numbers
  18. define('FH_INTEGER', 'IsInteger', true); // only numbers 0-9 and an optional - (minus) sign (in the beginning only)
  19. define('FH_FLOAT', 'IsFloat', true); // like FH_INTEGER, only with , (comma)
  20. define('FH_FILENAME', 'IsFilename', true); // a valid file name (including dots but no slashes and other forbidden characters)
  21. define('FH_BOOL', 'IsBool', true); // a boolean (TRUE is either a case-insensitive "true" or "1". Everything else is FALSE)
  22. define('FH_VARIABLE', 'IsVariabele', true); // a valid variable name (letters, digits, underscore)
  23. define('FH_PASSWORD', 'IsPassword', true); // a valid password (alphanumberic + some other characters but no spaces. Only allow ASCII 33 - 126)
  24. define('FH_URL', 'IsURL', true); // a valid URL
  25. define('FH_URL_HOST', 'IsURLHost', true); // a valid URL (http connection is used to check if url exists!)
  26. define('FH_EMAIL', 'IsEmail', true); // a valid email address (only checks for valid format: xxx@xxx.xxx)
  27. define('FH_EMAIL_HOST', 'IsEmailHost', true); // like FH_EMAIL only with host check
  28. define('FH_TEXT', 'IsText', true); // like FH_STRING, but newline characters are allowed
  29. define('FH_NOT_EMPTY', 'notEmpty', true); // check if the value is not empty
  30. define('FH_NO_HTML', 'NoHTML', true); // check if the value does not contain html
  31. define('FH_IP', 'IsIp', true); // check if the value is a valid ip adres (xxx.xxx.xxx.xxx:xxxx)
  32. // for dutch people
  33. define('FH_POSTCODE', 'IsPostcode', true); // valid dutch postcode (eg. 9999 AA)
  34. define('FH_PHONE', 'IsPhone', true); // valid dutch phone-number(eg. 058-2134778)
  35. // same as above, but with these the value is not required
  36. define('_FH_STRING', '_IsString', true);
  37. define('_FH_ALPHA', '_IsAlpha', true);
  38. define('_FH_DIGIT', '_IsDigit', true);
  39. define('_FH_ALPHA_NUM', '_IsAlphaNum', true);
  40. define('_FH_INTEGER', '_IsInteger', true);
  41. define('_FH_FLOAT', '_IsFloat', true);
  42. define('_FH_FILENAME', '_IsFilename', true);
  43. define('_FH_BOOL', '_IsBool', true);
  44. define('_FH_VARIABLE', '_IsVariabele', true);
  45. define('_FH_PASSWORD', '_IsPassword', true);
  46. define('_FH_URL', '_IsURL', true);
  47. define('_FH_URL_HOST', '_IsURLHost', true);
  48. define('_FH_EMAIL', '_IsEmail', true);
  49. define('_FH_EMAIL_HOST', '_IsEmailHost', true);
  50. define('_FH_TEXT', '_IsText', true);
  51. define('_FH_POSTCODE', '_IsPostcode', true);
  52. define('_FH_PHONE', '_IsPhone', true);
  53. define('_FH_NO_HTML', '_NoHTML', true);
  54. define('_FH_IP', '_IsIp', true);
  55. // Mask for titles above the fields..
  56. // This is not used by default but can be handy for the users
  57. define('FH_TITLE_ABOVE_FIELD_MASK',
  58. " <tr>\n".
  59. " <td>%title% %seperator%</td>\n".
  60. " </tr>\n".
  61. " <tr>\n".
  62. " <td>%field% %help% %error%</td>\n".
  63. " </tr>\n"
  64. );
  65. // make some variables global when the version < 4.1.0
  66. if(intval( str_replace('.', '', phpversion()) ) < 410)
  67. {
  68. define('_global', false);
  69. $_GET = $HTTP_GET_VARS;
  70. $_POST = $HTTP_POST_VARS;
  71. $_FILES = $HTTP_POST_FILES;
  72. $_SERVER = $HTTP_SERVER_VARS;
  73. }
  74. // set the var so that we dont have to make the $_GET arrays global
  75. else
  76. {
  77. define('_global', true);
  78. }
  79. // include needed files
  80. define('FH_INCLUDE_DIR', str_replace('\\', '/', dirname(__FILE__)).'/');
  81. require_once( FH_INCLUDE_DIR . 'fields/class.Field.php' );
  82. require_once( FH_INCLUDE_DIR . 'buttons/class.Button.php' );
  83. require_once( FH_INCLUDE_DIR . 'includes/config.inc.php' );
  84. require_once( FH_INCLUDE_DIR . 'includes/error.inc.php' );
  85. require_once( FH_INCLUDE_DIR . 'includes/class.Validator.php' );
  86. require_once( FH_INCLUDE_DIR . 'includes/class.MaskLoader.php' );
  87. /**
  88. * class FormHandler
  89. *
  90. * FormHandler without DB options
  91. *
  92. * @author Teye Heimans
  93. * @link http://www.formhandler.net
  94. */
  95. class FormHandler
  96. {
  97. // protected !!
  98. var $_fields; // array: contains all the fields
  99. var $_posted; // boolean: if the form is posted or not
  100. var $_name; // string: the name of the form
  101. var $_action; // string: the action of the form
  102. var $_displayErrors; // boolean: if we have to display the errors in the form
  103. var $_mask; // string: the mask which should be used
  104. var $_upload; // array: contains the names of the uploadfields
  105. var $_date; // array: contains the names of the datefields
  106. var $_onCorrect; // string: the callback function when the form is correct
  107. var $_add; // array: contains the data which was added by the user
  108. var $_focus; // string: the field which should get the focus
  109. var $_convert; // array: fields which should be converted (eg. resizeimage or mergeimage)
  110. var $_buffer; // array: buffer of set values (used when the field does not exists yet)
  111. var $_text; // array: the language array we are using to display the messages etc
  112. var $_lang; // string: the language used
  113. var $_setTable; // boolean: set a html table arround the fields or has the user done that in the mask ?
  114. var $_extra; // string: extra tag information for the <form> tag (like CSS or javascript)
  115. var $_pageCounter; // int: how many pages has this form
  116. var $_curPage; // int: current page
  117. var $_mail; // array: contains the mailing data
  118. var $_tabindexes; // array: tab indexes of the fields...
  119. var $_js; // array: contains all the needed javascript for the form
  120. var $_help; // array: contains the help text for the fields
  121. var $_helpIcon; // string: the path to the help image
  122. var $_cache; // array: save the values of the field in this array after the flush is called (then the objects are deleted!)
  123. var $_viewMode; // boolean: is view mode enabled or not
  124. var $_tableSettings; // array: array with all table settings
  125. var $_ajaxValidator; // boolean: if Ajax validation must be used or not.
  126. var $_ajaxValidatorScript; // boolean: if Ajax validation must include library or not.
  127. /**
  128. * FormHandler::FormHandler()
  129. *
  130. * constructor: initialisation of some vars
  131. *
  132. * @param string $name: the name for the form (used in the <form> tag
  133. * @param string $action: the action for the form (used in <form action="xxx">)
  134. * @param string $extra: extra css or js which is included in the <form> tag
  135. * @author Teye Heimans
  136. * @return FormHandler
  137. */
  138. function FormHandler( $name = null, $action = null, $extra = null )
  139. {
  140. // initialisation
  141. $this->_viewMode = false;
  142. $this->_ajaxValidator = false;
  143. $this->_ajaxValidatorScript = true;
  144. $this->_fields = array();
  145. $this->_date = array();
  146. $this->_upload = array();
  147. $this->_add = array();
  148. $this->_js = array();
  149. $this->_buffer = array();
  150. $this->_convert = array();
  151. $this->_mail = array();
  152. $this->_tabindexes = array();
  153. $this->_customMsg = array();
  154. $this->_help = array();
  155. $this->_cache = array();
  156. $this->_tableSettings = array();
  157. $this->_displayErrors = true;
  158. $this->_setTable = true;
  159. $this->_focus = null;
  160. $this->_pageCounter = 1;
  161. // make vars global if needed
  162. if(!_global) global $_SERVER, $_POST, $_GET;
  163. // try to disable caching from the browser if possible
  164. if(!headers_sent())
  165. {
  166. header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
  167. header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
  168. header('Cache-Control: no-store, no-cache, must-revalidate');
  169. header('Cache-Control: post-check=0, pre-check=0', false);
  170. header('Pragma: no-cache');
  171. header("Cache-control: private");
  172. }
  173. // set all config values
  174. fh_conf();
  175. // get config setting for _setTable, since 08-10-2009 JW
  176. $this->_setTable = FH_USE_TABLE;
  177. // get config setting for _focus, since 14-01-2010 JW
  178. $this->_focus = FH_SET_FOCUS;
  179. // set the name of the form (the user has submitted one)
  180. if( !empty($name) )
  181. {
  182. $this->_name = $name;
  183. }
  184. // get a unique form name because the user did not give one
  185. else
  186. {
  187. // get a unique form name!
  188. $i = null;
  189. while(defined('FH_'.FH_DEFAULT_FORM_NAME.$i))
  190. {
  191. $i = is_null($i) ? 1 : ($i+1);
  192. }
  193. define('FH_'.FH_DEFAULT_FORM_NAME.$i, 1);
  194. $this->_name = FH_DEFAULT_FORM_NAME.$i;
  195. $i = null;
  196. }
  197. // set the action of the form if none is given
  198. if( !empty($action) )
  199. {
  200. $this->_action = $action;
  201. }
  202. else
  203. {
  204. $this->_action = $_SERVER['PHP_SELF'];
  205. if( !empty($_SERVER['QUERY_STRING']) )
  206. {
  207. $this->_action .= '?'.$_SERVER['QUERY_STRING'];
  208. }
  209. }
  210. // get the $extra (JS, css, etc..) to put into the <form> tag
  211. if( !empty( $extra ) )
  212. {
  213. $this->_extra = $extra;
  214. }
  215. // set the default mask
  216. $this->setMask( FH_DEFAULT_ROW_MASK );
  217. // set the default help icon
  218. $this->setHelpIcon( FH_FHTML_DIR.'images/helpicon.gif' );
  219. // check if the form is posted
  220. $this->_posted = ($_SERVER['REQUEST_METHOD'] == 'POST' && isset($_POST[$this->_name.'_submit']));
  221. // make a hidden field so we can identify the form
  222. $this->hiddenField( $this->_name.'_submit', '1' );
  223. // get the current page
  224. $this->_curPage = isset($_POST[$this->_name.'_page']) ? $_POST[$this->_name.'_page'] : 1;
  225. // set our own error handler
  226. if(FH_DISPLAY_ERRORS)
  227. {
  228. error_reporting( E_ALL );
  229. set_error_handler( 'catchErrors' );
  230. }
  231. // set the language...
  232. $this->setLanguage();
  233. // set the default table settings
  234. $this->setTableSettings();
  235. }
  236. /********************************************************/
  237. /************* FIELDS ***********************************/
  238. /********************************************************/
  239. /**
  240. * FormHandler::browserField()
  241. *
  242. * Creates a browserfield on the form
  243. *
  244. * @param string $title: The title of the field
  245. * @param string $name: The name of the field
  246. * @param string $path: The path to browse
  247. * @param string $validator: The validator which should be used to validate the value of the field
  248. * @param int $size: The size of the field
  249. * @param string $extra: CSS, Javascript or other which are inserted into the HTML tag
  250. * @return void
  251. * @access public
  252. * @author Johan Wiegel
  253. */
  254. function browserField(
  255. $title,
  256. $name,
  257. $path,
  258. $validator = null,
  259. $size = null,
  260. $extra = null)
  261. {
  262. require_once(FH_INCLUDE_DIR.'fields/class.BrowserField.php');
  263. require_once(FH_INCLUDE_DIR.'buttons/class.Button.php');
  264. // create the field
  265. $fld = new BrowserField($this, $name, $path);
  266. if(!empty($validator)) $fld->setValidator( $validator );
  267. if(!empty($size)) $fld->setSize( $size );
  268. if(!empty($extra)) $fld->setExtra( $extra );
  269. // register the field
  270. $this->_registerField( $name, $fld, $title );
  271. }
  272. /**
  273. * FormHandler::textField()
  274. *
  275. * Creates a textfield on the form
  276. *
  277. * @param string $title: The title of the field
  278. * @param string $name: The name of the field
  279. * @param string $validator: The validator which should be used to validate the value of the field
  280. * @param int $size: The size of the field
  281. * @param int $maxlength: The allowed max input of the field
  282. * @param string $extra: CSS, Javascript or other which are inserted into the HTML tag
  283. * @return void
  284. * @access public
  285. * @author Teye Heimans
  286. */
  287. function textField(
  288. $title,
  289. $name,
  290. $validator = null,
  291. $size = null,
  292. $maxlength = null,
  293. $extra = null)
  294. {
  295. require_once(FH_INCLUDE_DIR.'fields/class.TextField.php');
  296. // create the field
  297. $fld = new TextField($this, $name);
  298. if(!empty($validator)) $fld->setValidator( $validator );
  299. if(!empty($size)) $fld->setSize( $size );
  300. if(!empty($maxlength)) $fld->setMaxlength( $maxlength );
  301. if(!empty($extra)) $fld->setExtra( $extra );
  302. // register the field
  303. $this->_registerField( $name, $fld, $title );
  304. }
  305. /**
  306. * FormHandler::captchaField()
  307. *
  308. * Creates a captchafield on the form using Securimage - A PHP class for creating and managing form CAPTCHA images
  309. *
  310. * @param string $title: The title of the field
  311. * @param string $name: The name of the field
  312. * @param int $size: The size of the field
  313. * @param int $maxlength: The allowed max input of the field
  314. * @param string $extra: CSS, Javascript or other which are inserted into the HTML tag
  315. * @return void
  316. * @access public
  317. * @author Johan Wiegel
  318. * @since 27-11-2007
  319. */
  320. function CaptchaField(
  321. $title,
  322. $name,
  323. $size = null,
  324. $maxlength = null,
  325. $extra = null)
  326. {
  327. static $bCaptcha = true;
  328. if ($bCaptcha)
  329. {
  330. $bCaptcha = false;
  331. require_once(FH_INCLUDE_DIR.'fields/class.TextField.php');
  332. // create the field
  333. $fld = new TextField($this, $name);
  334. if( $this->isPosted() )
  335. {
  336. $fld->setValidator( 'FH_CAPTCHA' );
  337. }
  338. if(!empty($size)) $fld->setSize( $size );
  339. if(!empty($maxlength)) $fld->setMaxlength( $maxlength );
  340. if(!empty($extra)) $fld->setExtra( $extra );
  341. $this->ImageButton( FH_FHTML_DIR .'securimage/securimage_show.php?sid='.md5(uniqid(time())),null,'onclick="return false;" style="cursor:default;"' );
  342. // register the field
  343. $this->_registerField( $name, $fld, $title );
  344. // empty the field if the value was not correct.
  345. if ($this->isPosted() && !$this->isCorrect())
  346. {
  347. $this->setValue($name, "", true);
  348. }
  349. }
  350. else
  351. {
  352. trigger_error( "Only one captchafield in a form", E_USER_WARNING );
  353. }
  354. }
  355. /**
  356. * FormHandler::textSelectField()
  357. *
  358. * Creates a textSelectfield on the form
  359. *
  360. * @param string $title: The title of the field
  361. * @param string $name: The name of the field
  362. * @param array $aOptions : the options for the select part
  363. * @param string $validator: The validator which should be used to validate the value of the field
  364. * @param int $size: The size of the field
  365. * @param int $maxlength: The allowed max input of the field
  366. * @param string $extra: CSS, Javascript or other which are inserted into the HTML tag
  367. * @return void
  368. * @access public
  369. * @author Johan wiegel
  370. * @since 22-10-2008
  371. */
  372. function textSelectField(
  373. $title,
  374. $name,
  375. $aOptions,
  376. $validator = null,
  377. $size = null,
  378. $maxlength = null,
  379. $extra = null)
  380. {
  381. require_once(FH_INCLUDE_DIR.'fields/class.TextField.php');
  382. require_once(FH_INCLUDE_DIR.'fields/class.TextSelectField.php');
  383. // create the field
  384. $fld = new TextSelectField($this, $name, $aOptions);
  385. if(!empty($validator)) $fld->setValidator( $validator );
  386. if(!empty($size)) $fld->setSize( $size );
  387. if(!empty($maxlength)) $fld->setMaxlength( $maxlength );
  388. if(!empty($extra)) $fld->setExtra( $extra );
  389. // register the field
  390. $this->_registerField( $name, $fld, $title );
  391. }
  392. /**
  393. * FormHandler::passField()
  394. *
  395. * Create a password field
  396. *
  397. * @param string $title: The title of the field
  398. * @param string $name: The name of the field
  399. * @param string $validator: The validator which should be used to validate the value of the field
  400. * @param int $size: The size of the field
  401. * @param int $maxlength: The allowed max input of the field
  402. * @param string $extra: CSS, Javascript or other which are inserted into the HTML tag
  403. * @return void
  404. * @access public
  405. * @author Teye Heimans
  406. */
  407. function passField(
  408. $title,
  409. $name,
  410. $validator = null,
  411. $size = null,
  412. $maxlength = null,
  413. $extra = null)
  414. {
  415. require_once(FH_INCLUDE_DIR.'fields/class.TextField.php');
  416. require_once(FH_INCLUDE_DIR.'fields/class.PassField.php');
  417. // create the field
  418. $fld = new PassField( $this, $name );
  419. if(!empty($validator)) $fld->setValidator( $validator );
  420. if(!empty($size)) $fld->setSize( $size );
  421. if(!empty($maxlength)) $fld->setMaxlength( $maxlength );
  422. if(!empty($extra)) $fld->setExtra( $extra );
  423. // register the field
  424. $this->_registerField( $name, $fld, $title );
  425. }
  426. /**
  427. * FormHandler::hiddenField()
  428. *
  429. * Create a hidden field
  430. *
  431. * @param string $name: The name of the field
  432. * @param string $value: The value of the field
  433. * @param string $validator: The validator which should be used to validate the value of the field
  434. * @param string $extra: CSS, Javascript or other which are inserted into the HTML tag
  435. * @return void
  436. * @access public
  437. * @author Teye Heimans
  438. */
  439. function hiddenField(
  440. $name,
  441. $value = null,
  442. $validator = null,
  443. $extra = null)
  444. {
  445. require_once(FH_INCLUDE_DIR.'fields/class.HiddenField.php');
  446. // create new hidden field
  447. $fld = new HiddenField($this, $name);
  448. // only set the hidden field value if there is not a value in the $_POST array
  449. if(!is_null($value) && !$this->isPosted() )
  450. $fld->setValue( $value );
  451. if(!empty($validator)) $fld->setValidator( $validator );
  452. if(!empty($extra)) $fld->setExtra( $extra );
  453. // register the field
  454. $this->_registerField( $name, $fld, '__HIDDEN__' );
  455. }
  456. /**
  457. * FormHandler::textArea()
  458. *
  459. * Create a textarea on the form
  460. *
  461. * @param string $title: The title of the field
  462. * @param string $name: The name of the field
  463. * @param string $validator: The validator which should be used to validate the value of the field
  464. * @param int $cols: How many cols (the width of the field)
  465. * @param int $rows: How many rows (the height of the field)
  466. * @param string $extra: CSS, Javascript or other which are inserted into the HTML tag
  467. * @return void
  468. * @access public
  469. * @author Teye Heimans
  470. */
  471. function textArea(
  472. $title,
  473. $name,
  474. $validator = null,
  475. $cols = null,
  476. $rows = null,
  477. $extra = null)
  478. {
  479. require_once(FH_INCLUDE_DIR.'fields/class.TextArea.php');
  480. // create new textarea
  481. $fld = new TextArea($this, $name);
  482. if(!empty($validator)) $fld->setValidator( $validator );
  483. if(!empty($cols)) $fld->setCols( $cols );
  484. if(!empty($rows)) $fld->setRows( $rows );
  485. if(!empty($extra)) $fld->setExtra( $extra );
  486. // register the field
  487. $this->_registerField( $name, $fld, $title );
  488. }
  489. /**
  490. * FormHandler::selectField()
  491. *
  492. * Create a selectField on the form
  493. *
  494. * @param string $title: The title of the field
  495. * @param string $name: The name of the field
  496. * @param array $options: The options used for the field
  497. * @param string $validator: The validator which should be used to validate the value of the field
  498. * @param boolean $useArrayKeyAsValue: If the array key's are the values for the options in the field
  499. * @param boolean $multiple: Should it be possible to select multiple options ? (Default: false)
  500. * @param int $size: The size of the field (how many options are displayed)
  501. * @param string $extra: CSS, Javascript or other which are inserted into the HTML tag
  502. * @return void
  503. * @access public
  504. * @author Teye Heimans
  505. */
  506. function selectField(
  507. $title,
  508. $name,
  509. $options,
  510. $validator = null,
  511. $useArrayKeyAsValue = null,
  512. $multiple = null,
  513. $size = null,
  514. $extra = null)
  515. {
  516. require_once(FH_INCLUDE_DIR.'fields/class.SelectField.php');
  517. // options has to be an array
  518. if(!is_array($options))
  519. {
  520. trigger_error(
  521. "You have to give an array as value with the selectfield '$name'",
  522. E_USER_WARNING
  523. );
  524. return;
  525. }
  526. // create new selectfield
  527. $fld = new SelectField( $this, $name );
  528. $fld->setOptions( $options );
  529. if(!empty($validator)) $fld->setValidator( $validator );
  530. if(!is_null($useArrayKeyAsValue)) $fld->useArrayKeyAsValue( $useArrayKeyAsValue );
  531. if(!empty($extra)) $fld->setExtra( $extra );
  532. if($multiple) $fld->setMultiple( $multiple );
  533. // if the size is given
  534. if(!empty($size))
  535. {
  536. $fld->setSize( $size );
  537. }
  538. // if no size is set and multiple is enabled, set the size default to 4
  539. else if( $multiple )
  540. {
  541. $fld->setSize( 4 );
  542. }
  543. // register the field
  544. $this->_registerField( $name, $fld, $title );
  545. }
  546. /**
  547. * FormHandler::checkBox()
  548. *
  549. * Create a checkBox on the form
  550. *
  551. * @param string $title: The title of the field
  552. * @param string $name: The name of the field
  553. * @param array|string $value: The option(s) used for the field
  554. * @param string $validator: The validator which should be used to validate the value of the field
  555. * @param boolean $useArrayKeyAsValue: If the array key's are the values for the options in the field
  556. * @param string $extra: CSS, Javascript or other which are inserted into the HTML tag
  557. * @param string $mask: if more the 1 options are given, glue the fields together with this mask
  558. * @return void
  559. * @access public
  560. * @author Teye Heimans
  561. */
  562. function checkBox(
  563. $title,
  564. $name,
  565. $value = 'on',
  566. $validator = null,
  567. $useArrayKeyAsValue = null,
  568. $extra = null,
  569. $mask = null)
  570. {
  571. require_once(FH_INCLUDE_DIR.'fields/class.CheckBox.php');
  572. // create a new checkbox
  573. $fld = new CheckBox($this, $name, $value);
  574. if(!empty($validator)) $fld->setValidator( $validator );
  575. if(!is_null($useArrayKeyAsValue)) $fld->useArrayKeyAsValue( $useArrayKeyAsValue );
  576. if(!empty($extra)) $fld->setExtra( $extra );
  577. if(!empty($mask)) $fld->setMask( $mask );
  578. // register the field
  579. $this->_registerField( $name, $fld, $title );
  580. }
  581. /**
  582. * FormHandler::radioButton()
  583. *
  584. * Create a radioButton on the form
  585. *
  586. * @param string $title: The title of the field
  587. * @param string $name: The name of the field
  588. * @param array $options: The options used for the field
  589. * @param string $validator: The validator which should be used to validate the value of the field
  590. * @param boolean $useArrayKeyAsValue: If the array key's are the values for the options in the field
  591. * @param string $extra: CSS, Javascript or other which are inserted into the HTML tag
  592. * @param string $mask: if more the 1 options are given, glue the fields together with this mask
  593. * @return void
  594. * @access public
  595. * @author Teye Heimans
  596. */
  597. function radioButton(
  598. $title,
  599. $name,
  600. $options,
  601. $validator = null,
  602. $useArrayKeyAsValue = null,
  603. $extra = null,
  604. $mask = null)
  605. {
  606. require_once(FH_INCLUDE_DIR.'fields/class.RadioButton.php');
  607. // value has to be an array
  608. if(!is_array($options))
  609. {
  610. trigger_error(
  611. "You have to give an array as value with the radiobutton '$name'",
  612. E_USER_WARNING
  613. );
  614. return;
  615. }
  616. // create a new checkbox
  617. $fld = new RadioButton($this, $name, $options);
  618. if(!empty($validator)) $fld->setValidator( $validator );
  619. if(!is_null($useArrayKeyAsValue)) $fld->useArrayKeyAsValue( $useArrayKeyAsValue );
  620. if(!empty($extra)) $fld->setExtra( $extra );
  621. if(!empty($mask)) $fld->setMask( $mask );
  622. // register the field
  623. $this->_registerField( $name, $fld, $title );
  624. }
  625. /**
  626. * FormHandler::uploadField()
  627. *
  628. * Create a uploadField on the form
  629. *
  630. * @param string $title: The title of the field
  631. * @param string $name: The name of the field
  632. * @param array $config: The configuration used for the field
  633. * @param string $validator: The validator which should be used to validate the value of the field
  634. * @param string $extra: CSS, Javascript or other which are inserted into the HTML tag
  635. * @param string $alertOverwrite: Do we have to alert the user when he/she is going to overwrite a file?
  636. * @return void
  637. * @access public
  638. * @author Teye Heimans
  639. */
  640. function uploadField(
  641. $title,
  642. $name,
  643. $config = array(),
  644. $validator = null,
  645. $extra = null,
  646. $alertOverwrite = null)
  647. {
  648. require_once(FH_INCLUDE_DIR.'fields/class.UploadField.php');
  649. // create a new uploadfield
  650. $fld = new UploadField($this, $name, $config);
  651. if(!empty($validator)) $fld->setValidator( $validator );
  652. if(!empty($extra)) $fld->setExtra( $extra );
  653. if(!is_null($alertOverwrite)) $fld->setAlertOverwrite( $alertOverwrite );
  654. // register the field
  655. $this->_registerField( $name, $fld, $title );
  656. // set that this form is using uploadfields
  657. $this->_upload[] = $name;
  658. }
  659. /**
  660. * FormHandler::listField()
  661. *
  662. * Create a listField on the form
  663. *
  664. * @param string $title: The title of the field
  665. * @param string $name: The name of the field
  666. * @param array $options: The options used for the field
  667. * @param string $validator: The validator which should be used to validate the value of the field
  668. * @param string $onTitle: The title used above the ON section of the field
  669. * @param string $offTitle: The title used above the OFF section of the field
  670. * @param boolean $useArrayKeyAsValue: If the array key's are the values for the options in the field
  671. * @param int $size: The size of the field (how many options are displayed)
  672. * @param string $extra: CSS, Javascript or other which are inserted into the HTML tag
  673. * @param string $verticalMode: Verticalmode
  674. * @return void
  675. * @access public
  676. * @author Teye Heimans
  677. */
  678. function listField(
  679. $title,
  680. $name,
  681. $options,
  682. $validator = null,
  683. $useArrayKeyAsValue = null,
  684. $onTitle = null,
  685. $offTitle = null,
  686. $size = null,
  687. $extra = null,
  688. $verticalMode = null)
  689. {
  690. require_once(FH_INCLUDE_DIR.'fields/class.SelectField.php');
  691. require_once(FH_INCLUDE_DIR.'fields/class.ListField.php');
  692. // options has to be an array
  693. if(!is_array($options))
  694. {
  695. trigger_error(
  696. "You have to give an array as value with the listfield '$name'",
  697. E_USER_WARNING
  698. );
  699. return;
  700. }
  701. // create a listfield
  702. $fld = new ListField( $this, $name, $options );
  703. if(!empty($validator)) $fld->setValidator( $validator );
  704. if(!is_null($useArrayKeyAsValue)) $fld->useArrayKeyAsValue( $useArrayKeyAsValue );
  705. if(!empty($size)) $fld->setSize( $size );
  706. if(!empty($extra)) $fld->setExtra( $extra );
  707. if(!empty($onTitle)) $fld->setOnTitle( $onTitle );
  708. if(!empty($offTitle)) $fld->setOffTitle( $offTitle );
  709. if(!empty($verticalMode)) $fld->setVerticalMode( $verticalMode );
  710. // register the field
  711. $this->_registerField( $name, $fld, $title );
  712. }
  713. /**
  714. * FormHandler::editor()
  715. *
  716. * Create a editor on the form
  717. *
  718. * @param string $title: The title of the field
  719. * @param string $name: The name of the field
  720. * @param string $validator: The validator which should be used to validate the value of the field
  721. * @param string $path: Path on the server where we have to upload the files
  722. * @param string $toolbar: The toolbar we have to use
  723. * @param string $skin: The skin to use
  724. * @param int $width: The width of the field
  725. * @param int $height: The height of the field
  726. * @param boolean $useArrayKeyAsValue: If the array key's are the values for the options in the field
  727. * @param string $extra: CSS, Javascript or other which are inserted into the HTML tag
  728. * @return void
  729. * @access public
  730. * @author Teye Heimans
  731. */
  732. function editor(
  733. $title,
  734. $name,
  735. $validator = null,
  736. $path = null,
  737. $toolbar = null,
  738. $skin = null,
  739. $width = null,
  740. $height = null,
  741. $config = null)
  742. {
  743. require_once(FH_INCLUDE_DIR.'fields/class.Editor.php');
  744. require_once(FH_FHTML_INCLUDE_DIR . 'ckeditor/ckeditor.php');
  745. // create a new editor
  746. $fld = new Editor( $this, $name );
  747. if(!empty($validator)) $fld->setValidator( $validator );
  748. if(!is_null($path)) $fld->setServerPath( $path );
  749. if(!empty($toolbar)) $fld->setToolbar( $toolbar );
  750. if(!empty($skin)) $fld->setSkin( $skin );
  751. if(!empty($width)) $fld->setWidth( $width );
  752. if(!empty($height)) $fld->setHeight( $height );
  753. if(is_array($config)) $fld->setConfig( $config );
  754. // register the field
  755. $this->_registerField( $name, $fld, $title );
  756. }
  757. /**
  758. * FormHandler::dateField()
  759. *
  760. * Create a dateField on the form
  761. *
  762. * @param string $title: The title of the field
  763. * @param string $name: The name of the field
  764. * @param string $validator: The validator which should be used to validate the value of the field
  765. * @param boolean $required: If the field is required to fill in or can the user leave it blank
  766. * @param string $mask: How do we have to display the fields? These can be used: d, m and y.
  767. * @param string $interval: The interval between the current year and the years to start/stop.Default the years are beginning at 90 yeas from the current. It is also possible to have years in the future. This is done like this: "90:10" (10 years in the future).
  768. * @param string $extra: CSS, Javascript or other which are inserted into the HTML tag
  769. * @return void
  770. * @access public
  771. * @author Teye Heimans
  772. */
  773. function dateField(
  774. $title,
  775. $name,
  776. $validator = null,
  777. $required = null,
  778. $mask = null,
  779. $interval = null,
  780. $extra = null)
  781. {
  782. require_once(FH_INCLUDE_DIR.'fields/class.SelectField.php');
  783. require_once(FH_INCLUDE_DIR.'fields/class.TextField.php');
  784. require_once(FH_INCLUDE_DIR.'fields/class.DateField.php');
  785. // create a new datefield
  786. $fld = new DateField(
  787. $this,
  788. $name,
  789. !empty($mask) ? $mask : null,
  790. $required,
  791. $interval
  792. );
  793. if(!empty($validator)) $fld->setValidator( $validator );
  794. if(!empty($extra)) $fld->setExtra( $extra );
  795. /// register the field
  796. $this->_registerField( $name, $fld, $title );
  797. // save the field in the datefields array (special treatment! :)
  798. $this->_date[] = $name;
  799. }
  800. /**
  801. * FormHandler::jsDateField()
  802. *
  803. * Create a dateField with a jscalendar popup on the form
  804. *
  805. * @param string $title: The title of the field
  806. * @param string $name: The name of the field
  807. * @param string $validator: The validator which should be used to validate the value of the field
  808. * @param boolean $required: If the field is required to fill in or can the user leave it blank
  809. * @param string $mask: How do we have to display the fields? These can be used: d, m and y.
  810. * @param string $interval: The interval between the current year and the years to start/stop.Default the years are beginning at 90 yeas from the current. It is also possible to have years in the future. This is done like this: "90:10" (10 years in the future).
  811. * @param string $extra: CSS, Javascript or other which are inserted into the HTML tag
  812. * @param boolean $bIncludeJS: Should we include the js file (only needed once on a page)
  813. * @return void
  814. * @access public
  815. * @author Teye Heimans
  816. */
  817. function jsDateField(
  818. $title,
  819. $name,
  820. $validator = null,
  821. $required = null,
  822. $mask = null,
  823. $interval = null,
  824. $extra = null,
  825. $bIncludeJS = true
  826. )
  827. {
  828. require_once(FH_INCLUDE_DIR.'fields/class.SelectField.php');
  829. require_once(FH_INCLUDE_DIR.'fields/class.TextField.php');
  830. require_once(FH_INCLUDE_DIR.'fields/class.DateField.php');
  831. require_once(FH_INCLUDE_DIR.'fields/class.jsDateField.php');
  832. // create a new datefield
  833. $fld = new jsDateField( $this, $name, $mask, $required, $interval, $bIncludeJS );
  834. if(!empty($validator)) $fld->setValidator( $validator );
  835. if(!empty($extra)) $fld->setExtra( $extra );
  836. // register the field
  837. $this->_registerField( $name, $fld, $title );
  838. // save the field in the datefields array (special treatment! :)
  839. $this->_date[] = $name;
  840. }
  841. /**
  842. * FormHandler::timeField()
  843. *
  844. * Create a timeField on the form
  845. *
  846. * @param string $title: The title of the field
  847. * @param string $name: The name of the field
  848. * @param string $validator: The validator which should be used to validate the value of the field
  849. * @param int $format: 12 or 24. Which should we use?
  850. * @param string $extra: CSS, Javascript or other which are inserted into the HTML tag
  851. * @return void
  852. * @access public
  853. * @author Teye Heimans
  854. */
  855. function timeField(
  856. $title,
  857. $name,
  858. $validator = null,
  859. $required = null,
  860. $format = null,
  861. $extra = null)
  862. {
  863. require_once(FH_INCLUDE_DIR.'fields/class.SelectField.php');
  864. require_once(FH_INCLUDE_DIR.'fields/class.TimeField.php');
  865. // create a new timefield
  866. $fld = new TimeField($this, $name);
  867. if(!empty($validator)) $fld->setValidator( $validator );
  868. if(!is_null($required)) $fld->setRequired( $required );
  869. if(!empty($format)) $fld->setHourFormat( $format );
  870. if(!empty($extra)) $fld->setExtra( $extra );
  871. // register the field
  872. $this->_registerField( $name, $fld, $title );
  873. }
  874. /**
  875. * FormHandler::colorPicker()
  876. *
  877. * Creates a colorpicker on the form
  878. *
  879. * @param string $title: The title of the field
  880. * @param string $name: The name of the field
  881. * @param string $validator: The validator which should be used to validate the value of the field
  882. * @param int $size: The size of the field
  883. * @param int $maxlength: The allowed max input of the field
  884. * @param string $extra: CSS, Javascript or other which are inserted into the HTML tag
  885. * @return void
  886. * @access public
  887. * @author Johan Wiegel
  888. * @since 23-10-2008
  889. */
  890. function colorPicker(
  891. $title,
  892. $name,
  893. $validator = null,
  894. $size = null,
  895. $maxlength = null,
  896. $extra = null)
  897. {
  898. require_once(FH_INCLUDE_DIR. 'fields/class.ColorPicker.php');
  899. // create the field
  900. $fld = new ColorPicker($this, $name);
  901. if(!empty($validator)) $fld->setValidator( $validator );
  902. if(!empty($size)) $fld->setSize( $size );
  903. if(!empty($maxlength)) $fld->setMaxlength( $maxlength );
  904. if(!empty($extra)) $fld->setExtra( $extra );
  905. // register the field
  906. $this->_registerField( $name, $fld, $title.$fld->sTitleAdd );
  907. }
  908. /**
  909. * FormHandler::dateTextField()
  910. *
  911. * Create a dateTextField on the form
  912. * Validator added by Johan Wiegel
  913. *
  914. * @param string $title: The title of the field
  915. * @param string $name: The name of the field
  916. * @param string $validator: The validator which should be used to validate the value of the field
  917. * @param string $mask: How do we have to display the fields? These can be used: d, m and y. (Only for DB-Field with Type 'Date')
  918. * @param bool $bParseOtherPresentations: try to parse other presentations of dateformat
  919. * @param string $extra: CSS, Javascript or other which are inserted into the HTML tag
  920. * @return void
  921. * @access public
  922. * @author Thomas Branius
  923. * @since 16-03-2010
  924. */
  925. function dateTextField(
  926. $title,
  927. $name,
  928. $validator = null,
  929. $mask = null,
  930. $bParseOtherPresentations = false,
  931. $extra = null
  932. )
  933. {
  934. require_once(FH_INCLUDE_DIR.'fields/class.TextField.php');
  935. require_once(FH_INCLUDE_DIR.'fields/class.DateTextField.php');
  936. // create a new datetextfield
  937. $fld = new DateTextField(
  938. $this,
  939. $name,
  940. !empty($mask) ? $mask : null,
  941. $bParseOtherPresentations
  942. );
  943. if(!empty($validator)) $fld->setValidator( $validator );
  944. if(!empty($extra)) $fld->setExtra( $extra );
  945. /// register the field
  946. $this->_registerField( $name, $fld, $title );
  947. // save the field in the datefields array (special treatment! :)
  948. $this->_date[] = $name;
  949. }
  950. /**
  951. * FormHandler::jsdateTextField()
  952. *
  953. * Create a dateTextField on the form
  954. * Validator added by Johan Wiegel
  955. *
  956. * @param string $title: The title of the field
  957. * @param string $name: The name of the field
  958. * @param string $mask: How do we have to display the fields? These can be used: d, m and y. (Only for DB-Field with Type 'Date')
  959. * @param bool $bParseOtherPresentations: try to parse other presentations of dateformat
  960. * @param boolean $bIncludeJS: Should we include the js file (only needed once on a page)
  961. * @param string $extra: CSS, Javascript or other which are inserted into the HTML tag
  962. * @param boolean $bIncludeJS: Should we include the js file (only needed once on a page)
  963. * @return void
  964. * @access public
  965. * @author Thomas Branius
  966. * @since 16-03-2010
  967. */
  968. function jsDateTextField(
  969. $title,
  970. $name,
  971. $validator = null,
  972. $mask = null,
  973. $bParseOtherPresentations = false,
  974. $extra = null,
  975. $bIncludeJS = true
  976. )
  977. {
  978. require_once(FH_INCLUDE_DIR.'fields/class.TextField.php');
  979. require_once(FH_INCLUDE_DIR.'fields/class.DateTextField.php');
  980. require_once(FH_INCLUDE_DIR.'fields/class.jsDateTextField.php');
  981. // create a new datetextfield
  982. $fld = new jsDateTextField(
  983. $this,
  984. $name,
  985. !empty($mask) ? $mask : null,
  986. $bParseOtherPresentations,
  987. $bIncludeJS
  988. );
  989. if(!empty($validator)) $fld->setValidator( $validator );
  990. if(!empty($extra)) $fld->setExtra( $extra );
  991. /// register the field
  992. $this->_registerField( $name, $fld, $title );
  993. // save the field in the datefields array (special treatment! :)
  994. $this->_date[] = $name;
  995. }
  996. /*****************/
  997. /**** BUTTONS ****/
  998. /*****************/
  999. /**
  1000. * FormHandler::button()
  1001. *
  1002. * Create a button on the form
  1003. *
  1004. * @param string $caption: The caption of the button
  1005. * @param string $name: The name of the button
  1006. * @param string $extra: CSS, Javascript or other which are inserted into the HTML tag
  1007. * @return void
  1008. * @access public
  1009. * @author Teye Heimans
  1010. */
  1011. function button( $caption, $name = null, $extra = null)
  1012. {
  1013. // get new button name if none is given
  1014. if( empty($name) )
  1015. {
  1016. $name = $this->_getNewButtonName();
  1017. }
  1018. // create new submitbutton
  1019. $btn = new Button( $this, $name );
  1020. $btn->setCaption( $caption );
  1021. if(!empty($extra))
  1022. {
  1023. $btn->setExtra($extra);
  1024. }
  1025. // register the button
  1026. $this->_registerField( $name, $btn );
  1027. }
  1028. /**
  1029. * FormHandler::submitButton()
  1030. *
  1031. * Create a submitButton on the form
  1032. *
  1033. * @param string $caption: The caption of the button
  1034. * @param string $name: The name of the button
  1035. * @param string $extra: CSS, Javascript or other which are inserted into the HTML tag
  1036. * @param boolean $disableOnSubmit: Disable the button when it is pressed
  1037. * @return void
  1038. * @access public
  1039. * @author Teye Heimans
  1040. */
  1041. function submitButton( $caption = null, $name = null, $extra = null, $disableOnSubmit = null)
  1042. {
  1043. require_once(FH_INCLUDE_DIR.'buttons/class.SubmitButton.php');
  1044. // get new button name if none is given
  1045. if( empty($name) )
  1046. {
  1047. $name = $this->_getNewButtonName();
  1048. }
  1049. // create new submitbutton
  1050. $btn = new SubmitButton( $this, $name );
  1051. if(!empty($caption)) $btn->setCaption( $caption );
  1052. if(!empty($extra)) $btn->setExtra( $extra );
  1053. if(!is_null($disableOnSubmit)) $btn->disableOnSubmit( $disableOnSubmit );
  1054. // register the button
  1055. $this->_registerField( $name, $btn );
  1056. }
  1057. /**
  1058. * FormHandler::imageButton()
  1059. *
  1060. * Create a imageButton on the form
  1061. *
  1062. * @param string $image: The image URL which should be a button
  1063. * @param string $name: The name of the button
  1064. * @param string $extra: CSS, Javascript or other which are inserted into the HTML tag
  1065. * @param boolean $disableOnSubmit: Disable the button when it is pressed
  1066. * @return void
  1067. * @access public
  1068. * @author Teye Heimans
  1069. */
  1070. function imageButton( $image, $name = null, $extra = null )
  1071. {
  1072. require_once(FH_INCLUDE_DIR.'buttons/class.ImageButton.php');
  1073. // get new button name if none is given
  1074. if( empty($name) )
  1075. {
  1076. $name = $this->_getNewButtonName();
  1077. }
  1078. // create the image button
  1079. $btn = new ImageButton( $this, $name, $image );
  1080. if(!empty($extra)) $btn->setExtra( $extra );
  1081. // register the button
  1082. $this->_registerField( $name, $btn );
  1083. }
  1084. /**
  1085. * FormHandler::resetButton()
  1086. *
  1087. * Create a resetButton on the form
  1088. *
  1089. * @param string $caption: The caption of the button
  1090. * @param string $name: The name of the button
  1091. * @param string $extra: CSS, Javascript or other which are inserted into the HTML tag
  1092. * @return void
  1093. * @access public
  1094. * @author Teye Heimans
  1095. */
  1096. function resetButton($caption = null, $name = null, $extra = null)
  1097. {
  1098. require_once(FH_INCLUDE_DIR.'buttons/class.ResetButton.php');
  1099. // get new button name if none given
  1100. if(empty($name))
  1101. {
  1102. $name = $this->_getNewButtonName();
  1103. }
  1104. // create new resetbutton
  1105. $btn = new ResetButton( $this, $name );
  1106. if(!empty($caption)) $btn->setCaption( $caption );
  1107. if(!empty($extra)) $btn->setExtra( $extra );
  1108. // register the button
  1109. $this->_registerField( $name, $btn );
  1110. }
  1111. /**
  1112. * FormHandler::cancelButton()
  1113. *
  1114. * Create a cancelButton on the form
  1115. *
  1116. * @param string $caption: The caption of the button
  1117. * @param string $url: The URL to go to when the button is clicked
  1118. * @param string $name: The name of the button
  1119. * @param string $extra: CSS, Javascript or other which are inserted into the HTML tag
  1120. * @return void
  1121. * @access public
  1122. * @author Teye Heimans
  1123. */
  1124. function cancelButton($caption = null, $url = null, $name = null, $extra = null)
  1125. {
  1126. // get new button name if none given
  1127. if(empty($name))
  1128. {
  1129. $name = $this->_getNewButtonName();
  1130. }
  1131. if( !$url )
  1132. {
  1133. $url = 'history.back(-1)';
  1134. }
  1135. // where to go when the button is clicked...
  1136. $extra .= preg_match('/history/', $url) ? ' onclick="'.$url.'"' : ' onclick="document.location.href=\''.$url.'\'"';
  1137. // if no caption is given, get our own caption
  1138. if(is_null($caption))
  1139. {
  1140. $caption = $this->_text( 28 );
  1141. }
  1142. // create new button
  1143. $btn = new Button( $this, $name );
  1144. $btn->setCaption( $caption );
  1145. if(!empty($extra))
  1146. {
  1147. $btn->setExtra( $extra );
  1148. }
  1149. // register the button
  1150. $this->_registerField( $name, $btn );
  1151. }
  1152. /**
  1153. * FormHandler::backButton()
  1154. *
  1155. * Generate a back button to go one page back in a multi-paged form
  1156. *
  1157. * @param string $caption: The caption of the button
  1158. * @param string $name: The name of the button
  1159. * @param string $extra: CSS, Javascript or other which are inserted into the HTML tag
  1160. * @return void
  1161. * @access public
  1162. * @author Teye Heimans
  1163. */
  1164. function backButton( $caption = null, $name = null, $extra = null)
  1165. {
  1166. static $setJS = false;
  1167. // include the needed javascript file
  1168. if( !$setJS )
  1169. {
  1170. $this->_setJS(FH_FHTML_DIR.'js/page_back.js', true);
  1171. $setJS = true;
  1172. }
  1173. // get new button name if none given
  1174. if(empty($name))
  1175. {
  1176. $name = $this->_getNewButtonName();
  1177. }
  1178. $extra .= ' onclick="pageBack(document.forms[\''.$this->_name.'\']);"';
  1179. // if no caption is given, get our own caption
  1180. if(is_null($caption))
  1181. {
  1182. $caption = $this->_text( 38 );
  1183. }
  1184. // create new button
  1185. $btn = new Button( $this, $name );
  1186. $btn->setCaption( $caption );
  1187. if(!empty($extra))
  1188. {
  1189. $btn->setExtra( $extra );
  1190. }
  1191. // register the button
  1192. $this->_registerField( $name, $btn );
  1193. }
  1194. /********************************************************/
  1195. /************* LOOK & FEEL ******************************/
  1196. /********************************************************/
  1197. /**
  1198. * FormHandler::setMaxLength()
  1199. *
  1200. * Set the maximum length of a TextArea
  1201. *
  1202. * @param string $field: The field for which the maximum length will be set
  1203. * @param int $maxlength: The allowed max input length of the field
  1204. * @param boolean $displaymessage: determines if a message is displayed with characters left
  1205. * @return void
  1206. * @access public
  1207. * @author Teye Heimans
  1208. */
  1209. function setMaxLength( $field, $maxlength, $displaymessage = true )
  1210. {
  1211. static $setJSmaxlength = false;
  1212. // check if the field exists and is a textarea
  1213. if( !$this->fieldExists($field) || strtolower(get_class( $this->_fields[$field][1] )) != 'textarea')
  1214. {
  1215. trigger_error(
  1216. 'You have to declare the textarea first! '.
  1217. 'The field "'.$field.'" does not exists in the form!',
  1218. E_USER_WARNING
  1219. );
  1220. return;
  1221. }
  1222. // check if the maxlength is numeric
  1223. if( !is_numeric( $maxlength ) )
  1224. {
  1225. trigger_error( 'You have to give an numeric maxlength!', E_USER_WARNING );
  1226. return;
  1227. }
  1228. // add the javascript file if not done yet
  1229. if( !$setJSmaxlength )
  1230. {
  1231. $setJSmaxlength = true;
  1232. $this->_setJS( FH_FHTML_DIR.'js/maxlength.js', true );
  1233. }
  1234. // set the max length PHP check
  1235. $this->_fields[$field][1] -> setMaxLength( $maxlength, $displaymessage );
  1236. }
  1237. /**
  1238. * FormHandler::parse_error_style()
  1239. *
  1240. * Set the style class on a by %error_style% specified element
  1241. *
  1242. * @param string $html: html for the field
  1243. * @return string
  1244. * @access public
  1245. * @author Ronald Hulshof
  1246. * @since 07-01-2009
  1247. */
  1248. function parse_error_style( $mask )
  1249. {
  1250. // Get element containing %error_style%
  1251. $pattern = '/<[^<>]*%error_style%[^<>]*>/';
  1252. if( preg_match( $pattern, $mask, $result ) )
  1253. {
  1254. $element = $result[0];
  1255. // Check if class-attribute already exists in element
  1256. if( preg_match( '/class=\"[^"]*"/', $element ) )
  1257. {
  1258. // Class-attribute exists; add style
  1259. $pattern = array( '/class="/', '/\s*%error_style%\s*/' );
  1260. $replace = array('class="error ', '');
  1261. $new_elem = preg_replace( $pattern, $replace, $element );
  1262. $mask = str_replace($element, $new_elem, $mask);
  1263. }
  1264. else
  1265. {
  1266. // Class-attribute does not exist; create it
  1267. $new_elem = preg_replace('/%error_style%/', 'class="error"', $element);
  1268. $mask = str_replace($element, $new_elem, $mask);
  1269. }
  1270. }
  1271. return $mask;
  1272. }
  1273. /**
  1274. * Formhandler::parse_error_Fieldstyle
  1275. *
  1276. * Set the error class to the field itself
  1277. *
  1278. * @param string $field
  1279. * @return string
  1280. * @access public
  1281. * @author Johan Wiegel
  1282. * @since 25-08-2009
  1283. */
  1284. function parse_error_Fieldstyle( $field )
  1285. {
  1286. // Check if class-attribute already exists in element
  1287. if( preg_match( '/class=\"[^"]*"/', $field ) OR preg_match( '/class=\'[^"]*\'/', $field ) )
  1288. {
  1289. // Class-attribute exists; add style
  1290. $pattern = array( '/class="/', '/class=\'/' );
  1291. $replace = array( 'class="error ', 'class=\'error ' );
  1292. $field = preg_replace($pattern, $replace, $field);
  1293. }
  1294. elseif( preg_match( '/class=[^"]*/', $field ) )
  1295. {
  1296. // Class-attribute exists; add style
  1297. $pattern = array( '/class=/' );
  1298. $replace = array( 'class=error ' );
  1299. $field = preg_replace($pattern, $replace, $field);
  1300. }
  1301. else
  1302. {
  1303. // Class-attribute does not exist; create it
  1304. if( FH_XHTML_CLOSE != '' AND !preg_match( '/\<select /', $field ) AND !preg_match( '/\<textarea name/', $field ) )
  1305. {
  1306. $field = preg_replace('/\/>/', 'class="error" />', $field);
  1307. }
  1308. else
  1309. {
  1310. if( preg_match( '/\<textarea name/', $field ) )
  1311. {
  1312. $field = preg_replace('/<textarea /', '<textarea class="error" ', $field);
  1313. }
  1314. elseif( preg_match( '/\<select name/', $field ) )
  1315. {
  1316. $field = preg_replace('/<select /', '<select class="error" ', $field);
  1317. }
  1318. else
  1319. {
  1320. $field = preg_replace('/>/', 'class="error">', $field);
  1321. }
  1322. }
  1323. }
  1324. return $field;
  1325. }
  1326. /**
  1327. * FormHandler::setHelpText()
  1328. *
  1329. * Set the help text for a specific field
  1330. *
  1331. * @param string $field: The name of the field to set the help text for
  1332. * @param string $helpText: The help text for the field
  1333. * @param string $helpTitle: The help title
  1334. * @return void
  1335. * @access public
  1336. * @author Teye Heimans
  1337. */
  1338. function setHelpText( $field, $helpText, $helpTitle = null )
  1339. {
  1340. static $setJS = false;
  1341. if( !FH_USE_OVERLIB )
  1342. {
  1343. $setJS = true;
  1344. }
  1345. // make sure that the overlib js file is included
  1346. if(!$setJS)
  1347. {
  1348. $setJS = true;
  1349. $this->_setJS( FH_FHTML_DIR.'overlib/overlib.js', true );
  1350. $this->_setJS( FH_FHTML_DIR.'overlib/overlib_hideform.js', true );
  1351. }
  1352. // escape the values from dangerous characters
  1353. $helpTitle = is_null($helpTitle) ? "%title% - " . $this -> _text( 41 ) : htmlentities( $helpTitle, null, 'UTF-8' );
  1354. $helpTitle = preg_replace("/\r?\n/", "\\n", addslashes( $helpTitle ));
  1355. $helpText = preg_replace("/\r?\n/", "\\n", addslashes( $helpText ));
  1356. // set the help text
  1357. $this->_help[$field] = array(
  1358. htmlentities( $helpText, null, 'UTF-8' ),
  1359. $helpTitle
  1360. );
  1361. }
  1362. /**
  1363. * FormHandler::setHelpIcon()
  1364. *
  1365. * Set the help icon used for help messages
  1366. *
  1367. * @param string $helpIcon: The path to the help icon
  1368. * @return void
  1369. * @access public
  1370. * @author Teye Heimans
  1371. */
  1372. function setHelpIcon( $helpIcon )
  1373. {
  1374. $this->_helpIcon = $helpIcon;
  1375. }
  1376. /**
  1377. * FormHandler::addHTML()
  1378. *
  1379. * Add some HTML to the form
  1380. *
  1381. * @param string $html: The HTML we have to add to the form
  1382. * @return void
  1383. * @access public
  1384. * @author Teye Heimans
  1385. */
  1386. function addHTML( $html )
  1387. {
  1388. $this->_fields[] = array( '__HTML__', $html );
  1389. }
  1390. /**
  1391. * FormHandler::addLine()
  1392. *
  1393. * Add a new row to the form.
  1394. *
  1395. * @param string $data: Possible data to set into the row (line)
  1396. * @return void
  1397. * @access public
  1398. * @author Teye Heimans
  1399. */
  1400. function addLine( $text = null )
  1401. {
  1402. $this->_fields[] = array( '__LINE__', sprintf( FH_LINE_MASK, $text ) );
  1403. }
  1404. /**
  1405. * FormHandler::borderStart()
  1406. *
  1407. * Begin a new fieldset
  1408. *
  1409. * @param string $caption: The caption of the fieldset
  1410. * @param string $name: The name of the fieldset
  1411. * @param string $extra: Extra css or javascript which should be placed in the fieldset tag
  1412. * @return void
  1413. * @access public
  1414. * @author Teye Heimans
  1415. */
  1416. function borderStart( $caption = null, $name = null, $extra = '' )
  1417. {
  1418. static $i = 1;
  1419. if( empty( $name ) )
  1420. {
  1421. $name = 'fieldset'.$i++;
  1422. }
  1423. $this->_fields[] = array(
  1424. '__FIELDSET__',
  1425. array( $name, $caption, $extra )
  1426. );
  1427. }
  1428. /**
  1429. * FormHandler::borderStop()
  1430. *
  1431. * Stops a fieldset
  1432. *
  1433. * @return void
  1434. * @access public
  1435. * @author Teye Heimans
  1436. */
  1437. function borderStop()
  1438. {
  1439. $this->_fields[] = array('__FIELDSET-END__', true);
  1440. }
  1441. /**
  1442. * FormHandler::useTable()
  1443. *
  1444. * Do we have to set the <table> tag arround the fields ?
  1445. *
  1446. * @param bool $setTable
  1447. * @return void
  1448. * @access public
  1449. * @author Teye Heimans
  1450. */
  1451. function useTable( $setTable )
  1452. {
  1453. $this->_setTable = (bool) $setTable;
  1454. }
  1455. /**
  1456. * FormHandler::setMask()
  1457. *
  1458. * Sets a mask for the new row of fields
  1459. *
  1460. * @param string $mask: The mask we have to use
  1461. * @param int|bool $repeat: If we have to repeat the mask. When a integer is given, it will be countdown
  1462. * @return void
  1463. * @access public
  1464. * @author Teye Heimans
  1465. * @since 14-02-2008 Changed in order to also parse php as a template by Johan Wiegel
  1466. */
  1467. function setMask( $mask = null, $repeat = true )
  1468. {
  1469. // when no mask is given, set the default mask
  1470. if(is_null($mask))
  1471. {
  1472. $mask = FH_DEFAULT_ROW_MASK;
  1473. }
  1474. // a mask is given.. is it a file ?
  1475. else if( file_exists($mask) && is_file($mask) ) // double check of PHP bug in file_exists
  1476. {
  1477. // is the file readable ?
  1478. if( is_readable($mask) )
  1479. {
  1480. // get the contents of the file and parse php code in it
  1481. $mask = $this->get_include_contents($mask);
  1482. }
  1483. // the file is not readable!
  1484. else
  1485. {
  1486. trigger_error('Could not read template '.$mask, E_USER_WARNING );
  1487. }
  1488. }
  1489. // is there a third arument (the old way for disabling the table tag)
  1490. if( func_num_args() == 3 )
  1491. {
  1492. // display deprectated message
  1493. trigger_error(
  1494. 'This way of disabling the table tag is deprecated! '.
  1495. 'Use the method "useTable" instead!',
  1496. E_USER_NOTICE
  1497. );
  1498. // save the var
  1499. $this->_setTable = func_get_arg( 2 );
  1500. }
  1501. // save the mask
  1502. $this->_fields[] = array( '__MASK__', array( $mask, $repeat ) );
  1503. }
  1504. /**
  1505. * Get the file contents by including it, to enable parsing of php files
  1506. *
  1507. * @param string $sFilename : the file to get/parse
  1508. * @return void
  1509. * @access public
  1510. * @author sid benachenhou
  1511. * @since 14-02-2008 added by Johan Wiegel
  1512. */
  1513. function get_include_contents( $sFilename )
  1514. {
  1515. if( is_file( $sFilename ) )
  1516. {
  1517. ob_start();
  1518. include $sFilename;
  1519. $contents = ob_get_contents();
  1520. ob_end_clean();
  1521. return $contents;
  1522. }
  1523. return false;
  1524. }
  1525. /**
  1526. * FormHandler::setErrorMessage()
  1527. *
  1528. * Set a spicified error message to a field
  1529. *
  1530. * @param string $field: The field to set the message for
  1531. * @param string $message: The message to use when the fields value is invalid
  1532. * @return void
  1533. * @access public
  1534. * @author Teye Heimans
  1535. */
  1536. function setErrorMessage( $field, $message, $useStyle = true )
  1537. {
  1538. $this->_customMsg[$field] = array( $message, $useStyle );
  1539. }
  1540. /**
  1541. * FormHandler::setAutoComplete()
  1542. *
  1543. * Set a list of items for auto complete
  1544. *
  1545. * @param string $field: The field which should be auto complete
  1546. * @param array $options: The list of options for the uto complete
  1547. * @return void
  1548. * @access public
  1549. * @author Teye Heimans
  1550. */
  1551. function setAutoComplete( $field, $options )
  1552. {
  1553. static $setJS = false;
  1554. // check if the field exists and is a textfield
  1555. if( !$this->fieldExists($field) || strtolower(get_class( $this->_fields[$field][1] )) != 'textfield')
  1556. {
  1557. trigger_error(
  1558. 'You have to declare the textfield first! '.
  1559. 'The field "'.$field.'" does not exists in the form!',
  1560. E_USER_WARNING
  1561. );
  1562. return;
  1563. }
  1564. // check if the options are correct
  1565. if( !is_array( $options ) )
  1566. {
  1567. trigger_error( 'You have to give an array as options!', E_USER_WARNING );
  1568. return;
  1569. }
  1570. // add the javascript file if not done yet
  1571. if( !$setJS )
  1572. {
  1573. $setJS = true;
  1574. $this->_setJS( FH_FHTML_DIR.'js/autocomplete.js', true );
  1575. }
  1576. // create the javascript array
  1577. $js = $field.'_values = [';
  1578. foreach( $options as $option )
  1579. {
  1580. $js .= '"'.htmlentities($option) .'", ';
  1581. }
  1582. $this->_setJS( substr($js, 0, -2)."];\n" );
  1583. // add the javascript to the fields "extra" argument
  1584. $this->_fields[$field][1]->_sExtra .= " onkeypress='return FH_autocomplete(this, event, ".$field."_values);' ";
  1585. }
  1586. /**
  1587. * FormHandler::setAutoComplete()
  1588. *
  1589. * Set a list of items for auto complete after specified character
  1590. *
  1591. * @param string $field: The field which should be auto complete
  1592. * @param string $after: The character after wicht auto completion will start
  1593. * @param array $options: The list of options for the uto complete
  1594. * @return void
  1595. * @access public
  1596. * @author Rob Geerts
  1597. * @since 12-02-2008 ADDED BY Johan Wiegel
  1598. */
  1599. function setAutoCompleteAfter( $field, $after, $options )
  1600. {
  1601. static $setJS = false;
  1602. // check if the field exists and is a textfield
  1603. if( !$this->fieldExists($field) || strtolower(get_class( $this->_fields[$field][1] )) != 'textfield')
  1604. {
  1605. trigger_error(
  1606. 'You have to declare the textfield first! '.
  1607. 'The field "'.$field.'" does not exists in the form!',
  1608. E_USER_WARNING
  1609. );
  1610. return;
  1611. }
  1612. // check if the options are correct
  1613. if( !is_array( $options ) )
  1614. {
  1615. trigger_error( 'You have to give an array as options!', E_USER_WARNING );
  1616. return;
  1617. }
  1618. // add the javascript file if not done yet
  1619. if( !$setJS )
  1620. {
  1621. $setJS = true;
  1622. $this->_setJS( FH_FHTML_DIR.'js/autocomplete.js', true );
  1623. }
  1624. // create the javascript array
  1625. $js = $field.'_values = [';
  1626. foreach( $options as $option )
  1627. {
  1628. $js .= '"'.htmlentities($option) .'", ';
  1629. }
  1630. $this->_setJS( substr($js, 0, -2)."];\n" );
  1631. // add the javascript to the fields "extra" argument
  1632. $this->_fields[$field][1]->_sExtra .= " onkeypress='return autocompleteafter(this, event,\"".$after."\", ".$field."_values);' ";
  1633. }
  1634. /***/
  1635. /**
  1636. * FormHandler::newPage()
  1637. *
  1638. * Put the following fields on a new page
  1639. *
  1640. * @return void
  1641. * @access public
  1642. * @author Teye Heimans
  1643. */
  1644. function newPage()
  1645. {
  1646. $this->_fields[] = array( '__PAGE__', $this->_pageCounter++ );
  1647. }
  1648. /**
  1649. * FormHandler::setTabIndex()
  1650. *
  1651. * Set the tab index for the fields
  1652. *
  1653. * @param mixed $mTabs: array or comma seperated string with the field names.
  1654. * When an array is given the array index will set as tabindex
  1655. * @return void
  1656. * @access public
  1657. * @author Teye Heimans
  1658. */
  1659. function setTabIndex( $tabs )
  1660. {
  1661. // is the given value a string?
  1662. if( is_string( $tabs ) )
  1663. {
  1664. // split the commas
  1665. $tabs = explode(',', $tabs);
  1666. // add an empty value so that the index 0 isnt used
  1667. array_unshift($tabs, '');
  1668. }
  1669. // is the given value an array
  1670. else if( is_array( $tabs ))
  1671. {
  1672. // is set element 0, then move all elements
  1673. // (0 is not a valid tabindex, it starts with 1)
  1674. if( isset( $tabs[0]))
  1675. {
  1676. ksort( $tabs );
  1677. $new = array();
  1678. foreach( $tabs as $key => $value )
  1679. {
  1680. while( array_key_exists( $key, $new) || $key <= 0) $key++;
  1681. $new[$key] = $value;
  1682. }
  1683. $tabs = $new;
  1684. }
  1685. // the tabs array is good.. just use it
  1686. }
  1687. // array with tabs set ?
  1688. if( isset( $tabs ) )
  1689. {
  1690. // walk each tabindex
  1691. foreach($tabs as $key => $value )
  1692. {
  1693. // if there is a field..
  1694. if( !empty($value) )
  1695. {
  1696. $tabs[$key] = trim($value);
  1697. }
  1698. // no field is given, remove it's index
  1699. else
  1700. {
  1701. unset($tabs);
  1702. }
  1703. }
  1704. // save the tab indexes
  1705. $this->_tabindexes = $this->_tabindexes + $tabs ;
  1706. }
  1707. }
  1708. /**
  1709. * FormHandler::setLanguage()
  1710. *
  1711. * Set the language we should use for error messages etc.
  1712. * If no language is given, try to get the language defined by the visitors browser.
  1713. *
  1714. * @param string $language: The language we should use
  1715. * @return void
  1716. * @access public
  1717. * @author Teye Heimans
  1718. */
  1719. function setLanguage( $sLanguage = null )
  1720. {
  1721. if(!_global) global $_SERVER;
  1722. // if nog language is given, try to get it from the visitors browser if wanted
  1723. if( is_null($sLanguage))
  1724. {
  1725. // auto detect language ?
  1726. $bSet = false;
  1727. if( FH_AUTO_DETECT_LANGUAGE )
  1728. {
  1729. // get all accepted languages by the browser
  1730. $aLang = array();
  1731. if(isset($_SERVER['HTTP_ACCEPT_LANGUAGE']))
  1732. {
  1733. foreach(explode(',', $_SERVER['HTTP_ACCEPT_LANGUAGE']) as $sValue)
  1734. {
  1735. if(strpos($sValue, ';') !== false) {
  1736. list($sValue, ) = explode(';', $sValue);
  1737. }
  1738. if(strpos($sValue, '-') !== false) {
  1739. list($sValue, ) = explode('-', $sValue);
  1740. }
  1741. $aLang[] = $sValue;
  1742. }
  1743. }
  1744. // set the language which formhandler supports
  1745. while (list (, $l) = each ($aLang))
  1746. {
  1747. // check if the language file exists
  1748. if( file_exists( FH_INCLUDE_DIR.'language/'.strtolower($l).'.php') )
  1749. {
  1750. // set the language
  1751. $this->setLanguage( $l );
  1752. $bSet = true;
  1753. break;
  1754. }
  1755. }
  1756. }
  1757. // no language is set yet.. set the default language
  1758. if(!$bSet)
  1759. {
  1760. $this->setLanguage( FH_DEFAULT_LANGUAGE );
  1761. }
  1762. }
  1763. // when a language is given
  1764. else
  1765. {
  1766. // check if the language does not contain any slashes or dots
  1767. if( preg_match('/\.|\/|\\\/', $sLanguage ) )
  1768. {
  1769. return;
  1770. }
  1771. // make sure that the language is set in lower case
  1772. $sLanguage = strtolower( $sLanguage );
  1773. // check if the file exists
  1774. if( file_exists(FH_INCLUDE_DIR.'language/'.$sLanguage.'.php'))
  1775. {
  1776. // include the language file
  1777. include( FH_INCLUDE_DIR.'language/'.$sLanguage.'.php' );
  1778. // load the array from the text file
  1779. $this->_text = $fh_lang;
  1780. // save the language
  1781. $this->_lang = $sLanguage;
  1782. }
  1783. // language file does not exists
  1784. else
  1785. {
  1786. trigger_error(
  1787. 'Unknown language: '.$sLanguage.'. Could not find '.
  1788. 'file '.FH_INCLUDE_DIR.'language/'.$sLanguage.'.php!',
  1789. E_USER_ERROR
  1790. );
  1791. }
  1792. }
  1793. }
  1794. /**
  1795. * FormHandler::catchErrors()
  1796. *
  1797. * Get the errors occoured in the form
  1798. *
  1799. * @param boolean $display: If we still have to display the errors in the form (default this is disabled)
  1800. * @return array of errors or an empty array if none occoured
  1801. * @access public
  1802. * @author Teye Heimans
  1803. */
  1804. function catchErrors( $display = false )
  1805. {
  1806. // only return the errors when the form is posted
  1807. // and the form is not correct
  1808. if( $this->isPosted() && !$this -> isCorrect() )
  1809. {
  1810. $this->_displayErrors = $display;
  1811. // walk each field and get the error of the field
  1812. $errors = array();
  1813. foreach( $this->_fields as $field => $obj )
  1814. {
  1815. // check if it's a field (where we can get an error message from )
  1816. $obj = $this->_fields[$field];
  1817. if(is_object( $obj[1] ) && method_exists($obj[1], 'getError') && method_exists($obj[1], 'isValid'))
  1818. {
  1819. // check if it's valid
  1820. if( !$obj[1]->isValid() )
  1821. {
  1822. // save the error message if there is one
  1823. $err = $obj[1]->getError();
  1824. if( strlen($err) > 0)
  1825. {
  1826. // if there is an error, check if we should use a custom error message
  1827. if( array_key_exists($field, $this->_customMsg) )
  1828. {
  1829. // use the default error mask ?
  1830. if( $this->_customMsg[$field][1] )
  1831. {
  1832. $err = sprintf( FH_ERROR_MASK, $this->_customMsg[$field][1], $this->_customMsg[$field][0] );
  1833. }
  1834. // dont use the default error mask...
  1835. else
  1836. {
  1837. $err = $this->_customMsg[$field][0];
  1838. }
  1839. }
  1840. $errors[$field] = $err;
  1841. }
  1842. }
  1843. }
  1844. }
  1845. return $errors;
  1846. }
  1847. return array();
  1848. }
  1849. /**
  1850. * FormHandler::setFocus()
  1851. *
  1852. * Set the focus to a sepcific field
  1853. *
  1854. * @param string $field: The field which should get the focus
  1855. * @return boolean: true if the focus could be set, false if not
  1856. * @access public
  1857. * @author Teye Heimans
  1858. */
  1859. function setFocus( $field )
  1860. {
  1861. // if the field is false, no focus has to be set...
  1862. if( $field === false )
  1863. {
  1864. $this->_focus = false;
  1865. return true;
  1866. }
  1867. // check if the field exists
  1868. if(! $this->fieldExists( $field) )
  1869. {
  1870. trigger_error(
  1871. 'Could net set focus to unknown field "'.$field.'"',
  1872. E_USER_NOTICE
  1873. );
  1874. return;
  1875. }
  1876. // some fields have other names... change it.
  1877. switch ( strtolower( get_class($this->_fields[$field][1]) ) )
  1878. {
  1879. case 'jsdatefield':
  1880. case 'datefield':
  1881. $field = $field.'_day';
  1882. break;
  1883. case 'listfield':
  1884. $field = $field.'_ListOn';
  1885. break;
  1886. case 'timefield':
  1887. $field = $field.'_hour';
  1888. break;
  1889. // these fields cant have the focus
  1890. case 'editor':
  1891. case 'radiobutton':
  1892. case 'checkbox':
  1893. case 'hiddenfield':
  1894. // buttons cant have the focus
  1895. case 'submitbutton':
  1896. case 'resetbutton':
  1897. case 'imagebutton':
  1898. case 'button':
  1899. $field = null;
  1900. break;
  1901. }
  1902. $this->_focus = $field;
  1903. return !is_null( $field );
  1904. }
  1905. /**
  1906. * FormHandler::enableAjaxValidator
  1907. *
  1908. * @param boolean $mode: The new state of the AjaxValidator
  1909. * @param boolean $bScript: Should the library (jQuery) be included by FH
  1910. * @return void
  1911. *
  1912. * @since 03-12-2008
  1913. * @author Johan Wiegel
  1914. */
  1915. function enableAjaxValidator( $mode = true, $bScript = true)
  1916. {
  1917. $this->_ajaxValidator = (bool) $mode;
  1918. $this->_ajaxValidatorScript = (bool) $bScript;
  1919. }
  1920. /**
  1921. * FormHandler::enableViewMode()
  1922. *
  1923. * Set all fields in view mode
  1924. *
  1925. * @param boolean $mode: The new state of the Forms View Mode
  1926. * @return void
  1927. */
  1928. function enableViewMode( $mode = true)
  1929. {
  1930. $this->_viewMode = (bool) $mode;
  1931. }
  1932. /**
  1933. * FormHandler::isViewMode()
  1934. *
  1935. * Gets the ViewMode state
  1936. *
  1937. * @return boolean
  1938. * @access public
  1939. * @author Teye Heimans
  1940. */
  1941. function isViewMode()
  1942. {
  1943. return $this->_viewMode;
  1944. }
  1945. /**
  1946. * FormHandler::setFieldViewMode()
  1947. *
  1948. * Sets and indiviual f ields display mode
  1949. *
  1950. * @param string $field: The name of the field to set the display mode for
  1951. * @param boolean $mode: True = field is view only
  1952. * @return void
  1953. * @access public
  1954. */
  1955. function setFieldViewMode( $field, $mode = true )
  1956. {
  1957. // does the field exists?
  1958. if( $this -> fieldExists( $field ) )
  1959. {
  1960. // set the new modes
  1961. $this -> _fields[$field][1] -> setViewMode( $mode );
  1962. }
  1963. // the field does not exists! error!
  1964. else
  1965. {
  1966. trigger_error(
  1967. 'Error, could not find field "'. $field .'"! Please define the field first!',
  1968. E_USER_NOTICE
  1969. );
  1970. }
  1971. }
  1972. /**
  1973. * FormHandler::isFieldViewMode()
  1974. *
  1975. * Check if the field should be displayed as view only
  1976. *
  1977. * @param string $field: The field to check
  1978. * @return boolean
  1979. * @access public
  1980. */
  1981. function isFieldViewMode( $field )
  1982. {
  1983. // does the field exists?
  1984. if( $this -> fieldExists( $field ) && is_object( $this -> _fields[$field][1] ) && method_exists( $this -> _fields[$field][1], 'getViewMode' ) )
  1985. {
  1986. // get the mode
  1987. return $this -> _fields[$field][1] -> getViewMode();
  1988. }
  1989. // the field does not exists! error!
  1990. else
  1991. {
  1992. trigger_error(
  1993. 'Error, could not find field "'. $field .'"! Please define the field first!',
  1994. E_USER_NOTICE
  1995. );
  1996. }
  1997. }
  1998. /**
  1999. * FormHandler::setTableSettings()
  2000. *
  2001. * @param int width
  2002. * @return void
  2003. * @author Teye Heimans
  2004. */
  2005. function setTableSettings(
  2006. $width = null,
  2007. $cellspacing = null,
  2008. $cellpadding = null,
  2009. $border = null,
  2010. $extra = '')
  2011. {
  2012. // set the default
  2013. if( is_null($width )) $width = FH_DEFAULT_TABLE_WIDTH;
  2014. if( !is_numeric($cellspacing)) $cellspacing = FH_DEFAULT_TABLE_CELLSPACING;
  2015. if( !is_numeric($cellpadding)) $cellpadding = FH_DEFAULT_TABLE_CELLPADDING;
  2016. if( !is_numeric($border)) $border = FH_DEFAULT_TABLE_BORDER;
  2017. // save the table settings
  2018. $this->_tableSettings = array(
  2019. 'width' => $width,
  2020. 'cellspacing' => $cellspacing,
  2021. 'cellpadding' => $cellpadding,
  2022. 'border' => $border,
  2023. 'extra' => $extra
  2024. );
  2025. }
  2026. /********************************************************/
  2027. /************* DATA HANDLING ****************************/
  2028. /********************************************************/
  2029. /**
  2030. * FormHandler::getValue()
  2031. *
  2032. * Alias for the function value
  2033. *
  2034. * @param string $field: The field which value we have to return
  2035. * @return string
  2036. * @access public
  2037. * @author Teye Heimans
  2038. */
  2039. function getValue( $field )
  2040. {
  2041. return $this->value( $field );
  2042. }
  2043. /**
  2044. * FormHandler::getAsArray()
  2045. *
  2046. * Return the value of a datefield as an array: array(y,m,d)
  2047. *
  2048. * @param string $datefield: return the value of the datefield as an array
  2049. * @return array
  2050. * @access public
  2051. * @author Teye Heimans
  2052. */
  2053. function getAsArray( $datefield )
  2054. {
  2055. // check if the datefield exists
  2056. if( in_array($datefield, $this->_date ) )
  2057. {
  2058. return $this->_fields[$datefield][1]->getAsArray();
  2059. }
  2060. // the datefield does not exists
  2061. else
  2062. {
  2063. trigger_error(
  2064. 'The datefield "'.$datefield.'" does not exists!',
  2065. E_USER_NOTICE
  2066. );
  2067. return false;
  2068. }
  2069. }
  2070. /**
  2071. * FormHandler::value()
  2072. *
  2073. * Get the value of the requested field
  2074. *
  2075. * @param string $field: The field which value we have to return
  2076. * @return string
  2077. * @access public
  2078. * @author Teye Heimans
  2079. */
  2080. function value( $field )
  2081. {
  2082. if(!_global) global $_POST;
  2083. // is it a field?
  2084. if( isset( $this->_fields[$field] ) && is_object($this->_fields[$field][1]) && method_exists($this->_fields[$field][1], 'getvalue') )
  2085. {
  2086. return $this->_fields[$field][1]->getValue();
  2087. }
  2088. // is it an user added value ?
  2089. else if( isset($this->_add[$field]) )
  2090. {
  2091. return $this->_add[$field];
  2092. }
  2093. // _chache contains the values of the fields after flush() is called
  2094. // (because then all objects are removed from the memory)
  2095. else if( isset( $this->_cache[$field]) )
  2096. {
  2097. return $this->_cache[$field];
  2098. }
  2099. // is it a set value of a field which does not exists yet ?
  2100. else if( isset( $this->_buffer[$field]) )
  2101. {
  2102. return $this->_buffer[$field][1];
  2103. }
  2104. // is it a value from the $_POST array ?
  2105. else if( isset( $_POST[$field] ) )
  2106. {
  2107. // give a notice
  2108. //trigger_error(
  2109. // 'Notice: the value retrieved from the field "'.$field.'" could '.
  2110. // 'only be fetched from the $_POST array. The field is not found in the form...',
  2111. // E_USER_NOTICE
  2112. //);
  2113. return $_POST[$field];
  2114. }
  2115. trigger_error(
  2116. 'Try to get the value of an unknown field "'.$field.'"!',
  2117. E_USER_WARNING
  2118. );
  2119. return null;
  2120. }
  2121. /**
  2122. * FormHandler::setValue()
  2123. *
  2124. * Set the value of the spicified field
  2125. *
  2126. * @param string $field: The field which value we have to set
  2127. * @param string $value: The value we have to set
  2128. * @param boolean $overwriteCurrentValue: Do we have to overwrite the current value of the field (posted value)
  2129. * @return void
  2130. * @access public
  2131. * @author Teye Heimans
  2132. */
  2133. function setValue( $sField, $sValue, $bOverwriteCurrentValue = false )
  2134. {
  2135. // check if the field exists
  2136. if( $this->fieldExists( $sField ) )
  2137. {
  2138. // if the field does not exists in the database
  2139. if( $bOverwriteCurrentValue || !$this->isPosted() ||
  2140. // only set the value if the page is not 'done' yet, otherwise
  2141. // we will overwrite it
  2142. $this->_curPage < $this->_pageCounter )
  2143. {
  2144. $this->_fields[$sField][1]->setValue( $sValue );
  2145. }
  2146. }
  2147. // the field does not exists. Save the value in the buffer.
  2148. // the field will check this buffer and use it value when it's created
  2149. else
  2150. {
  2151. // save the data untill the field exists
  2152. $this->_buffer[$sField] = array( $bOverwriteCurrentValue, $sValue );
  2153. }
  2154. }
  2155. /**
  2156. * FormHandler::addValue()
  2157. *
  2158. * Add a value to the data array which is going
  2159. * to be saved/used in the oncorrect & onsaved functions
  2160. *
  2161. * @param string $field: The field which value we have to set
  2162. * @param string $value: The value we have to set
  2163. * @param boolean $sqlFunction: Is the value an SQL function ?
  2164. * @return void
  2165. * @access public
  2166. * @author Teye Heimans
  2167. */
  2168. function addValue($field, $value, $sqlFunction = false)
  2169. {
  2170. // save the added value
  2171. $this->_add[$field] = $value;
  2172. // add to the sql list if the value is a sql function
  2173. if( $sqlFunction )
  2174. {
  2175. $this->_sql[] = $field;
  2176. }
  2177. }
  2178. /**
  2179. * FormHandler::onCorrect()
  2180. *
  2181. * Set the function which has to be called when the form is correct
  2182. *
  2183. * @param string $callback: The name of the function
  2184. * @return void
  2185. * @access public
  2186. * @author Teye Heimans
  2187. */
  2188. function onCorrect( $callback )
  2189. {
  2190. // is the given value a string ?
  2191. if(!is_array($callback))
  2192. {
  2193. // does the function exists ?
  2194. if( function_exists($callback) )
  2195. {
  2196. $this->_onCorrect = $callback;
  2197. }
  2198. // the given callback function does not exists
  2199. else
  2200. {
  2201. trigger_error(
  2202. 'Error, the onCorrect function "'.$callback.'" does not exists!',
  2203. E_USER_ERROR
  2204. );
  2205. }
  2206. }
  2207. // we have to call a method
  2208. else
  2209. {
  2210. // check if the method exists in the given object
  2211. if( method_exists($callback[0], $callback[1]) )
  2212. {
  2213. $this->_onCorrect = $callback;
  2214. }
  2215. // the method does not exists
  2216. else
  2217. {
  2218. trigger_error(
  2219. 'Error, the onCorrect method "'.$callback[1].'" does not exists in the given object'.
  2220. (is_object($callback[0]) ? ' "'.get_class($callback[0]).'"!' : '!'),
  2221. E_USER_ERROR
  2222. );
  2223. }
  2224. }
  2225. }
  2226. /**
  2227. * FormHandler::setError()
  2228. *
  2229. * Set a specified error to a field
  2230. *
  2231. * @param string $field: The field to set the error for
  2232. * @param string $error: The error message to use
  2233. * @return boolean: Returns the success of the operation
  2234. * @access public
  2235. * @author Filippo Toso - filippotoso@libero.it
  2236. */
  2237. function setError( $field, $error )
  2238. {
  2239. if ( isset( $this->_fields[$field][1] ) )
  2240. {
  2241. $this -> _fields[$field][1] -> setError( $error );
  2242. $this -> _fields[$field][1] -> _isValid = false;
  2243. return true;
  2244. }
  2245. return false;
  2246. }
  2247. /********************************************************/
  2248. /************* GENERAL **********************************/
  2249. /********************************************************/
  2250. /**
  2251. * FormHandler::getFileInfo()
  2252. *
  2253. * Get the file info af an uploaded file
  2254. *
  2255. * @param string $uploadfield: the name of the uploadfield
  2256. * @return array file info
  2257. * @access public
  2258. * @author Teye Heimans
  2259. */
  2260. function getFileInfo( $uploadfield )
  2261. {
  2262. // does the field exists ?
  2263. if( $this -> fieldExists( $uploadfield ) )
  2264. {
  2265. // is it an uploadfield ?
  2266. $obj = &$this -> _fields[$uploadfield][1];
  2267. if( strtolower( get_class( $obj ) ) == 'uploadfield' )
  2268. {
  2269. // check if there is an file uploaded
  2270. if( $obj -> isUploaded() )
  2271. {
  2272. // return the file info
  2273. return $obj -> getFileInfo();
  2274. }
  2275. }
  2276. // the field is not an uploadfield
  2277. else
  2278. {
  2279. trigger_error(
  2280. 'Error, the field "'.$uploadfield.'" is not an uploadfield!',
  2281. E_USER_NOTICE
  2282. );
  2283. }
  2284. }
  2285. // the field does not exists
  2286. else
  2287. {
  2288. trigger_error(
  2289. 'Error, the uploadfield "'.$uploadfield.'" does not exists!',
  2290. E_USER_NOTICE
  2291. );
  2292. }
  2293. // if we come here, something went wrong. Return empty array
  2294. return array();
  2295. }
  2296. /**
  2297. * FormHandler::isUploaded()
  2298. *
  2299. * Check if the given uploadfield has a file which is uploaded
  2300. *
  2301. * @param string $uploadfield: the name of the uploadfield
  2302. * @return boolean
  2303. * @access public
  2304. * @author Teye Heimans
  2305. */
  2306. function isUploaded( $uploadfield )
  2307. {
  2308. // does the field exists ?
  2309. if( $this -> fieldExists( $uploadfield ) )
  2310. {
  2311. // is it an uploadfield ?
  2312. $obj = &$this -> _fields[$uploadfield][1];
  2313. if( strtolower( get_class( $obj ) ) == 'uploadfield' )
  2314. {
  2315. // check if there is an file uploaded
  2316. return $obj -> isUploaded();
  2317. }
  2318. // the field is not an uploadfield
  2319. else
  2320. {
  2321. trigger_error(
  2322. 'Error, the field "'.$uploadfield.'" is not an uploadfield!',
  2323. E_USER_NOTICE
  2324. );
  2325. }
  2326. }
  2327. // the field does not exists
  2328. else
  2329. {
  2330. trigger_error(
  2331. 'Error, the uploadfield "'.$uploadfield.'" does not exists!',
  2332. E_USER_NOTICE
  2333. );
  2334. }
  2335. // if we come here, something went wrong. Return false
  2336. return false;
  2337. }
  2338. /**
  2339. * FormHandler::getLastSubmittedPage()
  2340. *
  2341. * Returns the page number of the last submitted page of the form
  2342. *
  2343. * @return int
  2344. * @access public
  2345. * @author Remco van Arkelen & Johan Wiegel
  2346. * @since 21-08-2009
  2347. */
  2348. function getLastSubmittedPage()
  2349. {
  2350. return $this->getPage();
  2351. }
  2352. /**
  2353. * FormHandler::getPage()
  2354. *
  2355. * Returns the page number of the last submitted page the form (when getPage is called)
  2356. *
  2357. * @return int
  2358. * @access public
  2359. * @author Teye Heimans
  2360. */
  2361. function getPage()
  2362. {
  2363. return $this->_pageCounter;
  2364. }
  2365. /**
  2366. * FormHandler::getCurrentPage()
  2367. *
  2368. * Returns the current page number of the current form (used when newPage is used!)
  2369. *
  2370. * @return int
  2371. * @access public
  2372. * @author Teye Heimans
  2373. */
  2374. function getCurrentPage()
  2375. {
  2376. return $this->_curPage;
  2377. }
  2378. /**
  2379. * FormHandler::linkSelectFields()
  2380. *
  2381. * Link de given selectfields (load the values dynamicly)
  2382. *
  2383. * @param string $filename: the name of the file which will load the new values for the select field
  2384. * @param string $fields: the name of the first dynamic select field.
  2385. * @param ...: More fields which are linked to eachother
  2386. * @return null
  2387. * @access public
  2388. * @author Teye Heimans
  2389. */
  2390. function linkSelectFields( $filename, $fields )
  2391. {
  2392. static $setJS = false;
  2393. $page = $this -> isPosted() && !$this -> isCorrect() ? $this->_curPage - 1 : $this -> _curPage ;
  2394. // when we are not at the correct page, do nothing
  2395. // added && $this - > isCorrect() in order to keep validation 07-10-2009 JW
  2396. if( $page != ($this -> _pageCounter-1 < 1 ? 1 : $this -> _pageCounter-1) && $this -> isCorrect() )
  2397. {
  2398. return ;
  2399. }
  2400. // add the javascript file if not done yet
  2401. if( !$setJS )
  2402. {
  2403. $setJS = true;
  2404. $this->_setJS(FH_FHTML_DIR.'js/linked_select.js', true);
  2405. }
  2406. // walk all arguments
  2407. $js = '';
  2408. $values = array();
  2409. for( $i = 1; $i < (func_num_args()-1); $i++)
  2410. {
  2411. // get the "parent" and "child" field
  2412. $fld1 = func_get_arg($i);
  2413. $fld2 = func_get_arg($i+1);
  2414. $extra = '';
  2415. // extra arguments given ?
  2416. if( is_array( $fld1 ) )
  2417. {
  2418. $arr = $fld1;
  2419. $fld1 = array_shift( $arr );
  2420. // walk all "extra" arguments
  2421. while( $item = array_shift( $arr ) )
  2422. {
  2423. // is this argument a field? Then load the "db" value
  2424. if( $this->fieldExists( $item ) )
  2425. {
  2426. $extra .= '&'.$item.'="+document.forms["'.$this->getFormName().'"].elements["'.$item.'"].value+"';
  2427. }
  2428. // just load the extra argument, it's a js string
  2429. else
  2430. {
  2431. $extra .= $item;
  2432. }
  2433. }
  2434. }
  2435. if( is_array( $fld2 ) ) list( $fld2, ) = $fld2;
  2436. // make sure that the fields exists
  2437. if( !$this->fieldExists( $fld1) )
  2438. {
  2439. trigger_error(
  2440. 'Error, the field "'.$fld1.'" could not be found in the form!',
  2441. E_USER_NOTICE
  2442. );
  2443. return false;
  2444. }
  2445. // make sure that the fields exists
  2446. if( !$this->fieldExists( $fld2) )
  2447. {
  2448. trigger_error(
  2449. 'Error, the field "'.$fld2.'" could not be found in the form!',
  2450. E_USER_NOTICE
  2451. );
  2452. return false;
  2453. }
  2454. // values opslaan
  2455. $values[] = $this->getValue( $fld2 );
  2456. // change the name of a listfield to {$fieldname}_ListOff[]
  2457. if( strtolower(get_class($this->_fields[$fld1][1])) == 'listfield')
  2458. {
  2459. $fld1 .= '_ListOff';
  2460. }
  2461. if( strtolower(get_class($this->_fields[$fld2][1])) == 'listfield')
  2462. {
  2463. $fld2 .= '_ListOff';
  2464. }
  2465. // if this is the first field
  2466. if( $i == 1)
  2467. {
  2468. $jsAfter =
  2469. "// load the first item of the dynamic select fields\n".
  2470. "attach".$fld1."(";
  2471. }
  2472. // create the javascript for dynamic loading..
  2473. $func = $i < ( func_num_args() - 2 ) ? 'attach'.$fld2 : 'null';
  2474. $param = isset($this->edit) && $this->edit ? '&value=' . $values[count($values)-1] : '';
  2475. $param .= $extra;
  2476. $js.=
  2477. 'function attach'.$fld1.'( aArgs, sValue ) {'."\n".
  2478. ' attachelement("'.$fld1.'", "change", load'.$fld2.');'."\n".
  2479. ' load'.$fld2.'( aArgs, sValue );'."\n".
  2480. '}'."\n\n".
  2481. 'function load'.$fld2.'( aArgs, sValue ) {'."\n".
  2482. ' value = GetElement("'.$fld1.'").value;'."\n".
  2483. //' value = document.forms["'.$this->getFormName().'"].elements["'.$fld1.'"].value;'."\n".
  2484. //' //GetElement("'.$fld2.'").innerHTML = "loading";'."\n".
  2485. ' loadexternal('."\n".
  2486. ' "'.$filename.'",'."\n".
  2487. ' "linkselect=true&filter="+value+"&field='.$fld2.$param.'",'."\n".
  2488. ' "'.$fld2.'",'."\n". //display
  2489. ' '.$func.",\n".
  2490. ' aArgs,'."\n".
  2491. ' sValue'."\n".
  2492. ' )'."\n".
  2493. '}'."\n";
  2494. }
  2495. // add the value of the last field to the values array
  2496. //$values[] = $this->getValue( $fld2 );
  2497. // finalize the js to load the values
  2498. if( !empty( $jsAfter ) )
  2499. {
  2500. $jsAfter .= " new Array( ";
  2501. foreach( $values as $value )
  2502. {
  2503. if( is_array( $value ) )
  2504. {
  2505. $jsAfter .= " new Array( ";
  2506. foreach( $value as $item )
  2507. {
  2508. $jsAfter .= "'".addslashes($item)."', ";
  2509. }
  2510. $jsAfter = substr( $jsAfter, 0, -2) . "), ";
  2511. }
  2512. else
  2513. {
  2514. $jsAfter .= "'".addslashes($value)."', ";
  2515. }
  2516. }
  2517. $jsAfter = substr( $jsAfter, 0, -2) ."));\n\n";
  2518. $this -> _setJS( $jsAfter, 0, 0);
  2519. }
  2520. // set the js..
  2521. $this->_setJS( $js, false );
  2522. }
  2523. /**
  2524. * FormHandler::setDynamicOptions()
  2525. *
  2526. * Static: Make a javascript array of the given php array. This is
  2527. * used for dynamic select fields
  2528. *
  2529. * @param array $options: the new options for the select field
  2530. * @return null
  2531. * @access public
  2532. * @author Teye Heimans
  2533. */
  2534. function setDynamicOptions( $options, $useArrayKeyAsValue = true )
  2535. {
  2536. $output = 'var options = Array('." \n";
  2537. // generate a javascript array from the given array
  2538. foreach( $options as $key => $value )
  2539. {
  2540. $key = $useArrayKeyAsValue ? $key : $value;
  2541. $output .= ' Array("'.addslashes($key).'", "'.addslashes($value).'"),'."\n";
  2542. }
  2543. $output = substr( $output, 0, -2 );
  2544. $output .= "\n);\n";
  2545. echo $output;
  2546. }
  2547. /**
  2548. * FormHandler::getTitle()
  2549. *
  2550. * Return the title of the given field name
  2551. *
  2552. * @param string $sField: The fieldname where to retrieve the title from
  2553. * @return string
  2554. * @access public
  2555. * @author Teye Heimans
  2556. */
  2557. function getTitle( $sField )
  2558. {
  2559. // check if the field exists
  2560. if( isset($this->_fields[$sField]) && is_object( $this->_fields[$sField][1] ))
  2561. {
  2562. // check if the field is a child of the "field" class
  2563. if( is_subclass_of( $this->_fields[$sField][1], 'field') )
  2564. {
  2565. // return the title
  2566. return $this->_fields[$sField][0];
  2567. }
  2568. else
  2569. {
  2570. // print an error message
  2571. $sClass = strtolower( get_class( $this->_fields[$sField][1] ) );
  2572. trigger_error(
  2573. 'Error, cannot retrieve title of this kind of field: '.$sClass,
  2574. E_USER_WARNING
  2575. );
  2576. }
  2577. }
  2578. // the given field does not exists!
  2579. else
  2580. {
  2581. trigger_error(
  2582. 'Could not find field "'.$sField.'"',
  2583. E_USER_WARNING
  2584. );
  2585. }
  2586. return null;
  2587. }
  2588. /**
  2589. * FormHandler::getLanguage()
  2590. *
  2591. * Return the language used for the form
  2592. *
  2593. * @return string: the language
  2594. * @access public
  2595. * @author Teye Heimans
  2596. */
  2597. function getLanguage()
  2598. {
  2599. return $this->_lang;
  2600. }
  2601. /**
  2602. * FormHandler::fieldExists()
  2603. *
  2604. * Check if the field exists in the form
  2605. *
  2606. * @param string $sField: The field to check if it exists in the form or not
  2607. * @return boolean
  2608. * @access public
  2609. * @author Teye Heimans
  2610. */
  2611. function fieldExists( $sField )
  2612. {
  2613. return array_key_exists( $sField, $this->_fields );
  2614. }
  2615. /**
  2616. * FormHandler::getFormName()
  2617. *
  2618. * Return the name of the form
  2619. *
  2620. * @return string: the name of the form
  2621. * @access public
  2622. * @author Teye Heimans
  2623. */
  2624. function getFormName()
  2625. {
  2626. return $this->_name;
  2627. }
  2628. /**
  2629. * FormHandler::getJavascriptCode()
  2630. *
  2631. * Return the needed javascript code for this form
  2632. *
  2633. * @param $header: Return the javascript code for in the header (otherwise the javascript code which hase to be beneath the form will be returned)
  2634. * @return string: the needed javascript code for this form
  2635. * @access public
  2636. * @author Teye Heimans
  2637. *
  2638. * @since 17-08-2009 removed static before $return in order to handle multiple forms on a page. JW
  2639. */
  2640. function getJavascriptCode( $header = true )
  2641. {
  2642. $return = array( 0 => false, 1 => false );;
  2643. $s = $header ? 0 : 1;
  2644. // if the javascript is not retrieved yet..
  2645. if( !$return[$s] )
  2646. {
  2647. // generate the js "files" script
  2648. $result = '';
  2649. if( isset($this->_js[$s]['file']) && is_array($this->_js[$s]['file']) )
  2650. {
  2651. foreach( $this->_js[$s]['file'] as $line )
  2652. {
  2653. $result .= '<script type="text/javascript" src="'.$line.'"></script>'."\n";
  2654. }
  2655. }
  2656. // generate the other js script
  2657. if( isset($this->_js[$s]['code']) && is_array($this->_js[$s]['code']) )
  2658. {
  2659. $result .= '<script type="text/javascript">'."\n";
  2660. foreach( $this->_js[$s]['code'] as $code )
  2661. {
  2662. $result .= $code;
  2663. }
  2664. $result .= "</script>\n";
  2665. }
  2666. $return[$s] = true;
  2667. return $result;
  2668. }
  2669. return '';
  2670. }
  2671. /**
  2672. * FormHandler::getAsMailBody()
  2673. *
  2674. * Returns the values of the form as mail body
  2675. *
  2676. * @param string $mask: The mask which should be used for creating the mail body
  2677. * @return string
  2678. * @access public
  2679. * @author Teye Heimans
  2680. * @since 25/11/2005
  2681. */
  2682. function getAsMailBody( $mask = null )
  2683. {
  2684. // TODO
  2685. // replacement of %field% and of %{fieldname}%
  2686. $loader = new MaskLoader();
  2687. $loader -> setMask( $mask );
  2688. // create the search and replace strings
  2689. $search = array();
  2690. $replace = array();
  2691. // walk all elements in this form
  2692. reset( $this->_fields );
  2693. $mail = '';
  2694. while( list( $name, $fld ) = each( $this->_fields) )
  2695. {
  2696. // only use it in the mail if it has a view value (the fields)
  2697. if( is_object( $fld[1] ) && method_exists($fld[1], 'getViewValue') && $name != $this->_name.'_submit')
  2698. {
  2699. // search and replace the %field% %value% items
  2700. $loader -> setSearch( array( '/%field%/', '/%value%/') );
  2701. $mail .= $loader -> fill(
  2702. array(
  2703. $name,
  2704. $fld[1]->getViewValue()
  2705. )
  2706. );
  2707. // add the %{fieldname}% seach item to the search string for later...
  2708. $search[] = '/%'.$name.'%/';
  2709. $replace[] = $fld[1]->getViewValue();
  2710. }
  2711. }
  2712. // add the user added values to the search and replace arrays
  2713. foreach ( $this->_add as $name => $value )
  2714. {
  2715. $search[] = '/%'.$name.'%/';
  2716. $replace[] = $value;
  2717. }
  2718. $loader -> setSearch( $search );
  2719. // check if there is still something to fill
  2720. if( !$loader -> isFull() )
  2721. {
  2722. $mail .= $loader -> fill( $replace, -1 );
  2723. }
  2724. // get possible half filled mask
  2725. $mail .= $loader -> fill();
  2726. return $mail;
  2727. }
  2728. /**
  2729. * FormHandler::resizeImage()
  2730. *
  2731. * Resize the image uploaded in the given field
  2732. *
  2733. * @param string $field: The field where the image is uploaded
  2734. * @param string $saveAs: How the image has to be saved (if not given, the original wil be overwritten)
  2735. * @param int $maxWidth: The maximum width of the resized image
  2736. * @param int $maxHeight: the maximum height of the resized image
  2737. * @param int $quality: the quality of the resized image
  2738. * @param bool $constrainProportions: Keep the proportions when the image is resized?
  2739. * @return void
  2740. * @access public
  2741. * @author Teye Heimans
  2742. */
  2743. function resizeImage( $field, $saveAs = null, $maxWidth = null, $maxHeight = null, $quality = null, $constrainProportions = true )
  2744. {
  2745. require_once( FH_INCLUDE_DIR.'includes/class.ImageConverter.php' );
  2746. // is gd enabled ?
  2747. if( ! ImageConverter::GDVersion() )
  2748. {
  2749. trigger_error(
  2750. 'Error! To use the function resizeImage you have to enable GD Libary!',
  2751. E_USER_WARNING
  2752. );
  2753. return;
  2754. }
  2755. // set some default vars if none given
  2756. if(is_null($maxWidth)) $maxWidth = FH_DEFAULT_RESIZE_WIDTH;
  2757. if(is_null($maxHeight)) $maxHeight = $maxWidth;
  2758. // save the settings
  2759. $this->_convert[$field]['resize'][] = array( $saveAs, $maxWidth, $maxHeight, $quality, $constrainProportions );
  2760. }
  2761. /**
  2762. * FormHandler::mergeImage()
  2763. *
  2764. * Merge a image uploaded in the given field with another image
  2765. *
  2766. * @param string $field: The field where the image is uploaded
  2767. * @param string $merge: The image which we should merge
  2768. * @param int $align: The align of the merge image (eg: left, center, right)
  2769. * @param int $valign: The vertical align of the merge image( eg: top, middle, bottom)
  2770. * @return void
  2771. * @access public
  2772. * @author Teye Heimans
  2773. */
  2774. function mergeImage( $field, $merge, $align = 'center', $valign = 'bottom', $transparantColor = null )
  2775. {
  2776. require_once(FH_INCLUDE_DIR.'includes/class.ImageConverter.php');
  2777. // is gd enabled ?
  2778. if( ! ImageConverter::GDVersion() )
  2779. {
  2780. trigger_error(
  2781. 'Error! To use the function mergeImage you have to enable GD Libary!',
  2782. E_USER_WARNING
  2783. );
  2784. return;
  2785. }
  2786. // save the settings
  2787. $this->_convert[$field]['merge'][] = array( $merge, $align, $valign, $transparantColor );
  2788. }
  2789. /**
  2790. * FormHandler::checkPassword()
  2791. *
  2792. * Preform a password check on 2 password fields:
  2793. * - both values are the same
  2794. * - the values are longer then a minimum length (configured in the config file)
  2795. * - on an add-form, the fields are required
  2796. * - on an edit-form, the fields can be left empty, and the old password will stay (no changes will take place)
  2797. *
  2798. * @param string $field1: The first password field we should check
  2799. * @param string $field2: The second password field we should check
  2800. * @param boolean $setEditMsg: Should a message beeing displayed in an edit form that when leaving the fields blank the current passwords will be kept?
  2801. * @return void
  2802. * @access public
  2803. * @author Teye Heimans
  2804. */
  2805. function checkPassword($field1, $field2, $setEditMsg = true)
  2806. {
  2807. // check if the fields exists and that they are both passfields
  2808. if( !$this->fieldExists( $field1 ) || !$this->fieldExists( $field2) ||
  2809. strtolower( get_class( $this->_fields[$field1][1] ) ) != 'passfield' ||
  2810. strtolower( get_class( $this->_fields[$field2][1] ) ) != 'passfield')
  2811. {
  2812. trigger_error('Error: unknown field used in checkPassword!');
  2813. return;
  2814. }
  2815. // add some text to notify the user that he only has to enter his
  2816. // password when he wants to change it
  2817. if( isset($this->edit) && $this->edit && $setEditMsg )
  2818. {
  2819. $this->_fields[$field1][1]->setPre( $this->_text( 25 ) );
  2820. }
  2821. // is the form posted and this page is posted in case of mulitple page form.
  2822. if( $this->isPosted() && ($this->getPage() == $this->getCurrentPage()) )
  2823. {
  2824. // let passfield 1 check if it matches passfield 2
  2825. $this->_fields[$field1][1]->checkPassword( $this->_fields[$field2][1] );
  2826. }
  2827. }
  2828. /**
  2829. * FormHandler::isPosted()
  2830. *
  2831. * If the form is posted
  2832. *
  2833. * @return boolean: if the form is posted or not
  2834. * @access public
  2835. * @author Teye Heimans
  2836. */
  2837. function isPosted()
  2838. {
  2839. return $this->_posted;
  2840. }
  2841. /**
  2842. * FormHandler::isCorrect()
  2843. *
  2844. * Return if the form is filled correctly (for the fields which are set!)
  2845. *
  2846. * @return boolean: the form values valid or not
  2847. * @access public
  2848. * @author Teye Heimans
  2849. */
  2850. function isCorrect()
  2851. {
  2852. if( !_global) global $_POST;
  2853. $result = true;
  2854. foreach( $this->_fields as $id => $data )
  2855. {
  2856. // check if the fields are valid
  2857. if( is_object( $this->_fields[$id][1] ) && method_exists( $this->_fields[$id][1], 'isvalid') && $this->_fields[$id][1]->isValid() !== true)
  2858. {
  2859. // the field is not valid. If the focus is not set yet, set the focus to this field
  2860. if( is_null($this->_focus) )
  2861. {
  2862. $this->setFocus( $id );
  2863. }
  2864. $result = false;
  2865. }
  2866. // if multiple pages are used, only make sure that
  2867. // all pages untill the current page are correct
  2868. else if( $data[0] == '__PAGE__' && $this->_curPage == $data[1] )
  2869. {
  2870. break;
  2871. }
  2872. }
  2873. return $result;
  2874. }
  2875. /**
  2876. * FormHandler::flush()
  2877. *
  2878. * Prints or returns the form
  2879. *
  2880. * @return string: the form or null when the form should be printed
  2881. * @access public
  2882. * @author Teye Heimans
  2883. */
  2884. function flush( $return = false )
  2885. {
  2886. if( $this->_ajaxValidator === true )
  2887. {
  2888. require_once( FH_INCLUDE_DIR . 'includes/class.AjaxValidator.php' );
  2889. $oAjaxValidator = new AjaxValidator( $this->_ajaxValidatorScript );
  2890. $oAjaxValidator->CreateObservers( $this );
  2891. }
  2892. // when the form is not posted or the form is not valid
  2893. if( !$this->isPosted() || !$this->isCorrect() )
  2894. {
  2895. // check if a value is set of an unknown field
  2896. if( sizeof( $this->_buffer ) > 0 )
  2897. {
  2898. // error messages for the values for unknown fields
  2899. foreach($this->_buffer as $sField => $a)
  2900. {
  2901. trigger_error('Value set of unknown field "'.$sField.'"', E_USER_WARNING );
  2902. }
  2903. }
  2904. // get the form
  2905. $form = $this->_getForm();
  2906. }
  2907. // when the form is not totaly completed yet (multiple pages)
  2908. else if( $this->_curPage < $this->_pageCounter )
  2909. {
  2910. // upload and convert uploads
  2911. $this->_handleUploads();
  2912. // get the next form
  2913. $form = $this->_getForm( $this -> _curPage + 1 );
  2914. }
  2915. // form in view mode
  2916. elseif($this->isViewMode() == true)
  2917. {
  2918. $form = $this->_getForm();
  2919. }
  2920. // when the form is valid
  2921. else
  2922. {
  2923. // upload and convert uploads
  2924. $this->_handleUploads();
  2925. // generate the data array
  2926. $data = array();
  2927. reset( $this->_fields );
  2928. while( list( $name, $fld ) = each( $this->_fields) )
  2929. {
  2930. if(is_object($fld[1]) && method_exists($fld[1], 'getValue') && $name != $this->_name.'_submit')
  2931. {
  2932. $data[$name] = $fld[1]->getValue();
  2933. }
  2934. }
  2935. // add the user added data to the array
  2936. $data = array_merge( $data, $this->_add );
  2937. // call the users oncorrect function
  2938. if(!empty($this->_onCorrect))
  2939. {
  2940. if(is_array($this->_onCorrect))
  2941. {
  2942. $hideForm = call_user_func_array( array(&$this->_onCorrect[0], $this->_onCorrect[1]), array($data, &$this) );
  2943. }
  2944. else
  2945. {
  2946. $hideForm = call_user_func_array( $this->_onCorrect, array($data, &$this) );
  2947. }
  2948. }
  2949. // add the user added data again to the array (could have been changed!)
  2950. $data = array_merge( $data, $this->_add );
  2951. // display the form again if wanted..
  2952. if(isset($hideForm) && $hideForm === false)
  2953. {
  2954. $form = $this->_getForm();
  2955. }
  2956. // the user want's to display something else..
  2957. else if( isset( $hideForm ) && is_string($hideForm))
  2958. {
  2959. $form = $hideForm;
  2960. }
  2961. // dont display the form..
  2962. else
  2963. {
  2964. $form = '';
  2965. }
  2966. }
  2967. // cache all the fields values for the function value()
  2968. reset( $this->_fields );
  2969. while( list( $fld, $value ) = each( $this->_fields) )
  2970. {
  2971. // check if it's a field
  2972. if( is_object($this->_fields[$fld][1]) && method_exists($this->_fields[$fld][1], "getvalue"))
  2973. {
  2974. $this->_cache[ $fld ] = $this->_fields[$fld][1]->getValue();
  2975. }
  2976. }
  2977. /*
  2978. // remove all vars to free memory
  2979. $vars = get_object_vars($this);
  2980. foreach( $vars as $name => $value )
  2981. {
  2982. // remove all vars except these..
  2983. if( !in_array($name, array( '_cache', 'edit', 'insert', '_posted', '_name' ) ) )
  2984. {
  2985. unset( $this->{$name} );
  2986. }
  2987. }
  2988. */
  2989. // disable our error handler!
  2990. if( FH_DISPLAY_ERRORS )
  2991. {
  2992. restore_error_handler();
  2993. }
  2994. // return or print the form
  2995. if( $return )
  2996. {
  2997. return $form;
  2998. }
  2999. else
  3000. {
  3001. echo $form;
  3002. return null;
  3003. }
  3004. }
  3005. /********************************************************/
  3006. /************* BELOW IS ALL PRIVATE!! *******************/
  3007. /********************************************************/
  3008. /**
  3009. * FormHandler::_getNewButtonName()
  3010. *
  3011. * when no button name is given, get a unique button name
  3012. *
  3013. * @access private
  3014. * @return string: the new unique button name
  3015. * @author Teye Heimans
  3016. */
  3017. function _getNewButtonName()
  3018. {
  3019. static $counter = 1;
  3020. return 'button'.$counter++;
  3021. }
  3022. /**
  3023. * FormHandler::_setJS()
  3024. *
  3025. * Set the javascript needed for the fields
  3026. *
  3027. * @param string $js: The javascript to set
  3028. * @param boolean $isFile: Is the setted javascript a file?
  3029. * @param boolean $before: should the javascript be placed before or after the form?
  3030. * @return void
  3031. * @access private
  3032. * @author Teye Heimans
  3033. */
  3034. function _setJS( $js, $isFile = false, $before = true)
  3035. {
  3036. $this->_js[$before?0:1][$isFile?'file':'code'][] = $js;
  3037. }
  3038. /**
  3039. * FormHandler::_text()
  3040. *
  3041. * Return the given text in the correct language
  3042. *
  3043. * @param int $index: the index of the text in the textfile
  3044. * @return string: the text in the correct language
  3045. * @access private
  3046. * @author Teye Heimans
  3047. */
  3048. function _text( $iIndex )
  3049. {
  3050. // is a language set?
  3051. if( !isset( $this->_text ) || !is_array($this->_text))
  3052. {
  3053. trigger_error('No language file set!', E_USER_ERROR);
  3054. return false;
  3055. }
  3056. // does the index exists in the language file ?
  3057. if( !array_key_exists($iIndex, $this->_text) )
  3058. {
  3059. trigger_error('Unknown index '.$iIndex.' to get language string!', E_USER_NOTICE);
  3060. return '';
  3061. }
  3062. // return the language string
  3063. return $this->_text[$iIndex];
  3064. }
  3065. /**
  3066. * FormHandler::_registerField()
  3067. *
  3068. * Register a field or button at FormHandler
  3069. *
  3070. * @param string $name: The name of the field (or button)
  3071. * @param object $field: The object of the field or button
  3072. * @return string $title: The titlt of the field. Leave blank for a button
  3073. * @access private
  3074. * @author Teye Heimans
  3075. */
  3076. function _registerField( $name, &$field, $title = null )
  3077. {
  3078. // if no title is known then its a button..
  3079. if( $title === null )
  3080. {
  3081. $title = '__BUTTON__';
  3082. }
  3083. $this->_fields[$name] = array( $title, &$field );
  3084. return $field;
  3085. }
  3086. /**
  3087. * FormHandler::_registerFileName()
  3088. *
  3089. * Register the filenames which upload fields are using for there
  3090. * uploaded file so that other upload fields cannot use these.
  3091. * This is to prevent double filenames assumed by the upload fields
  3092. *
  3093. * @param string $sFilename: the filename to register
  3094. * @param string $sField: the field who is registering the file
  3095. * @return bool: false if the filename is already registered, true otherwise
  3096. * @access private
  3097. * @author Teye Heimans
  3098. */
  3099. function _registerFileName( $sFilename, $sField )
  3100. {
  3101. static $aFilenames = array();
  3102. // is the filename already registerd ?
  3103. if( isset($aFilenames[$sFilename]) && $aFilenames[$sFilename] != $sField)
  3104. {
  3105. return false;
  3106. }
  3107. // file name is still free.. register it and return true
  3108. $aFilenames[$sFilename] = $sField;
  3109. return true;
  3110. }
  3111. /**
  3112. * FormHandler::_handleUploads()
  3113. *
  3114. * Private: method to handle the uploads and image convertions
  3115. *
  3116. * @return void
  3117. * @access public
  3118. * @author Teye Heimans
  3119. */
  3120. function _handleUploads()
  3121. {
  3122. // upload the uploaded files
  3123. foreach( $this->_upload as $name )
  3124. {
  3125. $this->_fields[$name][1]->doUpload();
  3126. }
  3127. // walk all convert actions for the upload fields
  3128. foreach( $this->_convert as $field => $convertions )
  3129. {
  3130. // walk all convertions for this field
  3131. foreach( $convertions as $action => $data )
  3132. {
  3133. // check if the field is an upload field and that there is a file uploaded
  3134. if( in_array($field, $this->_upload) )
  3135. {
  3136. // is the file uploaded ?
  3137. if( $this->_fields[$field][1]->isUploaded() )
  3138. {
  3139. // get the file which is uploaded
  3140. $file =
  3141. $this->_fields[$field][1]->getSavePath().
  3142. $this->_fields[$field][1]->getValue();
  3143. // check if the file exitst
  3144. if( !file_exists($file) )
  3145. {
  3146. trigger_error("Error! Could not find uploaded file $file!", E_USER_WARNING);
  3147. unset($file);
  3148. continue;
  3149. }
  3150. }
  3151. // the uploadfield is not uploaded yet... do nothing.
  3152. else
  3153. {
  3154. // go to the next field
  3155. continue 2;
  3156. }
  3157. }
  3158. // it's not a uploadfield... is it an image ?
  3159. else if( file_exists($field) )
  3160. {
  3161. $file = $field;
  3162. // unknown field or file!
  3163. }
  3164. else
  3165. {
  3166. trigger_error('Could not find field or file to convert: '.$field , E_USER_WARNING);
  3167. continue;
  3168. }
  3169. // do the convert actions with the image (when the uploaded file is a jpg or png!)
  3170. if( isset($file) && in_array( strtolower(substr( $file, -4) ), array('.jpg', '.png', 'jpeg', '.gif')) )
  3171. {
  3172. // create a new image converter
  3173. $img = new ImageConverter( $file );
  3174. // stop when a error occoured
  3175. if( $img->getError() )
  3176. {
  3177. trigger_error( $img->getError(), E_USER_WARNING );
  3178. unset( $img );
  3179. continue;
  3180. }
  3181. // walk each data (there can be more of the save convertions on the save file!)
  3182. foreach( $data as $info )
  3183. {
  3184. // check if an error occured
  3185. if( $img->getError() )
  3186. {
  3187. // stop converting and notice the user
  3188. trigger_error( $img->getError(), E_USER_WARNING );
  3189. break;
  3190. }
  3191. switch($action)
  3192. {
  3193. // merge the uploaded file with a merge image
  3194. case 'merge':
  3195. list( $stamp, $align, $valign, $transparant ) = $info;
  3196. $img -> doMerge( $stamp, $align, $valign, $transparant );
  3197. break;
  3198. // resize the uploaded file
  3199. case 'resize':
  3200. list( $destination, $maxX, $maxY, $quality, $proportions ) = $info;
  3201. if( empty( $destination ) ) {
  3202. $destination = $file;
  3203. }
  3204. $img -> setQuality( $quality );
  3205. $img -> setConstrainProportions( $proportions );
  3206. $img -> doResize( $destination, $maxX, $maxY );
  3207. break;
  3208. }
  3209. }
  3210. unset( $img );
  3211. }
  3212. unset( $file );
  3213. }
  3214. }
  3215. }
  3216. /**
  3217. * FormHandler::_getForm()
  3218. *
  3219. * Private: get the form
  3220. *
  3221. * @return string: the generated form
  3222. * @access public
  3223. * @author Teye Heimans
  3224. */
  3225. function _getForm( $iDisplayPage = null )
  3226. {
  3227. // is no specific page requested, then get the "current" page
  3228. if( is_null( $iDisplayPage ) )
  3229. {
  3230. $iDisplayPage = $this->_curPage;
  3231. }
  3232. // make sure that the requested page cannot be negative
  3233. if( $iDisplayPage <= 0)
  3234. {
  3235. $iDisplayPage = 1;
  3236. }
  3237. // set the tab indexes for the fields...
  3238. reset( $this->_tabindexes );
  3239. ksort( $this->_tabindexes );
  3240. while( list( $index, $field ) = each( $this->_tabindexes ))
  3241. {
  3242. // check if the field exists in the form ?
  3243. if( $this->fieldExists( $field ) )
  3244. {
  3245. // set the tab index
  3246. $this->_fields[$field][1]->setTabIndex( $index );
  3247. }
  3248. // tab index set for unknown field... trigger_error
  3249. else
  3250. {
  3251. trigger_error(
  3252. 'Error, try to set the tabindex of an unknown field "'.$field.'"!',
  3253. E_USER_NOTICE
  3254. );
  3255. }
  3256. }
  3257. // set the focus to the first (tab index) field if no focus is set yet
  3258. if( is_null($this->_focus) )
  3259. {
  3260. // are there tab indexes set ?
  3261. if( sizeof( $this->_tabindexes) > 0 )
  3262. {
  3263. // set the focus to the element with the lowest positive tab index
  3264. reset( $this->_tabindexes );
  3265. while( list( $key, $field ) = each( $this->_tabindexes ))
  3266. if( $key >= 0 && $this->setFocus( $field ))
  3267. break;
  3268. }
  3269. // no focus set yet. Set the focus to the first field
  3270. if( is_null($this->_focus))
  3271. {
  3272. // is it a object (only fields + buttons are objects)
  3273. foreach( $this->_fields as $name => $data )
  3274. if( is_object( $this->_fields[$name][1]) && $this->setFocus( $name ))
  3275. break;
  3276. }
  3277. }
  3278. // initialize the used vars
  3279. $hidden = '';
  3280. $form = '';
  3281. $buffer = array();
  3282. $repeat = true;
  3283. $page = 1;
  3284. // start a new mask loader
  3285. $mask = new MaskLoader();
  3286. // set the seach values
  3287. $mask -> setSearch(
  3288. array(
  3289. '/%field%/',
  3290. '/%error%/',
  3291. '/%title%/',
  3292. '/%seperator%/',
  3293. '/%name%/',
  3294. '/%error_id%/',
  3295. '/%value%/',
  3296. '/%help%/'
  3297. )
  3298. );
  3299. // walk trought the fields array
  3300. foreach( $this->_fields as $id => $field )
  3301. {
  3302. switch( $field[0] )
  3303. {
  3304. // multiple pages in this form
  3305. case '__PAGE__':
  3306. # why did we stop at the current page ?
  3307. //if( $field[1] == $iDisplayPage)
  3308. //{
  3309. // break;
  3310. //}
  3311. $page++;
  3312. break;
  3313. // hidden field
  3314. case '__HIDDEN__':
  3315. $hidden .= $field[1] -> getField() ."\n";
  3316. $hidden .= $field[1] -> getError() ."\n";
  3317. break;
  3318. // new mask to set
  3319. case '__MASK__':
  3320. if( !isset($this->_mask) || is_null($this->_mask) || $page == $iDisplayPage )
  3321. {
  3322. list($this->_mask, $repeat) = $field[1];
  3323. }
  3324. break;
  3325. // insert html or a line
  3326. case '__HTML__':
  3327. case '__LINE__':
  3328. // but only if the html or line is on this page!
  3329. if($page == $iDisplayPage )
  3330. {
  3331. $form .= $field[1];
  3332. }
  3333. break;
  3334. // begin new fieldset
  3335. case '__FIELDSET__':
  3336. if($page == $iDisplayPage )
  3337. {
  3338. array_unshift( $field[1], $form );
  3339. array_push( $buffer, $field[1] );
  3340. $form = '';
  3341. }
  3342. break;
  3343. // end new fieldset
  3344. case '__FIELDSET-END__':
  3345. if($page == $iDisplayPage )
  3346. {
  3347. if( sizeof($buffer) > 0 )
  3348. {
  3349. $d = array_pop($buffer);
  3350. $form = $d[0].
  3351. str_replace(
  3352. array('%name%', '%caption%', '%content%', '%extra%' ),
  3353. array($d[1], $d[2], $form, $d[3] ),
  3354. FH_FIELDSET_MASK
  3355. );
  3356. }
  3357. else
  3358. {
  3359. trigger_error('Fieldset is closed while there is not an open fieldset!');
  3360. }
  3361. }
  3362. break;
  3363. // default action: field or button
  3364. default:
  3365. // the fields are not displayed in this page..
  3366. // set them as hidden fields in the form
  3367. if( $page != $iDisplayPage )
  3368. {
  3369. // put the data of the field in a hidden field
  3370. // buttons are just ignored
  3371. if( $field[0] != '__BUTTON__' )
  3372. {
  3373. // create a new hidden field to set the field's value in
  3374. $h = new HiddenField( $this, $id );
  3375. $value = $field[1] -> getValue();
  3376. $h->setValue( is_array( $value ) ? implode(', ', $value) : $value );
  3377. $hidden .= $h -> getField() ."\n";
  3378. unset( $h );
  3379. }
  3380. }
  3381. // the field is on the current page of the form
  3382. else
  3383. {
  3384. // set the mask which should be filled
  3385. $mask -> setMask( $this->_mask );
  3386. // easy names for the data
  3387. $title = $field[0];
  3388. $obj = &$field[1];
  3389. $name = $id;
  3390. // buttons don't have a title :-)
  3391. if($title == '__BUTTON__') $title = '';
  3392. /**
  3393. * From this point, we are collecting the data
  3394. * to fill the mask.
  3395. */
  3396. // Get the field or button value
  3397. // can we get a field ?
  3398. if( is_object( $obj ) && method_exists($obj, 'getField') )
  3399. {
  3400. $fld = $obj -> getField();
  3401. }
  3402. // can we get a button ?
  3403. else if( is_object( $obj ) && method_exists($obj, 'getButton') )
  3404. {
  3405. $fld = $obj -> getButton();
  3406. }
  3407. // ai, not a field and not a button..
  3408. else
  3409. {
  3410. // trigger error ?? (TODO)
  3411. $fld = '';
  3412. }
  3413. // escape dangerous characters
  3414. $fld = str_replace( '%', '____FH-percent____', $fld );
  3415. /**
  3416. * Get the error message for this field
  3417. */
  3418. // get possible error message
  3419. $error = '';
  3420. if( $this->_displayErrors && is_object( $obj ) && method_exists($obj, 'getError') )
  3421. {
  3422. // custom error message set and we got an error?
  3423. if( array_key_exists($name, $this->_customMsg) && $obj->getError() != '' )
  3424. {
  3425. // use the default error mask ?
  3426. if( $this->_customMsg[$name][1] )
  3427. {
  3428. $error = sprintf( FH_ERROR_MASK, $name,$this->_customMsg[$name][0] );
  3429. }
  3430. // dont use the default error mask...
  3431. else
  3432. {
  3433. $error = $this->_customMsg[$name][0];
  3434. }
  3435. }
  3436. // dont use a custom error message.. just get the FH error message
  3437. else
  3438. {
  3439. $error = $obj->getError();
  3440. }
  3441. }
  3442. // save the error messages
  3443. // (when the user wants to use his own error displayer)
  3444. $this->errors[$name] = $error;
  3445. /**
  3446. * Get the value for of the field
  3447. */
  3448. $value = '';
  3449. if( is_object( $obj ) && method_exists($obj, 'getValue') )
  3450. {
  3451. if( is_array($obj->getValue() ) )
  3452. {
  3453. $value = implode(', ', $obj->getValue());
  3454. }
  3455. else
  3456. {
  3457. $value = $obj->getValue() ;
  3458. }
  3459. }
  3460. /**
  3461. * Get the help string
  3462. */
  3463. $help = '';
  3464. if( array_key_exists( $name, $this->_help) && !$this -> isViewMode() && !$this->isFieldViewMode($name) )
  3465. {
  3466. if( strpos( FH_HELP_MASK, '%s' ) )
  3467. {
  3468. $help = sprintf(
  3469. FH_HELP_MASK,
  3470. $this->_helpIcon,
  3471. $this->_help[$name][0],
  3472. str_replace( '%title%', addslashes( htmlentities($title) ), $this->_help[$name][1])
  3473. );
  3474. }
  3475. else
  3476. {
  3477. $help = str_replace( array( '%helpicon%','%helptext%','%helptitle%' ),array( $this->_helpIcon,$this->_help[$name][0],str_replace( '%title%', addslashes( htmlentities( $title ) ), $this->_help[$name][1] ) ),FH_HELP_MASK );
  3478. }
  3479. }
  3480. // give the field a class error added 25-08-2009 in order to give the field the error mask
  3481. if( $this->isPosted() == true AND $error != '' )
  3482. {
  3483. $fld = $this->parse_error_Fieldstyle( $fld );
  3484. }
  3485. // now, put all the replace values into an array
  3486. $replace = array(
  3487. /* %field% */ $fld,
  3488. /* %error% */ $error,
  3489. /* %title% */ !empty($title) ? $title : "",
  3490. /* %seperator% */ ( !strlen($title) ? '' : ':' ),
  3491. /* %name% */ ( !empty($name) ? $name : '' ),
  3492. /* %error_id% */ ( !empty($name) ? 'error_'.$name : '' ),
  3493. /* %value% */ $value,
  3494. /* %help% */ $help
  3495. );
  3496. // fill the mask
  3497. $html = $mask -> fill( $replace );
  3498. // added 07-01-2009 in order to specify which element should get the error class
  3499. if( $this->isPosted() == true AND $error != '' )
  3500. {
  3501. $html = $this->parse_error_style( $html );
  3502. }
  3503. else
  3504. {
  3505. $html = str_replace( '%error_style%','',$html );
  3506. }
  3507. // is the mask filled ?
  3508. if($html)
  3509. {
  3510. // add it the the form HTML
  3511. $form .= str_replace('____FH-percent____', '%', $html );
  3512. // if we don't have to repeat the current mask, use the original
  3513. if( !$repeat )
  3514. {
  3515. $this->_mask = FH_DEFAULT_ROW_MASK;
  3516. }
  3517. // if we have to repeat the mask, repeat it and countdown
  3518. else if( is_numeric($repeat) )
  3519. {
  3520. $repeat--;
  3521. }
  3522. }
  3523. }
  3524. break;
  3525. }
  3526. }
  3527. // add the page number to the forms HTML
  3528. if($this->_pageCounter > 1)
  3529. {
  3530. $h = new HiddenField( $this, $this->_name .'_page' );
  3531. $h->setValue( $iDisplayPage );
  3532. $hidden .= $h->getField() ."\n";
  3533. unset( $h );
  3534. }
  3535. // get a possible half filled mask and add it to the html
  3536. $form .= str_replace('____FH-percent____', '%', $mask-> fill( null ) );
  3537. // delete the mask loader
  3538. unset( $mask );
  3539. // get occured PHP errors
  3540. $errors = catchErrors();
  3541. $errmsg = '';
  3542. // walk all error messages
  3543. foreach($errors as $error)
  3544. {
  3545. switch ($error['no']) {
  3546. case E_USER_WARNING: $type = 'Warning'; break;
  3547. case E_USER_NOTICE: $type = 'Notice'; break;
  3548. case E_USER_ERROR: $type = 'Error'; break;
  3549. default: $type = 'Warning ('.$error['no'].')'; break;
  3550. }
  3551. $errmsg .= "<b>".$type.":</b> ".basename($error['file'])." at ".$error['line']." ". $error['text'] ."<br />\n";
  3552. }
  3553. // set the javascript needed for setting the focus
  3554. if($this->_focus)
  3555. {
  3556. $this -> _setJS(
  3557. "// set the focus on a specific field \n".
  3558. "var elem = document.getElementById ? document.getElementById('".$this->_focus."'): document.all? document.all['".$this->_focus."']: false; \n".
  3559. "if( (elem) && (elem.type != 'hidden')) {\n".
  3560. " try {\n".
  3561. " elem.focus();\n".
  3562. " } catch(e) {}\n".
  3563. "}\n", 0, 0
  3564. );
  3565. }
  3566. // NOTE!!
  3567. // DO NOT REMOVE THIS!
  3568. // You can remove the line "This form is generated by FormHandler" in the config file!!
  3569. // DONT REMOVE THE HTML CODE BELOW! Just set FH_EXPOSE to FALSE!
  3570. $sHeader =
  3571. $errmsg .
  3572. "<!--\n".
  3573. " This form is automaticly being generated by FormHandler v3.\n".
  3574. " See for more info: http://www.formhandler.net\n".
  3575. " This credit MUST stay intact for use\n".
  3576. "-->\n".
  3577. $this->getJavascriptCode( true ).
  3578. '<form id="'.$this->_name.'" method="post" action="'.htmlentities( $this->_action ).'"'.
  3579. ( sizeof($this->_upload) > 0 ? ' enctype="multipart/form-data"':'' ).
  3580. (!empty($this->_extra) ? " ".$this->_extra : "" ).">\n".
  3581. '<ins>'.$hidden.'</ins>'.
  3582. ( $this->_setTable ?
  3583. sprintf(
  3584. "<table border='%d' cellspacing='%d' cellpadding='%d'%s>\n",
  3585. $this->_tableSettings['border'],
  3586. $this->_tableSettings['cellspacing'],
  3587. $this->_tableSettings['cellpadding'],
  3588. (!empty($this->_tableSettings['width']) ? " width='".$this->_tableSettings['width']."'" : "").
  3589. ' '.$this->_tableSettings['extra']
  3590. ) : ''
  3591. );
  3592. $sFooter = ( $this->_setTable ? "\n</table>\n" : '').
  3593. (FH_EXPOSE ?
  3594. "<p><span style='font-family:tahoma;font-size:10px;color:#B5B5B5;font-weight:normal;'>".
  3595. 'This form is generated by </span><a href="http://www.formhandler.net" >'.
  3596. '<span style="font-family:Tahoma;font-size:10px;color:#B5B5B5;"><strong>FormHandler</strong></span></a></p>'."\n" :''
  3597. ).
  3598. "</form>\n".
  3599. "<!--\n".
  3600. " This form is automaticly being generated by FormHandler v3.\n".
  3601. " See for more info: http://www.formhandler.net\n".
  3602. "-->". $this -> getJavascriptCode( false );
  3603. $search = array( '%header%', '%footer%' );
  3604. $replace = array( $sHeader, $sFooter );
  3605. $new_form = str_replace( $search, $replace, $form, $num_replaced );
  3606. if( $num_replaced === 2 )
  3607. {
  3608. return $new_form;
  3609. }
  3610. else
  3611. {
  3612. return $sHeader . $form . $sFooter;
  3613. }
  3614. }
  3615. }
  3616. ?>