PageRenderTime 72ms CodeModel.GetById 9ms RepoModel.GetById 0ms app.codeStats 0ms

/propel_15/vendor/propel/contrib/pat/patForms.php

http://github.com/eventhorizonpl/forked-php-orm-benchmark
PHP | 2784 lines | 1479 code | 297 blank | 1008 comment | 200 complexity | 8141291751468f7519dca1f0e546a175 MD5 | raw file
Possible License(s): LGPL-2.1, LGPL-3.0

Large files files are truncated, but you can click here to view the full file

  1. <?php
  2. /**
  3. * patForms form manager class - serialize form elements into any given output format
  4. * using element classes, and build the output via renderer classes.
  5. *
  6. * $Id: patForms.php 1347 2009-12-03 21:06:36Z francois $
  7. *
  8. * @package patForms
  9. * @author Sebastian Mordziol <argh@php-tools.net>
  10. * @author gERD Schaufelberger <gerd@php-tools.net>
  11. * @author Stephan Schmidt <schst@php-tools.net>
  12. * @copyright 2003-2004 PHP Application Tools
  13. * @license LGPL
  14. * @link http://www.php-tools.net
  15. */
  16. /**
  17. * set the include path
  18. */
  19. if ( !defined( 'PATFORMS_INCLUDE_PATH' ) ) {
  20. define( 'PATFORMS_INCLUDE_PATH', dirname( __FILE__ ). '/patForms' );
  21. }
  22. /**
  23. * needs helper methods of patForms_Element
  24. */
  25. include_once PATFORMS_INCLUDE_PATH . "/Element.php";
  26. /**
  27. * error definition: renderer base class file (renderers/_base.php) could not
  28. * be found.
  29. *
  30. * @see patForms::_createModule()
  31. */
  32. define( "PATFORMS_ERROR_NO_MODULE_BASE_FILE", 1001 );
  33. /**
  34. * error definition: the specified renderer could not be found.
  35. *
  36. * @see patForms::_createModule()
  37. */
  38. define( "PATFORMS_ERROR_MODULE_NOT_FOUND", 1002 );
  39. /**
  40. * error definition: the element added via the {@link patForms::addElement()}
  41. * is not an object. Use the {@link patForms::createElement()} method to
  42. * create an element object.
  43. *
  44. * @see patForms::addElement()
  45. * @see patForms::createElement()
  46. */
  47. define( "PATFORMS_ERROR_ELEMENT_IS_NO_OBJECT", 1003 );
  48. /**
  49. * error definition: generic unexpected error.
  50. */
  51. define( "PATFORMS_ERROR_UNEXPECTED_ERROR", 1004 );
  52. /**
  53. * element does not exist
  54. */
  55. define( "PATFORMS_ERROR_ELEMENT_NOT_FOUND", 1012 );
  56. /**
  57. * renderer object has not been set - if you want to render the form, you have to
  58. * set a renderer object via the {@link patForms::setRenderer()} method. To create
  59. * a renderer, use the {@link patForms::createRenderer()} method.
  60. *
  61. * @see patForms::setRenderer()
  62. * @see patForms::createRenderer()
  63. */
  64. define( "PATFORMS_ERROR_NO_RENDERER_SET", 1013 );
  65. /**
  66. * invalid renderer
  67. *
  68. * @see createRenderer()
  69. */
  70. define( "PATFORMS_ERROR_INVALID_RENDERER", 1014 );
  71. /**
  72. * invalid method
  73. *
  74. * @see setMethod()
  75. */
  76. define( "PATFORMS_ERROR_INVALID_METHOD", 1015 );
  77. /**
  78. * Given parameter is not a boolean value
  79. */
  80. define( "PATFORMS_ERROR_PARAMETER_NO_BOOL", 1016 );
  81. /**
  82. * Given Static property does not exist
  83. */
  84. define( "PATFORMS_ERROR_NO_STATIC_PROPERTY", 1017 );
  85. /**
  86. * Unknown event
  87. */
  88. define( "PATFORMS_ERROR_UNKNOWN_EVENT", 1018 );
  89. /**
  90. * Invalid event handler
  91. */
  92. define( "PATFORMS_ERROR_INVALID_HANDLER", 1019 );
  93. /**
  94. * Event exists
  95. */
  96. define( 'PATFORMS_NOTICE_EVENT_ALREADY_REGISTERED', 1020 );
  97. /**
  98. * Invalid storage container
  99. */
  100. define( 'PATFORMS_ERROR_INVALID_STORAGE', 1021 );
  101. define( 'PATFORMS_NOTICE_ARRAY_EXPECTED', 1022 );
  102. define( 'PATFORMS_NOTICE_ATTRIBUTE_NOT_SUPPORTED', 1023 );
  103. define( 'PATFORMS_NOTICE_INVALID_OPTION', 1024 );
  104. define( 'PATFORMS_ERROR_ATTRIBUTE_REQUIRED', 1025 );
  105. define( 'PATFORMS_ERROR_CAN_NOT_VERIFY_FORMAT', 1026 );
  106. define( 'PATFORMS_ERROR_METHOD_FOR_MODE_NOT_AVAILABLE', 1027 );
  107. /**
  108. * errors apply on translating errors matching current locale settings
  109. */
  110. define( 'PATFORMS_NOTICE_VALIDATOR_ERROR_LOCALE_UNDEFINED', 1028 );
  111. define( 'PATFORMS_WARNING_VALIDATOR_ERROR_UNDEFINED', 1029 );
  112. /**
  113. * apply the rule before the built-in validation
  114. */
  115. define( 'PATFORMS_RULE_BEFORE_VALIDATION', 1 );
  116. /**
  117. * apply the rule after the built-in validation
  118. */
  119. define( 'PATFORMS_RULE_AFTER_VALIDATION', 2 );
  120. /**
  121. * apply the rule before AND after the built-in validation
  122. */
  123. define( 'PATFORMS_RULE_BOTH', 3 );
  124. /**
  125. * attach the observer to the elements
  126. */
  127. define( 'PATFORMS_OBSERVER_ATTACH_TO_ELEMENTS', 1 );
  128. /**
  129. * attach the observer to the form
  130. */
  131. define( 'PATFORMS_OBSERVER_ATTACH_TO_FORM', 2 );
  132. /**
  133. * attach the observer to the form and the elements
  134. */
  135. define( 'PATFORMS_OBSERVER_ATTACH_TO_BOTH', 3 );
  136. /**
  137. * group values should stay nested
  138. */
  139. define('PATFORMS_VALUES_NESTED', 0);
  140. /**
  141. * group values should be flattened
  142. */
  143. define('PATFORMS_VALUES_FLATTENED', 1);
  144. /**
  145. * group values should be prefixed
  146. */
  147. define('PATFORMS_VALUES_PREFIXED', 2);
  148. /**
  149. * Static patForms properties - used to emulate pre-PHP5 static properties.
  150. *
  151. * @see setStaticProperty()
  152. * @see getStaticProperty()
  153. */
  154. $GLOBALS['_patForms'] = array(
  155. 'format' => 'html',
  156. 'locale' => 'C',
  157. 'customLocales' => array(),
  158. 'autoFinalize' => true,
  159. 'defaultAttributes' => array(),
  160. );
  161. /**
  162. * patForms form manager class - serialize form elements into any given output format
  163. * using element classes, and build the output via renderer classes.
  164. *
  165. * @package patForms
  166. * @author Sebastian Mordziol <argh@php-tools.net>
  167. * @author gERD Schaufelberger <gerd@php-tools.net>
  168. * @author Stephan Schmidt <schst@php-tools.net>
  169. * @copyright 2003-2004 PHP Application Tools
  170. * @license LGPL
  171. * @link http://www.php-tools.net
  172. * @version 0.9.0alpha
  173. * @todo check the clientside functionality, as that can lead to broken pages
  174. */
  175. class patForms
  176. {
  177. /**
  178. * javascript that will displayed only once
  179. *
  180. * @access private
  181. * @var array
  182. */
  183. var $globalJavascript = array();
  184. /**
  185. * javascript that will be displayed once per instance
  186. *
  187. * @access private
  188. * @var array
  189. */
  190. var $instanceJavascript = array();
  191. /**
  192. * stores the mode for the form. It defaults to 'default', and is only overwritten if
  193. * set specifically. It is passed on to any elements you create.
  194. *
  195. * @access private
  196. * @see setMode()
  197. */
  198. var $mode = 'default';
  199. /**
  200. * XML entities
  201. *
  202. * @access private
  203. * @see toXML()
  204. * @todo This is redundant to the Element's xmlEntities property - find a way to keep this in one place
  205. */
  206. var $xmlEntities = array(
  207. "<" => "&lt;",
  208. ">" => "&gt;",
  209. "&" => "&amp;",
  210. "'" => "&apos;",
  211. '"' => "&quot;"
  212. );
  213. /**
  214. * stores the format for the element. It defaults to 'html', and is only overwritten if
  215. * set specifically. It is passed on to any elements you create.
  216. *
  217. * @access private
  218. * @see setFormat()
  219. */
  220. var $format = 'html';
  221. /**
  222. * stores the flag telling the form whether it has been submitted - this is passed on to any
  223. * elements you create.
  224. *
  225. * @access private
  226. * @see setSubmitted()
  227. */
  228. var $submitted = false;
  229. /**
  230. * stores the element objects of this form.
  231. * @access private
  232. * @see addElement()
  233. */
  234. var $elements = array();
  235. /**
  236. * stores the current element count for this form, used to generate the ids for each element
  237. * @access private
  238. * @see getElementId()
  239. */
  240. var $elementCounter = 0;
  241. /**
  242. * stores a renderer
  243. * @access private
  244. * @see setRenderer(), renderForm()
  245. */
  246. var $renderer = null;
  247. /**
  248. * stores the locale to use when adding validation errors for the whole form.
  249. *
  250. * @access private
  251. * @var string $locale
  252. * @see setLocale()
  253. */
  254. var $locale = 'C';
  255. /**
  256. * stores custom locale
  257. *
  258. * @access private
  259. * @var array
  260. * @see setLocale()
  261. */
  262. var $customLocales = array();
  263. /**
  264. * stores the element name
  265. * @access private
  266. * @see getElementName()
  267. */
  268. var $elementName = 'Form';
  269. /**
  270. * flag to indicate, whether form should be validated automatically
  271. * by renderForm()
  272. *
  273. * @access private
  274. * @var string
  275. * @see setAutoValidate(), renderForm()
  276. */
  277. var $autoValidate = false;
  278. /**
  279. * name of the variable that indicates, whether the form has
  280. * been submitted.
  281. *
  282. * @access private
  283. * @var string
  284. * @see setAutoValidate()
  285. */
  286. var $submitVar = null;
  287. /**
  288. * event handlers
  289. *
  290. * @access private
  291. * @var array
  292. * @see registerEventHandler()
  293. * @see registerEvent()
  294. */
  295. var $_eventHandler = array();
  296. /**
  297. * events that can be triggered
  298. *
  299. * @access private
  300. * @var array
  301. * @see registerEventHandler()
  302. * @see triggerEvent()
  303. * @see registerEvent()
  304. */
  305. var $_validEvents = array( 'onInit', 'onValidate', 'onSubmit', 'onError', 'onSuccess' );
  306. /**
  307. * Stores whether the current form has been validated
  308. *
  309. * @access private
  310. */
  311. var $validated = false;
  312. /**
  313. * Stores whether the current form is valid or not (after the
  314. * validation process)
  315. *
  316. * @access private
  317. */
  318. var $valid = null;
  319. /**
  320. * Stores the names of all static properties that patForms will use as defaults
  321. * for the properties with the same name on startup.
  322. *
  323. * @access private
  324. */
  325. var $staticProperties = array(
  326. 'format' => 'setFormat',
  327. 'autoFinalize' => 'setAutoFinalize',
  328. 'locale' => 'setLocale',
  329. );
  330. /**
  331. * Stores the flag for the autoFinalize feature
  332. *
  333. * @access private
  334. */
  335. var $autoFinalize = true;
  336. /**
  337. * custom validation rules
  338. *
  339. * @access private
  340. * @var array
  341. */
  342. var $_rules = array();
  343. /**
  344. * define error codes an messages for the form
  345. *
  346. * Will be set by validation rules that have been
  347. * added to the form.
  348. *
  349. * @access private
  350. * @var array $validatorErrorCodes
  351. */
  352. var $validatorErrorCodes = array();
  353. /**
  354. * stores any validation errors that can occurr during the
  355. * form's validation process.
  356. *
  357. * @access private
  358. * @var array $validationErrors
  359. */
  360. var $validationErrors = array();
  361. /**
  362. * next error offset for rules
  363. * @access private
  364. * @var integer
  365. */
  366. var $nextErrorOffset = 1000;
  367. /**
  368. * Attributes of the form - needed to generate the form tag
  369. *
  370. * @access private
  371. * @var array $attributes
  372. * @see setAttribute()
  373. */
  374. var $attributes = array();
  375. /**
  376. * Attribute definition for the form - defines which attribute the form
  377. * itself supports.
  378. *
  379. * @access public
  380. */
  381. var $attributeDefinition = array(
  382. 'id' => array(
  383. 'required' => false,
  384. 'format' => 'string',
  385. 'outputFormats' => array( 'html' ),
  386. ),
  387. 'name' => array(
  388. 'required' => true,
  389. 'format' => 'string',
  390. 'outputFormats' => array( 'html' ),
  391. ),
  392. 'method' => array(
  393. 'required' => true,
  394. 'format' => 'string',
  395. 'default' => 'post',
  396. 'outputFormats' => array( 'html' ),
  397. ),
  398. 'action' => array(
  399. 'required' => true,
  400. 'format' => 'string',
  401. 'outputFormats' => array( 'html' ),
  402. ),
  403. 'accept' => array(
  404. 'required' => false,
  405. 'format' => 'string',
  406. 'outputFormats' => array( 'html' ),
  407. ),
  408. 'accept-charset' => array(
  409. 'required' => false,
  410. 'format' => 'string',
  411. 'outputFormats' => array( 'html' ),
  412. ),
  413. 'enctype' => array(
  414. 'required' => false,
  415. 'format' => 'string',
  416. 'outputFormats' => array( 'html' ),
  417. ),
  418. 'onreset' => array(
  419. 'required' => false,
  420. 'format' => 'string',
  421. 'outputFormats' => array( 'html' ),
  422. ),
  423. 'onsubmit' => array(
  424. 'required' => false,
  425. 'format' => 'string',
  426. 'outputFormats' => array( 'html' ),
  427. ),
  428. 'target' => array(
  429. 'required' => false,
  430. 'format' => 'string',
  431. 'outputFormats' => array( 'html' ),
  432. ),
  433. );
  434. /**
  435. * Stores all available patForms options - these are inherited by all elements
  436. * and their dependencies, like rules.
  437. *
  438. * Short option overview:
  439. *
  440. * - scripts: enable client script integration
  441. *
  442. * @access public
  443. */
  444. var $options = array(
  445. 'scripts' => array(
  446. 'enabled' => true,
  447. 'params' => array(),
  448. ),
  449. );
  450. /**
  451. * observers of the form
  452. *
  453. * @access private
  454. * @var array
  455. */
  456. var $observers = array();
  457. /**
  458. * Sets the default attributes that will be inherited by any elements you add to the form.
  459. *
  460. * <b>Note:</b> You have to call this method statically before creating a new form if you use
  461. * patForm's automatic element creation feature via the {@link createForm()} method, as the
  462. * default attributes cannot be set after an element has been created.
  463. *
  464. * @static
  465. * @access public
  466. * @param array $attributes The list of attributes to set with key => value pairs.
  467. */
  468. function setDefaultAttributes( $attributes )
  469. {
  470. patForms::setStaticProperty( 'defaultAttributes', $attributes );
  471. }
  472. /**
  473. * sets the locale (language) to use for the validation error messages of all elements
  474. * in the form.
  475. *
  476. * @access public
  477. * @param string language code
  478. * @param string optional language file
  479. * @return bool True on success
  480. */
  481. function setLocale( $locale, $languageFile = null )
  482. {
  483. if (!is_null($languageFile)) {
  484. $languageData = patForms::parseLocaleFile($languageFile);
  485. $customLocales = patForms::getStaticProperty('customLocales');
  486. $customLocales[$locale] = $languageData;
  487. patForms::setStaticProperty('customLocales', $customLocales);
  488. }
  489. if ( isset( $this ) && is_a( $this, 'patForms' ) ) {
  490. $this->locale = $locale;
  491. if ( !empty( $this->elements ) ) {
  492. $cnt = count( $this->elements );
  493. for ( $i=0; $i < $cnt; $i++ ) {
  494. $this->elements[$i]->setLocale( $locale );
  495. }
  496. }
  497. } else {
  498. patForms::setStaticProperty('locale', $locale);
  499. }
  500. return true;
  501. }
  502. /**
  503. * checks, whether a locale is a custom locale
  504. *
  505. * @static
  506. * @access public
  507. * @param string locale name
  508. * @return boolean
  509. */
  510. function isCustomLocale($locale)
  511. {
  512. $customLocales = patForms::getStaticProperty('customLocales');
  513. if (isset($customLocales[$locale])) {
  514. return true;
  515. }
  516. return false;
  517. }
  518. /**
  519. * get the custom locale for an element or a rule
  520. *
  521. * @static
  522. * @access public
  523. * @param string locale
  524. * @param string key
  525. * @return array
  526. */
  527. function getCustomLocale($locale, $key)
  528. {
  529. $customLocales = patForms::getStaticProperty('customLocales');
  530. if (!isset($customLocales[$locale])) {
  531. return false;
  532. }
  533. if (!isset($customLocales[$locale][$key])) {
  534. return false;
  535. }
  536. return $customLocales[$locale][$key];
  537. }
  538. /**
  539. * parses a locale file
  540. *
  541. * @access private
  542. * @param string filename
  543. * @return array locale information
  544. * @todo add some file checks
  545. */
  546. function parseLocaleFile($filename)
  547. {
  548. return parse_ini_file($filename, true);
  549. }
  550. /**
  551. * sets the format of the element - this will be passed on to any elements you create. If you
  552. * have already added some elements when you call this method, it will be passed on to them too.
  553. *
  554. * @access public
  555. * @param string $format The name of the format you have implemented in your element(s).
  556. * @return bool $result True on success
  557. * @see setMode()
  558. * @see format
  559. * @see serialize()
  560. */
  561. function setFormat( $format )
  562. {
  563. if ( isset( $this ) && is_a( $this, 'patForms' ) )
  564. {
  565. $this->format = strtolower( $format );
  566. if ( !empty( $this->elements ) )
  567. {
  568. $cnt = count( $this->elements );
  569. for ( $i=0; $i < $cnt; $i++ )
  570. {
  571. $this->elements[$i]->setFormat( $format );
  572. }
  573. }
  574. }
  575. else
  576. {
  577. patForms::setStaticProperty( 'format', $format );
  578. }
  579. return true;
  580. }
  581. /**
  582. * sets the mode of the form - If you have already added some elements when you call this
  583. * method, it will be passed on to them too.
  584. *
  585. * @access public
  586. * @param string $mode The mode to set the form to: default|readonly or any other mode you have implemented in your element class(es). Default is 'default'.
  587. * @see setMode()
  588. * @see mode
  589. * @see serialize()
  590. */
  591. function setMode( $mode )
  592. {
  593. $this->mode = strtolower( $mode );
  594. if ( !empty( $this->elements ) )
  595. {
  596. $cnt = count( $this->elements );
  597. for ( $i=0; $i < $cnt; $i++ )
  598. {
  599. $this->elements[$i]->setMode( $mode );
  600. }
  601. }
  602. }
  603. /**
  604. * sets the current submitted state of the form. Set this to true if you want the form
  605. * to pick up its submitted data. It will pass on this information to all elements that
  606. * have been added so far, and new ones inherit it too.
  607. *
  608. * @access public
  609. * @param bool $state True if it has been submitted, false otherwise (default).
  610. * @see isSubmitted()
  611. * @see submitted
  612. */
  613. function setSubmitted( $state )
  614. {
  615. if ( $state == true )
  616. {
  617. $eventState = $this->triggerEvent( 'Submit' );
  618. if ( $eventState === false )
  619. return false;
  620. }
  621. $this->submitted = $state;
  622. if ( !empty( $this->elements ) )
  623. {
  624. $cnt = count( $this->elements );
  625. for ( $i=0; $i < $cnt; $i++ )
  626. {
  627. $this->elements[$i]->setSubmitted( $state );
  628. }
  629. }
  630. return $state;
  631. }
  632. /**
  633. * sets the method for the request
  634. *
  635. * @access public
  636. * @param string $method GET or POST
  637. * @see method
  638. * @uses setAttribute()
  639. */
  640. function setMethod( $method )
  641. {
  642. $method = strtolower( $method );
  643. if ( $method != 'get' && $method != 'post' )
  644. {
  645. return patErrorManager::raiseError(
  646. PATFORMS_ERROR_INVALID_METHOD,
  647. 'Unknown method "'.$method.'". Currently only GET and POST are supported as patForms methods.'
  648. );
  649. }
  650. $this->setAttribute( 'method', $method );
  651. return true;
  652. }
  653. /**
  654. * sets the action for the form
  655. *
  656. * This is a only a wrapper for setAttribute()
  657. *
  658. * @access public
  659. * @param string $action
  660. * @see setAttribute()
  661. */
  662. function setAction( $action )
  663. {
  664. return $this->setAttribute( 'action', $action );
  665. }
  666. /**
  667. * Sets the AutoFinalize mode for the form. The AutoFinalize mode will tell patForms to
  668. * finalize all elements after the form has been validated successfully.
  669. *
  670. * @access public
  671. * @param boolean $mode Whether to activate the AutoFinalize mode (true) or not (false).
  672. * @return boolean $success True if okay, a patError object otherwise.
  673. * @see finalizeForm()
  674. */
  675. function setAutoFinalize( $mode )
  676. {
  677. if ( !is_bool( $mode ) )
  678. {
  679. return patErrorManager::raiseError(
  680. PATFORMS_ERROR_PARAMETER_NO_BOOL,
  681. 'The setAutoFinalize() method requires a boolean value ( true or false ) as parameter.'
  682. );
  683. }
  684. if ( isset( $this ) && is_a( $this, 'patForms' ) )
  685. {
  686. $this->autoFinalize = $mode;
  687. }
  688. else
  689. {
  690. patForms::setStaticProperty( 'autoFinalize', $mode );
  691. }
  692. return true;
  693. }
  694. /**
  695. * Wrapper method that adds a filter to all elements
  696. * of the form at once instead of having to do it for
  697. * each element.
  698. *
  699. * @access public
  700. * @param object &$filter The filter object to apply
  701. * @see patForms_Element::applyFilter()
  702. * @todo add error management and docs once the element's applyFilter method has too
  703. */
  704. function applyFilter( &$filter )
  705. {
  706. if ( empty( $this->elements ) )
  707. return true;
  708. $cnt = count( $this->elements );
  709. for ( $i = 0; $i < $cnt; $i++ )
  710. {
  711. $this->elements[$i]->applyFilter( $filter );
  712. }
  713. }
  714. /**
  715. * creates a new patForms object and returns it; this method is made to be called statically
  716. * to be able to create a new patForms object from anywhere.
  717. *
  718. * @access public
  719. * @param array $formDefinition Optional form definition for elements that will be added to the form
  720. * @param array $attributes The attributes to set for the form itself
  721. * @return object patForms $form The new patForms object.
  722. * @todo it should be possible to pass Rule definitions, so they can be loaded and added automatically.
  723. */
  724. function &createForm( $formDefinition = null, $attributes = null )
  725. {
  726. $form = &new patForms();
  727. if ( $attributes != null )
  728. {
  729. $form->setAttributes( $attributes );
  730. }
  731. if ( $formDefinition === null )
  732. return $form;
  733. foreach ( $formDefinition as $name => $element )
  734. {
  735. if ( !isset( $element["filters"] ) )
  736. {
  737. $element["filters"] = null;
  738. }
  739. if ( !isset( $element["children"] ) )
  740. {
  741. $element["children"] = null;
  742. }
  743. $el = &$form->createElement( $name, $element["type"], $element["attributes"], $element["filters"], $element["children"] );
  744. if ( isset( $element["renderer"] ) ) {
  745. $el->setRenderer( $element["renderer"] );
  746. }
  747. $result = $form->addElement( $el );
  748. if (patErrorManager::isError( $result )) {
  749. return $result;
  750. }
  751. }
  752. return $form;
  753. }
  754. /**
  755. * add a custom validation rule
  756. *
  757. * @access public
  758. * @param object patForms_Rule validation rule
  759. * @param integer time to apply rule (before or after built-in validation)
  760. * @param boolean apply the rule, even if the form is invalid
  761. * @param boolean should form get revalidated (not implemented yet)
  762. * @return boolean currently always true
  763. */
  764. function addRule( &$rule, $time = PATFORMS_RULE_AFTER_VALIDATION, $invalid = false, $revalidate = false )
  765. {
  766. $rule->prepareRule( $this );
  767. $this->_rules[] = array(
  768. 'rule' => &$rule,
  769. 'time' => $time,
  770. 'invalid' => $invalid,
  771. 'revalidate' => $revalidate
  772. );
  773. }
  774. /**
  775. * patForms PHP5 constructor - processes some intitialization tasks like merging the currently
  776. * set static properties with the internal properties.
  777. *
  778. * @access public
  779. */
  780. function __construct()
  781. {
  782. foreach ( $this->staticProperties as $staticProperty => $setMethod )
  783. {
  784. $propValue = patForms::getStaticProperty( $staticProperty );
  785. if ( patErrorManager::isError( $propValue ) )
  786. continue;
  787. $this->$setMethod( $propValue );
  788. }
  789. // initialize patForms internal attribute collection
  790. $this->loadAttributeDefaults();
  791. }
  792. /**
  793. * patForms pre-PHP5 constructor - does nothing for the moment except being a wrapper
  794. * for the PHP5 contructor for older PHP versions support.
  795. *
  796. * @access public
  797. */
  798. function patForms()
  799. {
  800. patForms::__construct();
  801. }
  802. /**
  803. * sets a renderer object that will be used to render
  804. * the form.
  805. *
  806. * @access public
  807. * @param object &$renderer The renderer object
  808. * @return mixed $success True on success, patError object otherwise.
  809. * @see createRenderer()
  810. * @see renderForm()
  811. */
  812. function setRenderer( &$renderer, $args = array() )
  813. {
  814. if ( !is_object( $renderer ) )
  815. {
  816. return patErrorManager::raiseError(
  817. PATFORMS_ERROR_INVALID_RENDERER,
  818. 'You can only set a patForms_Renderer object with the setRenderer() method, "'.gettype( $renderer ).'" given.'
  819. );
  820. }
  821. $this->renderer = &$renderer;
  822. if ( isset( $args['includeElements'] ) && $args['includeElements'] === true )
  823. {
  824. // check all elements - there may be some that need
  825. // renderers too, so we give them the same renderer if
  826. // they don't already have one.
  827. $cnt = count( $this->elements );
  828. for ( $i = 0; $i < $cnt; $i++ )
  829. {
  830. if ( $this->elements[$i]->usesRenderer && !is_object( $this->elements[$i]->renderer ) )
  831. {
  832. $this->elements[$i]->setRenderer( $renderer );
  833. }
  834. }
  835. }
  836. return true;
  837. }
  838. /**
  839. * sets a storage container object that will be used to store data
  840. *
  841. * @access public
  842. * @param object patForms_Storage
  843. * @see createStorage()
  844. */
  845. function setStorage( &$storage )
  846. {
  847. if ( !is_object( $storage ) )
  848. {
  849. return patErrorManager::raiseError(
  850. PATFORMS_ERROR_INVALID_STORAGE,
  851. 'You can only set a patForms_Storage object with the setStorage() method, "'.gettype( $storage ).'" given.'
  852. );
  853. }
  854. $this->registerEventHandlerObject( $storage,
  855. array(
  856. 'onInit' => 'loadEntry',
  857. 'onValidate' => 'validateEntry',
  858. 'onSuccess' => 'storeEntry'
  859. )
  860. );
  861. }
  862. /**
  863. * renders the form with the renderer that was set via the {@link setRenderer()}
  864. * method.
  865. *
  866. * WARNING: This is still in alpha state!
  867. *
  868. * Should this method return a reference??
  869. * The return value could contain large blocks of HTML or large arrays!
  870. * Do we want to copy these?
  871. *
  872. * @access public
  873. * @param mixed $args arguments that will be passed to the renderer
  874. * @return mixed $form The rendered form, or false if failed.
  875. */
  876. function renderForm( $args = null )
  877. {
  878. if ( $this->renderer === null )
  879. {
  880. return patErrorManager::raiseError(
  881. PATFORMS_ERROR_NO_RENDERER_SET,
  882. 'Form cannot be rendered, you have to set a renderer first via the setRenderer() method.'
  883. );
  884. }
  885. // form is not submitted, or auto-validation is disabled => render it
  886. if ( !$this->isSubmitted() || $this->autoValidate !== true )
  887. {
  888. $this->triggerEvent( 'Init' );
  889. return $this->renderer->render( $this, $args );
  890. }
  891. $this->validateForm();
  892. return $this->renderer->render( $this, $args );
  893. }
  894. /**
  895. * Validates all elements of the form.
  896. *
  897. * @access public
  898. * @param boolean Flag to indicate, whether form should be validated again, if it already has been validated.
  899. * @return boolean True if all elements could be validated, false otherwise.
  900. * @see finishForm()
  901. */
  902. function validateForm( $revalidate = false )
  903. {
  904. if ( $this->validated && !$revalidate )
  905. return $this->valid;
  906. $valid = true;
  907. /**
  908. * validate custom rules
  909. */
  910. if ( !$this->_applyRules( PATFORMS_RULE_BEFORE_VALIDATION ) )
  911. {
  912. $valid = false;
  913. }
  914. /**
  915. * validate elements
  916. */
  917. if ( $valid === true )
  918. {
  919. $cnt = count( $this->elements );
  920. for ( $i = 0; $i < $cnt; ++$i )
  921. {
  922. if ( !$this->elements[$i]->validate() )
  923. {
  924. $valid = false;
  925. }
  926. }
  927. }
  928. if ($valid === true) {
  929. $result = $this->triggerEvent('Validate');
  930. if ($result === false) {
  931. $valid = false;
  932. }
  933. }
  934. /**
  935. * validate custom rules
  936. */
  937. if ( !$this->_applyRules( PATFORMS_RULE_AFTER_VALIDATION, $valid ) )
  938. {
  939. $valid = false;
  940. }
  941. if ( $valid === true && $this->autoFinalize === true )
  942. $this->finalizeForm();
  943. $this->valid = $valid;
  944. $this->validated = true;
  945. if ( $valid === true )
  946. {
  947. $this->_announce( 'status', 'validated' );
  948. $event = 'Success';
  949. }
  950. else
  951. {
  952. $this->_announce( 'status', 'error' );
  953. $event = 'Error';
  954. }
  955. $this->triggerEvent( $event );
  956. return $this->valid;
  957. }
  958. /**
  959. * apply rules
  960. *
  961. * @access private
  962. * @param integer time of validation
  963. * @param boolean form is valid
  964. * @return boolean rules are valid or not
  965. * @todo add documentation
  966. */
  967. function _applyRules( $time, $isValid = true )
  968. {
  969. $valid = true;
  970. $cnt = count( $this->_rules );
  971. for ($i = 0; $i < $cnt; $i++) {
  972. // wrong time
  973. if (( $this->_rules[$i]['time'] & $time ) != $time) {
  974. continue;
  975. }
  976. if (!$isValid && !$this->_rules[$i]['invalid']) {
  977. continue;
  978. }
  979. $result = $this->_rules[$i]['rule']->applyRule( $this, PATFORMS_RULE_AFTER_VALIDATION );
  980. if ( $result === false ) {
  981. $valid = false;
  982. }
  983. }
  984. return $valid;
  985. }
  986. /**
  987. * Finalizes the form by telling each fom element to finalize - finalizing means to
  988. * process any tasks that need to be done after the form has been validated, like
  989. * deleting any temporary files or whatever an element needs to do at that point.
  990. *
  991. * @access public
  992. * @return bool $success Wether all elements could be finalized
  993. * @see validateForm()
  994. */
  995. function finalizeForm()
  996. {
  997. $success = true;
  998. $cnt = count( $this->elements );
  999. for ( $i = 0; $i < $cnt; ++$i )
  1000. {
  1001. if ( !$this->elements[$i]->finalize() )
  1002. {
  1003. patErrorManager::raiseWarning(
  1004. PATFORMS_ERROR_ELEMENT_NOT_FINALIZED,
  1005. 'Element "'.$this->elements[$i]->elementName.'" could not be finalized. See the element error messages for more details.'
  1006. );
  1007. $success = false;
  1008. }
  1009. }
  1010. return $success;
  1011. }
  1012. /**
  1013. * creates a new renderer from the patForms renderer collection and returns it.
  1014. *
  1015. * @access public
  1016. * @param string The name of the renderer to create - have a look at the Renderer/ subfolder for a list of available renderers.
  1017. * @return object patForms_Renderer The renderer object, or error object
  1018. */
  1019. function &createRenderer( $name )
  1020. {
  1021. return patForms::_createModule( 'Renderer', $name );
  1022. }
  1023. /**
  1024. * creates a new storage container and returns it.
  1025. *
  1026. * @access public
  1027. * @param string The name of the storage to create - have a look at the Storage/ subfolder for a list of available storage containers.
  1028. * @return object patForms_Storage The storage container, or error object
  1029. */
  1030. function &createStorage( $name )
  1031. {
  1032. return patForms::_createModule( 'Storage', $name );
  1033. }
  1034. /**
  1035. * Creates a new filter and returns it.
  1036. *
  1037. * You may pass an array as second parameter that contains
  1038. * parameters for the filter. patForms will check for setter methods
  1039. * for all keys and set the corresponding values.
  1040. *
  1041. * This eases the creating of simple filter objects.
  1042. *
  1043. * @access public
  1044. * @param string The name of the filter to create - have a look at the Filter/ subfolder for a list of available filters.
  1045. * @param array Optional parameters for the filter, if you provide a parameter, make sure the filter implements a set[Paramname]() method.
  1046. * This will be automated with interceptors in the PHP5 version of patForms
  1047. * @return object patForms_Filter The filter, or error object
  1048. */
  1049. function &createFilter( $name, $params = null )
  1050. {
  1051. $filter = &patForms::_createModule( 'Filter', $name );
  1052. if ( !is_array( $params ) )
  1053. {
  1054. return $filter;
  1055. }
  1056. foreach ( $params as $param => $value )
  1057. {
  1058. $setter = 'set' . ucfirst( $param );
  1059. if ( method_exists( $filter, $setter ) )
  1060. {
  1061. $filter->$setter( $value );
  1062. }
  1063. }
  1064. return $filter;
  1065. }
  1066. /**
  1067. * creates a new rule from the patForms rule collection and returns it.
  1068. *
  1069. * If your rules are not located in patForms/Rule you have to load and
  1070. * instantiate them on your own.
  1071. *
  1072. * @access public
  1073. * @param string The name of the rule to create - have a look at the Rule/ subfolder for a list of available rules.
  1074. * @param string The id of the rule, needed if the rule uses client side actions.
  1075. * @return object patForms_Rule The rule object, or error object
  1076. */
  1077. function &createRule( $name, $id = null )
  1078. {
  1079. $rule = &patForms::_createModule( 'Rule', $name );
  1080. if ( $id != null )
  1081. {
  1082. $rule->setId( $id );
  1083. }
  1084. return $rule;
  1085. }
  1086. /**
  1087. * creates a new observer from the patForms observer collection and returns it.
  1088. *
  1089. * If your observers are not located in patForms/Observer you have to load and
  1090. * instantiate them on your own.
  1091. *
  1092. * @access public
  1093. * @param string The name of the observer to create - have a look at the Observer/ subfolder for a list of available observers.
  1094. * @return object patForms_Observer The observer object, or error object
  1095. */
  1096. function &createObserver( $name )
  1097. {
  1098. $observer = &patForms::_createModule( 'Observer', $name );
  1099. return $observer;
  1100. }
  1101. /**
  1102. * creates a new module for patForms
  1103. *
  1104. * @access private
  1105. * @param string $type type of the module. Possible values are 'Renderer', 'Rule'
  1106. * @param string $name The name of the renderer to create - have a look at the renderers/ subfolder for a list of available renderers.
  1107. * @return object $module The module object, or an error object
  1108. */
  1109. function &_createModule( $type, $name )
  1110. {
  1111. $baseFile = PATFORMS_INCLUDE_PATH . '/'.$type.'.php';
  1112. $baseClass = 'patForms_'.$type;
  1113. // if there is an underscore in the module name, we want
  1114. // to load the module from a subfolder, so we transform
  1115. // all underscores to slashes.
  1116. $pathName = $name;
  1117. if ( strstr( $pathName, '_' ) )
  1118. {
  1119. $pathName = str_replace( '_', '/', $name );
  1120. }
  1121. $moduleFile = PATFORMS_INCLUDE_PATH . '/'.$type.'/'.$pathName.'.php';
  1122. $moduleClass = 'patForms_'.$type.'_'.$name;
  1123. if ( !class_exists( $baseClass ) )
  1124. {
  1125. if ( !file_exists( $baseFile ) )
  1126. {
  1127. return patErrorManager::raiseError(
  1128. PATFORMS_ERROR_NO_MODULE_BASE_FILE,
  1129. $type .' base file could not be found',
  1130. 'Tried to load base file in path "'.$baseFile.'"'
  1131. );
  1132. }
  1133. include_once $baseFile;
  1134. }
  1135. if ( !class_exists( $moduleClass ) )
  1136. {
  1137. if ( !file_exists( $moduleFile ) )
  1138. {
  1139. return patErrorManager::raiseError(
  1140. PATFORMS_ERROR_MODULE_NOT_FOUND,
  1141. $type.' "'.$name.'" file "'.$moduleFile. '" could not be found.'
  1142. );
  1143. }
  1144. include_once $moduleFile;
  1145. }
  1146. $module = &new $moduleClass();
  1147. return $module;
  1148. }
  1149. /**
  1150. * adds an element to the form - has to be a patForms_Element object. Use the {@link createElement()}
  1151. * method to create a new element object. Also takes care of passing on the form's configuration
  1152. * including the mode, format and submitted flags to the element.
  1153. *
  1154. * @access public
  1155. * @param object &$element The patForms_Element object to add to this form.
  1156. * @return bool $success True if everything went well, false otherwise.
  1157. * @see patForms_Element
  1158. * @see createElement()
  1159. */
  1160. function addElement( &$element )
  1161. {
  1162. if ( !is_object( $element ) )
  1163. {
  1164. return patErrorManager::raiseError(
  1165. PATFORMS_ERROR_ELEMENT_IS_NO_OBJECT,
  1166. 'The addElement() method expects an element object, "'.gettype( $element ).'" given.'
  1167. );
  1168. }
  1169. if ( patErrorManager::isError( $element ) )
  1170. {
  1171. return patErrorManager::raiseError(
  1172. PATFORMS_ERROR_UNEXPECTED_ERROR,
  1173. 'The element you are trying to add is a patError object, and not a patForms element object.'
  1174. );
  1175. }
  1176. if ( !$element->getId() ) {
  1177. $element->setId( $this->getElementId() );
  1178. }
  1179. $element->setMode( $this->getMode() );
  1180. $element->setFormat( $this->getFormat() );
  1181. $element->setSubmitted( $this->isSubmitted() );
  1182. $element->setLocale( $this->getLocale() );
  1183. $this->elements[] =& $element;
  1184. return true;
  1185. }
  1186. /**
  1187. * replaces an element in the form
  1188. *
  1189. * @access public
  1190. * @param object $element The patForms_Element object to be replaced
  1191. * @param object &$replace The element that will replace the old element
  1192. * @return bool $success True if everything went well, false otherwise.
  1193. * @see patForms_Element
  1194. * @see addElement()
  1195. */
  1196. function replaceElement( $element, &$replace )
  1197. {
  1198. if ( !is_object( $replace ) ) {
  1199. return patErrorManager::raiseError(
  1200. PATFORMS_ERROR_ELEMENT_IS_NO_OBJECT,
  1201. 'The addElement() method expects an element object, "'.gettype( $replace ).'" given.'
  1202. );
  1203. }
  1204. if ( patErrorManager::isError( $replace ) ) {
  1205. return patErrorManager::raiseError(
  1206. PATFORMS_ERROR_UNEXPECTED_ERROR,
  1207. 'The element you are trying to add is a patError object, and not a patForms element object.'
  1208. );
  1209. }
  1210. if (is_object($element)) {
  1211. $element = $element->getId();
  1212. }
  1213. $cnt = count($this->elements);
  1214. for ($i = 0; $i < $cnt; $i++) {
  1215. if ($this->elements[$i]->getId() === $element) {
  1216. if ( !$replace->getId() ) {
  1217. $replace->setId( $this->getElementId() );
  1218. }
  1219. $replace->setMode( $this->getMode() );
  1220. $replace->setFormat( $this->getFormat() );
  1221. $replace->setSubmitted( $this->isSubmitted() );
  1222. $replace->setLocale( $this->getLocale() );
  1223. $this->elements[$i] = &$replace;
  1224. return true;
  1225. }
  1226. // the current element is a container
  1227. if (method_exists($this->elements[$i], 'replaceElement')) {
  1228. $result = $this->elements[$i]->replaceElement($element, $replace);
  1229. if ($result === true) {
  1230. return $result;
  1231. }
  1232. }
  1233. }
  1234. return false;
  1235. }
  1236. /**
  1237. * Get an element by its name.
  1238. *
  1239. * @access public
  1240. * @param string $name name of the element
  1241. * @return object patForms element
  1242. * @deprecated please use patForms::getElementByName() instead
  1243. */
  1244. function &getElement( $name )
  1245. {
  1246. return $this->getElementByName( $name );
  1247. }
  1248. /**
  1249. * Get an element by its name.
  1250. *
  1251. * @access public
  1252. * @param string $name name of the element
  1253. * @return mixed either a patForms element or an array containing patForms elements
  1254. * @see getElementById()
  1255. */
  1256. function &getElementByName( $name )
  1257. {
  1258. if ( $name == '__form' ) {
  1259. return $this;
  1260. }
  1261. $elements = array();
  1262. $cnt = count( $this->elements );
  1263. for ($i = 0; $i < $cnt; $i++) {
  1264. if ($this->elements[$i]->getName() == $name) {
  1265. $elements[] = &$this->elements[$i];
  1266. continue;
  1267. }
  1268. if (method_exists($this->elements[$i], 'getElementById')) {
  1269. patErrorManager::pushExpect(PATFORMS_ERROR_ELEMENT_NOT_FOUND);
  1270. $result = &$this->elements[$i]->getElementByName($name);
  1271. patErrorManager::popExpect();
  1272. if (!patErrorManager::isError($result)) {
  1273. if (is_array($result)) {
  1274. $cnt2 = count( $result );
  1275. for ($j = 0; $j < $cnt2; $j++) {
  1276. $elements[] = &$result[$j];
  1277. }
  1278. } else {
  1279. $elements[] = &$result;
  1280. }
  1281. }
  1282. }
  1283. }
  1284. switch( count( $elements ) )
  1285. {
  1286. case 0:
  1287. return patErrorManager::raiseError(
  1288. PATFORMS_ERROR_ELEMENT_NOT_FOUND,
  1289. 'Element '.$name.' could not be found.'
  1290. );
  1291. break;
  1292. case 1:
  1293. return $elements[0];
  1294. break;
  1295. default:
  1296. return $elements;
  1297. break;
  1298. }
  1299. }
  1300. /**
  1301. * Get an element by its id.
  1302. *
  1303. * @access public
  1304. * @param string $id id of the element
  1305. * @return object patForms element
  1306. */
  1307. function &getElementById( $id )
  1308. {
  1309. $cnt = count( $this->elements );
  1310. for ( $i = 0; $i < $cnt; $i++ )
  1311. {
  1312. if ( $this->elements[$i]->getId() == $id ) {
  1313. return $this->elements[$i];
  1314. }
  1315. if (method_exists($this->elements[$i], 'getElementById')) {
  1316. patErrorManager::pushExpect(PATFORMS_ERROR_ELEMENT_NOT_FOUND);
  1317. $result = &$this->elements[$i]->getElementById($id);
  1318. patErrorManager::popExpect();
  1319. if (!patErrorManager::isError($result)) {
  1320. return $result;
  1321. }
  1322. }
  1323. }
  1324. return patErrorManager::raiseError(
  1325. PATFORMS_ERROR_ELEMENT_NOT_FOUND,
  1326. 'Element '.$name.' could not be found.'
  1327. );
  1328. }
  1329. /**
  1330. * Get all elements of the form
  1331. *
  1332. * @access public
  1333. * @return array all elements of the form
  1334. */
  1335. function &getElements()
  1336. {
  1337. return $this->elements;
  1338. }
  1339. /**
  1340. * Creates a new form element and returns a reference to it.
  1341. *
  1342. * The optional $filters array has to be in the following format:
  1343. *
  1344. * <pre>
  1345. * array(
  1346. * array(
  1347. * 'filter' => 'Multiplier',
  1348. * 'params' => array( 'multiplier' => 6 )
  1349. * )
  1350. * )
  1351. * </pre>
  1352. *
  1353. * @access public
  1354. * @param string $name The name of the element
  1355. * @param string $type The type of the element; for a list of possible elements, have a look at the elements/ subfolder of the patForms package.
  1356. * @param array $attributes Attributes for the element
  1357. * @param array $filters Optional filters that will be applied
  1358. * @return object patForms_Element $element The element object, or patError if failed.
  1359. */
  1360. function &createElement( $name, $type, $attributes, $filters = null, $children = null )
  1361. {
  1362. $element =& patForms::_createModule( 'Element', $type );
  1363. if ( patErrorManager::isError( $element ) )
  1364. {
  1365. return $element;
  1366. }
  1367. $attributes['name'] = $name;
  1368. if ( !isset( $attributes['id'] ) ) {
  1369. $attributes['id'] = $this->getElementId();
  1370. }
  1371. // add default attributes - do this the 'silent' way be checking whether
  1372. // the element supports the given attribute, as the element throws a notice
  1373. // if it does not support it - this is not expected from default attributes.
  1374. foreach ( patForms::getStaticProperty( 'defaultAttributes' ) as $attributeName => $attributeValue )
  1375. {
  1376. if ( !$element->hasAttribute( $attributeName ) )
  1377. {
  1378. continue;
  1379. }
  1380. $element->setAttribute( $attributeName, $attributeValue );
  1381. }
  1382. // set the given attributes normally
  1383. $success = $element->setAttributes( $attributes );
  1384. if ( patErrorManager::isError( $success ) )
  1385. {
  1386. return $success;
  1387. }
  1388. if (is_array($children)) {
  1389. foreach ($children as $child) {
  1390. $childName = $child['attributes']['name'];
  1391. $childEl = &patForms::createElement($childName, $child['type'], $child['attributes']);
  1392. if ( isset( $child["renderer"] ) ) {
  1393. $childEl->setRenderer( $child["renderer"] );
  1394. }
  1395. $element->addElement($childEl);
  1396. }
  1397. }
  1398. $success = $element->_init();
  1399. if ( patErrorManager::isError( $success ) ) {
  1400. return $success;
  1401. }
  1402. // if we don't have any filters to add, we're done
  1403. if ( !is_array( $filters ) )
  1404. {
  1405. return $element;
  1406. }
  1407. $cnt = count( $filters );
  1408. for ( $i = 0; $i < $cnt; $i++ )
  1409. {
  1410. $params = isset( $filters[$i]['params'] ) ? $filters[$i]['params'] : null;
  1411. $filter = &patForms::createFilter( $filters[$i]['filter'], $params );
  1412. if ( patErrorManager::isError( $filter ) )
  1413. {
  1414. continue;
  1415. }
  1416. $element->applyFilter( $filter );
  1417. }
  1418. return $element;
  1419. }
  1420. /**
  1421. * retrieves the validation errors from all elements in the form. Use this if the validateForm()
  1422. * method returned false.
  1423. *
  1424. * @access public
  1425. * q
  1426. * @return array $errors Array containing an array with validation errors for each element in the form.
  1427. * @todo replace __form with the name of the form, once attributes are implemented
  1428. */
  1429. function getValidationErrors($withElements = true)
  1430. {
  1431. $found = false;
  1432. $errors = array();
  1433. if ( !empty( $this->validationErrors ) )
  1434. {
  1435. $errors['__form'] = $this->validationErrors;
  1436. $found = true;
  1437. }
  1438. if ($withElements === false) {
  1439. return $errors;
  1440. }
  1441. $cnt = count( $this->elements );
  1442. for ( $i = 0; $i < $cnt; ++$i )
  1443. {
  1444. $name = $this->elements[$i]->getAttribute( 'name' );
  1445. if ( $name === false )
  1446. {
  1447. continue;
  1448. }
  1449. $elementErrors = $this->elements[$i]->getValidationErrors();
  1450. if ( empty( $elementErrors ) )
  1451. continue;
  1452. $errors[$name] = $elementErrors;
  1453. $found = true;
  1454. }
  1455. if ( $found )
  1456. return $errors;
  1457. return false;
  1458. }
  1459. /**
  1460. * retrieves the values for all elements in the form.
  1461. *
  1462. * @access public
  1463. * @param array desired fields
  1464. * @param integer Mode that should be used to return values in groups
  1465. * @return array The values for all elements, as elementname => elementvalue.
  1466. *
  1467. * @todo remove the ugly Group check and replace with something better
  1468. * @todo implement something similar for getValidation errors
  1469. */
  1470. function getValues( $fields = null, $type = PATFORMS_VALUES_NESTED )
  1471. {
  1472. $values = array();
  1473. $cnt = count( $this->elements );
  1474. for ( $i = 0; $i < $cnt; ++$i )
  1475. {
  1476. $name = $this->elements[$i]->getAttribute( 'name' );
  1477. if ( $name === false ) {
  1478. continue;
  1479. }
  1480. if ( is_array( $fields ) && !in_array( $name, $fields ) ) {
  1481. continue;
  1482. }
  1483. $tmpVal = $this->elements[$i]->getValue();
  1484. if (!is_array($tmpVal) || $this->elements[$i]->elementName != 'Group') {
  1485. $values[$name] = $tmpVal;
  1486. continue;
  1487. }
  1488. switch ($type) {
  1489. case PATFORMS_VALUES_FLATTENED:
  1490. $values = array_merge($values, $tmpVal);
  1491. break;
  1492. case PATFORMS_VALUES_PREFIXED:
  1493. foreach ($tmpVal as $key => $val) {
  1494. $values[$name.'_'.$key] = $val;
  1495. }
  1496. break;
  1497. case PATFORMS_VALUES_NESTED:
  1498. default:
  1499. $values[$name] = $tmpVal;
  1500. break;
  1501. }
  1502. }
  1503. return $values;
  1504. }
  1505. /**
  1506. * sets the values for all elements in the form. Use this to fill your form with external
  1507. * data, like a db query. Caution: if you do this and set the form to submitted, the values
  1508. * will be overwritten by any values present in the $_GET or $_POST variables.
  1509. *
  1510. * @access public
  1511. * @param array $values The values for all elements, as elementname => elementvalue.
  1512. */
  1513. function setValues( $values, $overrideUserInput = false )
  1514. {
  1515. patErrorManager::pushExpect(PATFORMS_ERROR_ELEMENT_NOT_FOUND);
  1516. foreach ($values as $elName => $value) {
  1517. $el = &$this->getElementByName($elName);
  1518. if (patErrorManager::isError($el)) {
  1519. continue;
  1520. }
  1521. if ($overrideUserInput === true) {
  1522. $el->setValue($value);
  1523. } else {
  1524. $el->setDefaultValue($value);
  1525. }
  1526. }
  1527. patErrorManager::popExpect();
  1528. return true;
  1529. }
  1530. /**
  1531. * retrieves the current mode of the form
  1532. *
  1533. * @access public
  1534. * @return string $mode The current form mode
  1535. * @see setMode()
  1536. * @see $mode
  1537. */
  1538. function getMode()
  1539. {
  1540. return $this->mode;
  1541. }
  1542. /**
  1543. * returns the locale that is currently set for the form.
  1544. *
  1545. * @access public
  1546. * @return string $locale The locale.
  1547. * @see setLocale()
  1548. * @see $locale
  1549. */
  1550. function getLocale()
  1551. {
  1552. return $this->locale;
  1553. }
  1554. /**
  1555. * retrieves the current format of the form
  1556. *
  1557. * @access public
  1558. * @return string $format The current form format
  1559. * @see setFormat()
  1560. * @see format
  1561. */
  1562. function getFormat()
  1563. {
  1564. return $this->format;
  1565. }
  1566. /**
  1567. * retrieves the current method of the form
  1568. *
  1569. * @access public
  1570. * @return string $method The request method
  1571. * @see setMethod()
  1572. */
  1573. function getMethod()
  1574. {
  1575. return $this->getAttribute( 'method' );
  1576. }
  1577. /**
  1578. * retrieves the current action of the form
  1579. *
  1580. * @access public
  1581. * @return string $action Action of the form
  1582. * @see setAction()
  1583. */
  1584. function getAction()
  1585. {
  1586. $action = $this->getAttribute( 'action' );
  1587. if ( !empty( $action ) )
  1588. return $action;
  1589. return $_SERVER['PHP_SELF'];
  1590. }
  1591. /**
  1592. * adds an atribute to the form's attribute collection. If the attribute
  1593. * already exists, it is overwritten.
  1594. *
  1595. * @access public
  1596. * @param string $attributeName The name of the attribute to add
  1597. * @param string $atributeValue The value of the attribute
  1598. */
  1599. function setAttribute( $attributeName, $attributeValue )
  1600. {
  1601. if ( !isset( $this->attributeDefinition[$attributeName] ) )
  1602. {
  1603. patErrorManager::raiseNotice(
  1604. PATFORMS_NOTICE_ATTRIBUTE_NOT_SUPPORTED,
  1605. "The attribute '".$attributeName."' is not supported by the form, skipped it. [".get_class( $this )."]"
  1606. );
  1607. return true;
  1608. }
  1609. $this->attributes[$attributeName] = $attributeValue;
  1610. return true;
  1611. }
  1612. /**
  1613. * adds several attributes at once to the form's attribute collection.
  1614. * Any existing attributes will be overwritten.
  1615. *
  1616. * @access public
  1617. * @param array $attributes The attributes to add
  1618. * @see setAttribute()
  1619. */
  1620. function setAttributes( $attributes )
  1621. {
  1622. if ( !is_array( $attributes ) )
  1623. {
  1624. return patErrorManager::raiseError(
  1625. PATFORMS_NOTICE_ARRAY_EXPECTED,
  1626. "setAttributes: array expected"
  1627. );
  1628. }
  1629. foreach ( $attributes as $attributeName => $attributeValue )
  1630. {
  1631. $this->setAttribute( $attributeName, $attributeValue );
  1632. }
  1633. return true;
  1634. }
  1635. /**
  1636. * retrieves the value of a form attribute.
  1637. *
  1638. * @access public
  1639. * @param string $attribute The name of the attribute to retrieve
  1640. * @return mixed $attributeValue The value of the attribute, or false if it does not exist in the attributes collection.
  1641. * @see setAttribute()
  1642. */
  1643. function getAttribute( $attribute )
  1644. {
  1645. if ( !isset( $this->attributes[$attribute] ) )
  1646. {
  1647. return false;
  1648. }
  1649. return $this->attributes[$attribute];
  1650. }
  1651. /**
  1652. * retrieves all attributes of the form, or only the specified attributes.
  1653. *
  1654. * @access public
  1655. * @param array $attributes Optional: The names of the attributes to retrieve. Only the attributes that exist will be returned.
  1656. * @return array $result The attributes
  1657. * @see getAttribute()
  1658. */
  1659. function getAttributes( $attributes = array() )
  1660. {
  1661. if ( empty( $attributes ) )
  1662. {
  1663. return $this->attributes;
  1664. }
  1665. $result = array();
  1666. foreach ( $attributes as $attribute )
  1667. {
  1668. if ( $attributeValue = $this->getAttribute( $attribute ) )
  1669. {
  1670. $result[$attribute] = $attributeValue;
  1671. }
  1672. }
  1673. return $result;
  1674. }
  1675. /**
  1676. * Loads the default attribute values into the attributes collection. Done directly
  1677. * on startup (in the consructor).
  1678. *
  1679. * The action defaults to the path of the current script, with session
  1680. * ID appended automatically, if SID has been defined.
  1681. *
  1682. * @access public
  1683. * @return bool $success Always returns true.
  1684. * @see $attributeDefaults
  1685. */
  1686. function loadAttributeDefaults()
  1687. {
  1688. foreach ( $this->attributeDefinition as $attributeName => $attributeDef )
  1689. {
  1690. if ( isset( $attributeDef['default'] ) )
  1691. {
  1692. $this->attributes[$attributeName] = $attributeDef['default'];
  1693. }
  1694. if ( $attributeName == 'action' )
  1695. {
  1696. $this->attributes[$attributeName] = $_SERVER['PHP_SELF'];
  1697. /**
  1698. * session has been started, append session ID
  1699. */
  1700. if ( defined( 'SID' ) )
  1701. $this->attributes[$attributeName] .= '?' . SID;
  1702. }
  1703. }
  1704. return true;
  1705. }
  1706. /**
  1707. * retrieves the form's current submitted state.
  1708. *
  1709. * If autoValidate is used, it will check for the submitVar and
  1710. * set the submitted flag accordingly
  1711. *
  1712. * @access public
  1713. * @return bool $state True if it has been submitted, false otherwise.
  1714. * @see setSubmitted(), setAutoValidate()
  1715. * @see submitted
  1716. */
  1717. function isSubmitted()
  1718. {
  1719. if ( $this->submitted === true )
  1720. {
  1721. return true;
  1722. }
  1723. if ( !isset( $this->submitVar ) )
  1724. {
  1725. return false;
  1726. }
  1727. if ( !$this->autoValidate )
  1728. {
  1729. return false;
  1730. }
  1731. if ( isset( $_GET[$this->submitVar] ) || isset( $_POST[$this->submitVar] ) )
  1732. {
  1733. $this->setSubmitted( true );
  1734. }
  1735. return $this->submitted;
  1736. }
  1737. /**
  1738. * Creates a new patForms_Creator object
  1739. *
  1740. * @static
  1741. * @access public
  1742. * @return object $creator The creator object, or a patError object on failure
  1743. */
  1744. function createCreator( $type )
  1745. {
  1746. return patForms::_createModule( 'Creator', $type );
  1747. }
  1748. /**
  1749. * get the element name of the form
  1750. *
  1751. * @access public
  1752. * @return string name of the form
  1753. */
  1754. function getElementName()
  1755. {
  1756. return $this->elementName;
  1757. }
  1758. /**
  1759. * get next error offset
  1760. *
  1761. * @access public
  1762. * @return integer
  1763. */
  1764. function getErrorOffset( $requiredCodes = 100 )
  1765. {
  1766. $offset = $this->nextErrorOffset;
  1767. $this->nextErrorOffset = $this->nextErrorOffset + $requiredCodes;
  1768. return $offset;
  1769. }
  1770. /**
  1771. * add error codes and messages for validator method
  1772. *
  1773. * @access public
  1774. * @param array defintions
  1775. * @param integer offset for the error codes
  1776. */
  1777. function addValidatorErrorCodes( $defs, $offset = 1000 )
  1778. {
  1779. foreach ( $defs as $lang => $codes )
  1780. {
  1781. if ( !isset( $this->validatorErrorCodes[$lang] ) )
  1782. {
  1783. $this->validatorErrorCodes[$lang] = array();
  1784. }
  1785. foreach ( $codes as $code => $message )
  1786. {
  1787. $this->validatorErrorCodes[$lang][($offset+$code)] = $message;
  1788. }
  1789. }
  1790. }
  1791. /**
  1792. * add a validation error to the whole form
  1793. *
  1794. * This can be achieved by adding a validation rule to the form.
  1795. *
  1796. * @access public
  1797. * @param integer $code
  1798. * @param array $vars fill named placeholder with value…

Large files files are truncated, but you can click here to view the full file