PageRenderTime 49ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/inc/patForms/Element.php

https://github.com/chregu/fluxcms
PHP | 1981 lines | 920 code | 211 blank | 850 comment | 115 complexity | e2b4b6cd58974df8abcdc8226ae5f713 MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause, Apache-2.0, LGPL-2.1
  1. <?php
  2. /**
  3. * base patForms element class with all needed base functionality that each element
  4. * should have.
  5. *
  6. * $Id$
  7. *
  8. * @package patForms
  9. * @subpackage patForms_Element
  10. * @access protected
  11. * @author Sebastian Mordziol <argh@php-tools.net>
  12. * @author gERD Schaufelberger <gerd@php-tools.net>
  13. * @author Stephan Schmidt <schst@php-tools.net>
  14. */
  15. /**
  16. * error definition: the attribute that was set is not supported by this element (it is
  17. * not listed in the attributeDefinition property set in the element class).
  18. * @see patForms_Element::attributeDefinition
  19. */
  20. define( "PATFORMS_ELEMENT_NOTICE_ATTRIBUTE_NOT_SUPPORTED", 1101 );
  21. /**
  22. * error definition: the setAttributes() method expects an array,
  23. * but given value was not.
  24. * @see patForms_Element::setAttributes()
  25. */
  26. define( "PATFORMS_ELEMENT_ERROR_ARRAY_EXPECTED", 1102 );
  27. /**
  28. * error definition: the given attribute could not be set
  29. */
  30. define( "PATFORMS_ELEMENT_ERROR_ADDING_ATTRIBUTE_FAILED", 1103 );
  31. /**
  32. * error definition: the element method to serialize the element in the given mode is
  33. * not implemented.
  34. * @see patForms_Element::serialize()
  35. */
  36. define( "PATFORMS_ELEMENT_ERROR_METHOD_FOR_MODE_NOT_AVAILABLE", 1104 );
  37. /**
  38. * error definition: the element returned an error
  39. */
  40. define( "PATFORMS_ELEMENT_ERROR_ERROR_RETURNED", 1105 );
  41. /**
  42. * error definition: the utility class {@link patForms_FormatChecker} could not be found, this is
  43. * needed for the format validation of certain variable types.
  44. * @see patForms_FormatChecker
  45. * @see patForms_Element::validateFormat()
  46. */
  47. define( "PATFORMS_ELEMENT_ERROR_FORMAT_CHECKER_NOT_FOUND", 1106 );
  48. /**
  49. * error definition: the modifier that was set for the element is not an array.
  50. * @see patForms_Element::_applyModifiers()
  51. */
  52. define( "PATFORMS_ELEMENT_ERROR_MODIFIER_NOT_AN_ARRAY", 1107 );
  53. /**
  54. * error definition: the method for the given modifier does not exist
  55. * @see patForms_Element::_applyModifiers()
  56. */
  57. define( "PATFORMS_ELEMENT_ERROR_METHOD_FOR_MODIFIER_NOT_FOUND", 1108 );
  58. /**
  59. * error definition: the modifier returned an error, modifications could not be made.
  60. * @see patForms_Element::_applyModifiers()
  61. */
  62. define( "PATFORMS_ELEMENT_ERROR_MODIFIER_RETURNED_ERROR", 1109 );
  63. /**
  64. * error definition: the given attribute is required for the specified output format.
  65. * @see patForms_Element::getAttributesFor()
  66. */
  67. define( "PATFORMS_ELEMENT_ERROR_ATTRIBUTE_REQUIRED", 1110 );
  68. /**
  69. * error definition: given modifier could not be applied to specified attribute
  70. * @see patForms_Element::getAttributesFor()
  71. */
  72. define( "PATFORMS_ELEMENT_ERROR_UNABLE_TO_APPLY_MODIFIER_TO_ATTRIBUTE", 1111 );
  73. /**
  74. * error definition: the given attribute is not available for output in the specified
  75. * output format.
  76. * @see patForms_Element::getAttributesFor()
  77. */
  78. define( "PATFORMS_ELEMENT_ERROR_ATTRIBUTE_NOT_AVAILABLE_FOR_OUTPUT", 1112 );
  79. /**
  80. * error definition: format of the attribute could not be verified
  81. * @see patForms_Element::getAttributesFor()
  82. */
  83. define( "PATFORMS_ELEMENT_ERROR_CAN_NOT_VERIFY_FORMAT", 1113 );
  84. /**
  85. * error definition: the attribute collection of the element could not be validated.
  86. * @see patForms_Element::toHtml()
  87. */
  88. define( "PATFORMS_ELEMENT_ERROR_CAN_NOT_VALIDATE_ATTRIBUTE_COLLECTION", 1114 );
  89. /**
  90. * error definition: validator undefined
  91. */
  92. define( "PATFORMS_ELEMENT_ERROR_VALIDATOR_ERROR_UNDEFINED", 1115 );
  93. /**
  94. * error definition: undefined locale for errors output
  95. */
  96. define( "PATFORMS_ELEMENT_ERROR_VALIDATOR_ERROR_LOCALE_UNDEFINED", 1116 );
  97. /**
  98. * error definition: the html source for the element could not be generated.
  99. */
  100. define( "PATFORMS_ELEMENT_ERROR_NO_HTML_CONTENT", 1221 );
  101. /**
  102. * error definition: not a valid renderer
  103. */
  104. define( 'PATFORMS_ELEMENT_ERROR_INVALID_RENDERER', 1222 );
  105. /**
  106. * error definition: this element does not support the use of a renderer
  107. */
  108. define( 'PATFORMS_ELEMENT_RENDERER_NOT_SUPPORTED', 1223 );
  109. /**
  110. * filter is located between patForms and browser
  111. */
  112. define( 'PATFORMS_FILTER_TYPE_HTTP', 1 );
  113. /**
  114. * filter is located between patForms and the PHP script
  115. */
  116. define( 'PATFORMS_FILTER_TYPE_PHP', 2 );
  117. /**
  118. * base patForms element class with all needed base functionality that each element
  119. * should have. Extend this class to create your own elements.
  120. *
  121. * $Id$
  122. *
  123. * @abstract
  124. * @package patForms
  125. * @subpackage patForms_Element
  126. * @access protected
  127. * @version 0.1
  128. * @author Sebastian Mordziol <argh@php-tools.net>
  129. * @author gERD Schaufelberger <gerd@php-tools.net>
  130. * @author Stephan Schmidt <schst@php-tools.net>
  131. * @license LGPL, see license.txt for details
  132. * @link http://www.php-tools.net
  133. */
  134. class patForms_Element
  135. {
  136. /**
  137. * the type of the element, set this in your element class!
  138. * @access protected
  139. */
  140. var $elementType = false;
  141. /**
  142. * javascript that will be displayed only once
  143. *
  144. * @access private
  145. * @var array
  146. */
  147. var $globalJavascript = array();
  148. /**
  149. * javascript that will be displayed once per instance
  150. *
  151. * @access private
  152. * @var array
  153. */
  154. var $instanceJavascript = array();
  155. /**
  156. * the value of the element
  157. * @access protected
  158. */
  159. var $value = false;
  160. /**
  161. * filters that have been applied
  162. * @access private
  163. */
  164. var $filters = array();
  165. /**
  166. * observers that have been attached
  167. *
  168. * @access private
  169. * @var array
  170. */
  171. var $observers = array();
  172. /**
  173. * The elementName for the serialized version of the element
  174. *
  175. * This is needed for the toXML() method and also by the patForms
  176. * error management. If it is not set, the element name will be
  177. * created by extracting everything after the last underscore in
  178. * the classname.
  179. *
  180. * @access protected
  181. * @see toXML()
  182. */
  183. var $elementName = null;
  184. /**
  185. * the attribute collection of the element
  186. * @access private
  187. * @see setAttribute()
  188. * @see setAttributes()
  189. * @see getAttribute()
  190. * @see getAttributes()
  191. */
  192. var $attributes = array();
  193. /**
  194. * the configuration for the attributes supported by the element. Overwrite this
  195. * in your element class.
  196. *
  197. * @abstract
  198. */
  199. var $attributeDefinition = array();
  200. /**
  201. * Stores the attribute defaults for the element, that will be used
  202. * if the given attributes have not been set by the user.
  203. *
  204. * @abstract
  205. * @access private
  206. * @see getAttributeDefaults()
  207. */
  208. var $attributeDefaults = array();
  209. /**
  210. * stores the mode for the element. It defaults to 'default', and is only overwritten if
  211. * set specifically.
  212. *
  213. * @access protected
  214. * @see setMode()
  215. */
  216. var $mode = "default";
  217. /**
  218. * stores the format for the element. It defaults to 'html', and is only overwritten if
  219. * set specifically.
  220. *
  221. * @access protected
  222. * @see setFormat()
  223. */
  224. var $format = "html";
  225. /**
  226. * stores the locale to use when adding validation errors. The specified locale has
  227. * to be set in the validationErrorCodes element class property, otherwise the default
  228. * 'C' (as in the programming language C => english) will be used.
  229. *
  230. * @access private
  231. * @var string $locale
  232. * @see setLocale()
  233. */
  234. var $locale = "C";
  235. /**
  236. * stores the flag telling the element whether it has been submitted - this is used by the
  237. * getValue() method to determine where to get the element's value from.
  238. * @access protected
  239. * @see getValue()
  240. */
  241. var $submitted = false;
  242. /**
  243. * stores the flag whether the element is valid
  244. * @access protected
  245. */
  246. var $valid = true;
  247. /**
  248. * stores any validation errors that can occurr during the element's validation process.
  249. *
  250. * @access private
  251. * @var array $validationErrors
  252. */
  253. var $validationErrors = array();
  254. /**
  255. * define error codes an messages for each form element
  256. *
  257. * @access protected
  258. * @var array $validatorErrorCodes
  259. */
  260. var $validatorErrorCodes = array();
  261. /**
  262. * defines the starting character for the modifier placeholders that can be inserted
  263. * in the attributes listed as having modifier support.
  264. *
  265. * @access private
  266. * @var string $modifierStart
  267. */
  268. var $modifierStart = "[";
  269. /**
  270. * defines the starting character for the modifier placeholders that can be inserted
  271. * in the attributes listed as having modifier support.
  272. *
  273. * @access private
  274. * @var string $modifierStart
  275. */
  276. var $modifierEnd = "]";
  277. /**
  278. * XML entities
  279. *
  280. * @access protected
  281. * @see toXML()
  282. */
  283. var $xmlEntities = array(
  284. "<" => "&lt;",
  285. ">" => "&gt;",
  286. "&" => "&amp;",
  287. "'" => "&apos;",
  288. '"' => "&quot;"
  289. );
  290. /**
  291. * shortcur to the session variables
  292. * If "false", no session will be used, otherwise it stores the session variables for this element
  293. *
  294. * @access private
  295. * @var mixed $sessionVar
  296. */
  297. var $sessionVar = false;
  298. /**
  299. * custom validation rules
  300. *
  301. * @access private
  302. * @var array
  303. */
  304. var $_rules = array();
  305. /**
  306. * next error offset for rules
  307. * @access private
  308. * @var integer
  309. */
  310. var $nextErrorOffset = 1000;
  311. /**
  312. * stores whether the element uses a renderer to serialize its content
  313. * @access private
  314. * @var bool
  315. */
  316. var $usesRenderer = false;
  317. /**
  318. * Stores the renderer object that can be set via the setRenderer method
  319. * @access private
  320. * @var object
  321. */
  322. var $renderer = false;
  323. /**
  324. * Stores all element options
  325. * @access private
  326. */
  327. var $options = array();
  328. /**
  329. * constructor - extend this in your class if you need to do specific operations
  330. * on startup. In that case, however, don't forget to call this constructor anyway
  331. * so that the thing happening here don't get lost.
  332. *
  333. * That's easy to do... just add the following line in your constructor:
  334. * parent::patForms_Element();
  335. *
  336. * @access public
  337. * @param mixed $mode Optional: the output format, e.g. 'html'
  338. */
  339. function __construct( $format = false )
  340. {
  341. if( $format !== false )
  342. {
  343. $this->format = $format;
  344. }
  345. $this->loadAttributeDefaults();
  346. }
  347. /**
  348. * patForms_Element constructor for php4
  349. *
  350. * @access private
  351. * @param integer $id
  352. * @return boolean $result true on success
  353. * @see __construct
  354. */
  355. function patForms_Element( $format = false )
  356. {
  357. $this->__construct( $format );
  358. }
  359. /**
  360. * Add any initialization routines for your element in your element class,
  361. * for everythig your element needs to do after it has been instantiated and
  362. * the attribute collection has been created.
  363. *
  364. * @abstract
  365. * @access private
  366. * @return mixed $success True on success, a patError object otherwise
  367. */
  368. function _init()
  369. {
  370. // your code here
  371. return true;
  372. }
  373. /**
  374. * sets the format of the element - this defines which method will be called in your
  375. * element class, along with the {@link mode} property.
  376. *
  377. * @access public
  378. * @param string $format The name of the format you have implemented in your element(s). Default is 'html'
  379. * @see setFormat()
  380. * @see format
  381. * @see serialize()
  382. */
  383. function setFormat( $format )
  384. {
  385. $this->format = strtolower( $format );
  386. }
  387. /**
  388. * sets the mode of the element that defines which methods will be called in your
  389. * element class, along with the {@link format} property.
  390. *
  391. * @access public
  392. * @param string $mode The mode to set the element to: default|readonly or any other mode you have implemented in your element class(es). Default is 'default'.
  393. * @see setFormat()
  394. * @see mode
  395. * @see serialize()
  396. */
  397. function setMode( $mode )
  398. {
  399. $this->mode = strtolower( $mode );
  400. }
  401. /**
  402. * sets the locale (language) to use for the validation error messages of the form.
  403. *
  404. * @access public
  405. * @param string $lang
  406. * @return bool $result True on success
  407. * @see $locale
  408. */
  409. function setLocale( $lang )
  410. {
  411. $this->locale = $lang;
  412. // check, whether this is a custom locale
  413. if (patForms::isCustomLocale($lang)) {
  414. $errorMessages = patForms::getCustomLocale($lang, 'Element::' . $this->elementName);
  415. if (is_array($errorMessages)) {
  416. $this->validatorErrorCodes[$lang] = $errorMessages;
  417. }
  418. }
  419. return true;
  420. }
  421. /**
  422. * sets the value of the element, which will be used to fill the element with. If none is
  423. * set and the element needs a value, it will load it using the {@link resolveValue()} method.
  424. *
  425. * This will override user input.
  426. *
  427. * @access public
  428. * @param mixed $value The value to set
  429. * @see $value
  430. * @see resolveValue()
  431. * @see getValue()
  432. */
  433. function setValue( $value )
  434. {
  435. $value = $this->_applyFilters( $value, 'in', PATFORMS_FILTER_TYPE_PHP );
  436. $this->value = $value;
  437. }
  438. /**
  439. * sets the default value of the element, which will be used to fill the element with.
  440. *
  441. * @access public
  442. * @param mixed $value The value to set
  443. * @see $value
  444. * @see resolveValue()
  445. * @see setValue()
  446. * @see getValue()
  447. */
  448. function setDefaultValue( $value )
  449. {
  450. $this->setAttribute('default', $value);
  451. }
  452. /**
  453. * sets the current submitted state of the element. Set this to true if you want the element
  454. * to pick up its submitted data.
  455. *
  456. * @access public
  457. * @param bool $state True if it has been submitted, false otherwise (default).
  458. * @see getSubmitted()
  459. * @see $submitted
  460. */
  461. function setSubmitted( $state )
  462. {
  463. $this->submitted = $state;
  464. }
  465. /**
  466. * sets the internal ID of the element - this is only used by the {@link patForms} class to
  467. * give each element a unique ID that will be added as ID attribute to each element if the
  468. * id attribute has not been defined.
  469. *
  470. * @access public
  471. * @param string $id The id to set for the element
  472. * @see getId()
  473. */
  474. function setId( $id )
  475. {
  476. $this->attributes['id'] = $id;
  477. }
  478. /**
  479. * gets the internal ID of the element
  480. *
  481. * @access public
  482. * @return string $id The id to set for the element
  483. * @see setId()
  484. */
  485. function getId()
  486. {
  487. return $this->getAttribute( 'id' );
  488. }
  489. /**
  490. * checks whether a given attribute is supported by this element.
  491. *
  492. * @access public
  493. * @param string $attributeName The name of the attribute to check
  494. * @return bool $hasAttribute True if it supports the attribute, false otherwise.
  495. */
  496. function hasAttribute( $attributeName )
  497. {
  498. if( isset( $this->attributeDefinition[$attributeName] ) )
  499. {
  500. return true;
  501. }
  502. return false;
  503. }
  504. /**
  505. * adds an attribute to the element's attribut3 collection. If the attribute
  506. * already exists, it is overwritten.
  507. *
  508. * @access public
  509. * @param string $attributeName The name of the attribute to add
  510. * @param string $attributeValue The value of the attribute
  511. * @return mixed $success True on success, a patError object otherwise
  512. */
  513. function setAttribute( $attributeName, $attributeValue )
  514. {
  515. if( !isset( $this->attributeDefinition[$attributeName] ) )
  516. {
  517. return patErrorManager::raiseNotice(
  518. PATFORMS_ELEMENT_NOTICE_ATTRIBUTE_NOT_SUPPORTED,
  519. 'Unknown attribute ['.$attributeName.']',
  520. 'Ignored the attribute as the ['.$this->elementName.'] element does not support it.'
  521. );
  522. }
  523. $this->attributes[$attributeName] = $attributeValue;
  524. switch( $this->attributeDefinition[$attributeName]["format"] ) {
  525. case 'array':
  526. $this->attributes[$attributeName] = split(' ',$attributeValue);
  527. break;
  528. case 'boolean':
  529. switch( $attributeValue ) {
  530. case "1":
  531. case "true":
  532. case "t":
  533. $this->attributes[$attributeName] = true;
  534. break;
  535. case "0":
  536. case "no":
  537. case "false":
  538. case "nil":
  539. $this->attributes[$attributeName] = false;
  540. break;
  541. default:
  542. $this->attributes[$attributeName] = null;
  543. break;
  544. }
  545. case 'int':
  546. case 'string':
  547. $this->attributes[$attributeName] = $attributeValue;
  548. default:
  549. return false;
  550. }
  551. return true;
  552. }
  553. /**
  554. * adds several attribute at once to the element's attributes collection.
  555. * Any existing attributes will be overwritten.
  556. *
  557. * @access public
  558. * @param array $attributes The attributes to add
  559. * @return mixed $success True on success, false otherwise
  560. */
  561. function setAttributes( $attributes )
  562. {
  563. if( !is_array( $attributes ) )
  564. {
  565. return patErrorManager::raiseError(
  566. PATFORMS_ELEMENT_ERROR_ARRAY_EXPECTED,
  567. "Not an array given (setAttributes)"
  568. );
  569. }
  570. foreach( $attributes as $attributeName => $attributeValue )
  571. {
  572. $this->setAttribute( $attributeName, $attributeValue );
  573. }
  574. return true;
  575. }
  576. /**
  577. * sets a renderer object that will be used to render
  578. * the element. Use the serialize() method to retrieve
  579. * the rendered content of the element.
  580. *
  581. * Only enabled in elements that support renderers, like
  582. * the radio element.
  583. *
  584. * @access public
  585. * @param object &$renderer The renderer object
  586. */
  587. function setRenderer( &$renderer )
  588. {
  589. if( !$this->usesRenderer )
  590. {
  591. return patErrorManager::raiseWarning(
  592. PATFORMS_ELEMENT_RENDERER_NOT_SUPPORTED,
  593. 'The element \''.$this->elementName.'\' does not support the use of renderers - you do not have to set a renderer for this element.'
  594. );
  595. }
  596. if( !is_object( $renderer ) )
  597. {
  598. return patErrorManager::raiseError(
  599. PATFORMS_ELEMENT_ERROR_INVALID_RENDERER,
  600. 'You can only set a patForms_Renderer object with the setRenderer() method, "'.gettype( $renderer ).'" given.'
  601. );
  602. }
  603. $this->renderer = &$renderer;
  604. }
  605. /**
  606. * retrieves the value of an attribute.
  607. *
  608. * @access public
  609. * @param string $attribute The name of the attribute to retrieve
  610. * @return mixed $attributeValue The value of the attribute, or false if it does not exist in the attributes collection.
  611. * @see setAttribute()
  612. */
  613. function getAttribute( $attribute )
  614. {
  615. if( !isset( $this->attributes[$attribute] ) )
  616. {
  617. return false;
  618. }
  619. return $this->attributes[$attribute];
  620. }
  621. /**
  622. * retrieves all attributes, or only the specified attributes.
  623. *
  624. * @access public
  625. * @param array $attributes Optional: The names of the attributes to retrieve. Only the attributes that exist will be returned.
  626. * @return array $result The attributes
  627. * @see getAttribute()
  628. */
  629. function getAttributes( $attributes = array() )
  630. {
  631. if( empty( $attributes ) )
  632. {
  633. return $this->attributes;
  634. }
  635. $result = array();
  636. foreach( $attributes as $attribute )
  637. {
  638. if( $attributeValue = $this->getAttribute( $attribute ) )
  639. {
  640. $result[$attribute] = $attributeValue;
  641. }
  642. }
  643. return $result;
  644. }
  645. /**
  646. * Loads the default attribute values into the attributes collection. Done directly
  647. * on startup (in the consructor), so make sure you call this if your element needs
  648. * this feature and you have implemented a custom constructor in your element.
  649. *
  650. * @access public
  651. * @return bool $success Always returns true.
  652. * @see $attributeDefaults
  653. */
  654. function loadAttributeDefaults()
  655. {
  656. foreach( $this->attributeDefinition as $attributeName => $attributeDef )
  657. {
  658. if( isset( $attributeDef['default'] ) )
  659. {
  660. $this->attributes[$attributeName] = $attributeDef['default'];
  661. }
  662. }
  663. return true;
  664. }
  665. /**
  666. * retrieves the current value of the element. If none is set, will try to retrieve the
  667. * value from submitted form data.
  668. *
  669. * @access public
  670. * @param boolean Determines whether the method is used from an external script
  671. * @return mixed The value, or an empty string if none found.
  672. * @see setValue()
  673. * @see value
  674. * @see resolveValue()
  675. */
  676. function getValue( $external = true )
  677. {
  678. if( $this->value === false )
  679. {
  680. $this->resolveValue();
  681. // could not be resolved
  682. if( $this->value === false )
  683. {
  684. $value = '';
  685. }
  686. else
  687. {
  688. $value = $this->value;
  689. }
  690. }
  691. else
  692. {
  693. $value = $this->value;
  694. }
  695. if( $external === false )
  696. {
  697. return $value;
  698. }
  699. $value = $this->_applyFilters( $value, 'out', PATFORMS_FILTER_TYPE_PHP );
  700. return $value;
  701. }
  702. /**
  703. * resolves the scope the value of the element may be stored in, and returns it.
  704. *
  705. * @access protected
  706. * @see getValue()
  707. * @see value
  708. * @todo parse element name, if it uses the array syntax
  709. */
  710. function resolveValue()
  711. {
  712. $varName = $this->attributes['name'];
  713. if( $this->submitted && isset( $_POST[$varName] ) )
  714. {
  715. $this->value = $_POST[$varName];
  716. $this->_filterHttpValue();
  717. return true;
  718. }
  719. if( $this->submitted && isset( $_GET[$varName] ) )
  720. {
  721. $this->value = $_GET[$varName];
  722. $this->_filterHttpValue();
  723. return true;
  724. }
  725. if( isset( $this->attributes['default'] ) )
  726. {
  727. $this->value = $this->attributes['default'];
  728. $this->value = $this->_applyFilters( $this->value, 'in', PATFORMS_FILTER_TYPE_PHP );
  729. return true;
  730. }
  731. return true;
  732. }
  733. /**
  734. * recursively strip slashes
  735. *
  736. * This method is used to 'fix' magic_quotes_gpc.
  737. *
  738. * @access public
  739. * @param mixed user input (get or post)
  740. * @return mixed data with slashes stripped
  741. */
  742. function rStripSlashes( $value )
  743. {
  744. if( is_scalar( $value ) )
  745. return stripslashes( $value );
  746. if( is_array( $value ) )
  747. {
  748. foreach( $value as $key => $val )
  749. {
  750. $value[$key] = $this->rStripSlashes( $val );
  751. }
  752. }
  753. return $value;
  754. }
  755. /**
  756. * apply filters to a value
  757. *
  758. * @access private
  759. * @param mixed value
  760. * @param string direction of the filter ('in' or 'out')
  761. * @param integer type of filters to apply
  762. * @return mixed filtered value
  763. */
  764. function _applyFilters( $value, $dir = 'in', $type = PATFORMS_FILTER_TYPE_PHP )
  765. {
  766. if( empty( $this->filters ) )
  767. return $value;
  768. /**
  769. * apply filters!
  770. */
  771. $cnt = count( $this->filters );
  772. for( $i = 0; $i < $cnt; $i++ )
  773. {
  774. /**
  775. * check, whether filter is located between php script and form
  776. */
  777. if( $this->filters[$i]->getType() != $type )
  778. {
  779. continue;
  780. }
  781. $value = $this->filters[$i]->$dir( $value );
  782. }
  783. return $value;
  784. }
  785. /**
  786. * retrieves the current mode of the element
  787. *
  788. * @access public
  789. * @return string $mode The current element mode
  790. * @see setMode()
  791. * @see mode
  792. */
  793. function getMode()
  794. {
  795. return $this->mode;
  796. }
  797. /**
  798. * retrieves the current format of the element
  799. *
  800. * @access public
  801. * @return string $format The current element format
  802. * @see setFormat()
  803. * @see format
  804. */
  805. function getFormat()
  806. {
  807. return $this->format;
  808. }
  809. /**
  810. * retrieves the element's current submitted state.
  811. *
  812. * @access public
  813. * @return bool $state True if it has been submitted, false otherwise.
  814. * @see setSubmitted()
  815. * @see submitted
  816. */
  817. function getSubmitted()
  818. {
  819. return $this->submitted;
  820. }
  821. /**
  822. * retrieves the name of the element
  823. *
  824. * @access public
  825. * @return string $name name of the element
  826. * @uses getAttribute()
  827. */
  828. function getName()
  829. {
  830. return $this->getAttribute( 'name' );
  831. }
  832. /**
  833. * add a custom validation rule
  834. *
  835. * @access public
  836. * @param object patForms_Rule validation rule
  837. * @param integer time, when rule has to be applied, can be before or after validation.
  838. * If set to null, it will use the default value as specified in the rule
  839. * @return boolean currently always true
  840. */
  841. function addRule( &$rule, $time = null )
  842. {
  843. if( is_null( $time ) )
  844. {
  845. $time = $rule->getTime();
  846. }
  847. $rule->prepareRule( $this );
  848. $this->_rules[] = array(
  849. 'rule' => &$rule,
  850. 'time' => $time,
  851. );
  852. return true;
  853. }
  854. /**
  855. * adds an observer to the element
  856. *
  857. * @access public
  858. * @param object patForms_Observer observer
  859. * @return boolean currently always true
  860. */
  861. function attachObserver( &$observer )
  862. {
  863. $this->observers[] = &$observer;
  864. return true;
  865. }
  866. /**
  867. * dispatches the serialization of the element in the format that was set to the
  868. * corresponding method in the element class. These methods must be named in the
  869. * folowing scheme:
  870. *
  871. * serialize[format][mode](), e.g. serializeHtmlDefault()
  872. *
  873. * @access public
  874. * @return string $element The created element according to the specified mode.
  875. * @see setFormat()
  876. * @see setMode()
  877. * @todo serialize*() methods should return a patError object instead of false!!!!
  878. * Has to be changed asap!
  879. */
  880. function serialize()
  881. {
  882. $methodName = "serialize".ucfirst( $this->getFormat() ).ucfirst( $this->getMode() );
  883. if( !method_exists( $this, $methodName ) )
  884. {
  885. return patErrorManager::raiseError(
  886. PATFORMS_ELEMENT_ERROR_METHOD_FOR_MODE_NOT_AVAILABLE,
  887. "Element method for form mode '".$this->getMode()."' (".$methodName.") is not available."
  888. );
  889. }
  890. /**
  891. * get the value for internal use
  892. * The PHP-filters will not be applied
  893. */
  894. $value = $this->getValue( false );
  895. $element = $this->$methodName( $value );
  896. if( patErrorManager::isError( $element ) )
  897. {
  898. return $element;
  899. }
  900. return $element;
  901. }
  902. /**
  903. * Template method that applies rules and calls the elements
  904. * validation method
  905. *
  906. * @final
  907. * @access public
  908. * @return bool $success True on success, false otherwise
  909. */
  910. function validate()
  911. {
  912. // apply locale, if the current locale is a custom locale
  913. if (patForms::isCustomLocale($this->locale)) {
  914. $cnt = count( $this->_rules );
  915. for( $i = 0; $i < $cnt; $i++ ) {
  916. $this->_rules[$i]['rule']->setLocale($this->locale);
  917. }
  918. }
  919. /**
  920. * validate custom rules
  921. */
  922. if( !$this->_applyRules( PATFORMS_RULE_BEFORE_VALIDATION ) )
  923. {
  924. $this->_announce( 'status', 'error' );
  925. return false;
  926. }
  927. /**
  928. * the the unfiltered value
  929. */
  930. $value = $this->getValue( false );
  931. $valid = $this->validateElement( $value );
  932. if( $valid === false )
  933. {
  934. $this->_announce( 'status', 'error' );
  935. return false;
  936. }
  937. /**
  938. * validate custom rules
  939. */
  940. if( !$this->_applyRules( PATFORMS_RULE_AFTER_VALIDATION ) )
  941. {
  942. $this->_announce( 'status', 'error' );
  943. return false;
  944. }
  945. $this->_announce( 'status', 'validated' );
  946. return true;
  947. }
  948. /**
  949. * validates the given data with the element's validation routines
  950. * and returns the data with any needed modifications.
  951. *
  952. * @abstract
  953. * @access private
  954. * @return bool $success True on success, false otherwise
  955. */
  956. function validateElement($value)
  957. {
  958. // your code here
  959. return true;
  960. }
  961. /**
  962. * apply rules
  963. *
  964. * @access private
  965. * @param integer time of validation
  966. * @return boolean rules are valid or not
  967. * @todo add documentation
  968. */
  969. function _applyRules( $time )
  970. {
  971. $valid = true;
  972. $cnt = count( $this->_rules );
  973. for( $i = 0; $i < $cnt; $i++ )
  974. {
  975. if( ( $this->_rules[$i]['time'] & $time ) != $time )
  976. continue;
  977. $result = $this->_rules[$i]['rule']->applyRule( $this, $time );
  978. if( $result === false )
  979. {
  980. $valid = false;
  981. }
  982. }
  983. return $valid;
  984. }
  985. /**
  986. * finalize the element.
  987. *
  988. * Used as a template method.
  989. *
  990. * @final
  991. * @access protected
  992. * @return bool $success True on success, false otherwise
  993. * @uses finalizeElement() to call the user code
  994. */
  995. function finalize()
  996. {
  997. $value = $this->getValue( false );
  998. return $this->finalizeElement( $value );
  999. }
  1000. /**
  1001. * finalize the element
  1002. *
  1003. * Offers the possibility to process any needed operations after the element
  1004. * has been validated. Implement any tasks that you need to do then here - a
  1005. * good example is the File element, where this method enables the moving of
  1006. * the uploaded file to the correct location.
  1007. *
  1008. * @abstract
  1009. * @access private
  1010. * @param mixed value of the element
  1011. * @return bool $success True on success, false otherwise
  1012. */
  1013. function finalizeElement( $value )
  1014. {
  1015. return true;
  1016. }
  1017. /**
  1018. * Enables an element option.
  1019. *
  1020. * See the {@link patForms::$options} property for an exhaustive list of available options.
  1021. *
  1022. * @access public
  1023. * @param string $option The option to enable
  1024. * @param array $params Optional parameters for the option
  1025. * @see disableOption()
  1026. * @see $options
  1027. */
  1028. function enableOption( $option, $params = array() )
  1029. {
  1030. if( !isset( $this->options[$option] ) )
  1031. $this->options[$option] = array();
  1032. $this->options[$option]['enabled'] = true;
  1033. $this->options[$option]['params'] = $params;
  1034. }
  1035. /**
  1036. * Disables an element option
  1037. *
  1038. * See the {@link patForms::$options} property for an exhaustive list of available options.
  1039. *
  1040. * @access public
  1041. * @param string $option The option to disable
  1042. * @see enableOption()
  1043. * @see $options
  1044. */
  1045. function disableOption( $option )
  1046. {
  1047. if( !isset( $this->options[$option] ) )
  1048. $this->options[$option] = array();
  1049. $this->options[$option]['enabled'] = false;
  1050. }
  1051. /**
  1052. * [helper method] validates the given value according to the specified method. It first
  1053. * checks if there is a method to check the format in the {@link patForms_FormatChecker}
  1054. * class, then checks in the element class itself.
  1055. *
  1056. * @access public
  1057. * @param mixed $value The value to validate the format of
  1058. * @param string $format The format to validate the value with
  1059. * @return bool $isValid True if valid, false if invalid or no method exists to validate the format.
  1060. * @see patForms_FormatChecker
  1061. */
  1062. function validateFormat( $value, $format )
  1063. {
  1064. if( !class_exists( "patForms_FormatChecker" ) )
  1065. {
  1066. $checkerFile = dirname( __FILE__ )."/FormatChecker.php";
  1067. if( !file_exists( $checkerFile ) )
  1068. {
  1069. $this->valid = false;
  1070. return patErrorManager::raiseError(
  1071. PATFORMS_ELEMENT_ERROR_FORMAT_CHECKER_NOT_FOUND,
  1072. "Type checker could not be found, aborting validation."
  1073. );
  1074. }
  1075. include_once( $checkerFile );
  1076. }
  1077. $format = strtolower( $format );
  1078. $methodName = "is_".$format;
  1079. $option = false;
  1080. if( method_exists( $this, $methodName ) )
  1081. {
  1082. return $this->$methodName( $value );
  1083. }
  1084. if( in_array( $methodName, get_class_methods( "patForms_FormatChecker" ) ) )
  1085. {
  1086. return call_user_func( array( 'patForms_FormatChecker', $methodName ), $value );
  1087. }
  1088. return false;
  1089. }
  1090. /**
  1091. * get next error offset
  1092. *
  1093. * @access public
  1094. * @return integer
  1095. */
  1096. function getErrorOffset( $requiredCodes = 100 )
  1097. {
  1098. $offset = $this->nextErrorOffset;
  1099. $this->nextErrorOffset = $this->nextErrorOffset + $requiredCodes;
  1100. return $offset;
  1101. }
  1102. /**
  1103. * add error codes and messages for validator method
  1104. *
  1105. * @access public
  1106. * @param array defintions
  1107. * @param integer offset for the error codes
  1108. */
  1109. function addValidatorErrorCodes( $defs, $offset = 1000 )
  1110. {
  1111. foreach( $defs as $lang => $codes )
  1112. {
  1113. if( !isset( $this->validatorErrorCodes[$lang] ) ) {
  1114. $this->validatorErrorCodes[$lang] = array();
  1115. }
  1116. foreach( $codes as $code => $message ) {
  1117. $this->validatorErrorCodes[$lang][($offset+$code)] = $message;
  1118. }
  1119. }
  1120. }
  1121. /**
  1122. * getValidationErrors
  1123. *
  1124. * @access public
  1125. * @return array errors that occured during the validation
  1126. */
  1127. function getValidationErrors()
  1128. {
  1129. return $this->validationErrors;
  1130. }
  1131. /**
  1132. * addValidationError
  1133. *
  1134. *
  1135. * @access public
  1136. * @param integer $code
  1137. * @param array $vars fill named placeholder with values
  1138. * @return boolean $result true on success
  1139. */
  1140. function addValidationError( $code, $vars = array() )
  1141. {
  1142. $error = false;
  1143. $lang = $this->locale;
  1144. $element = $this->getElementName();
  1145. // find error message for selected language
  1146. while( true )
  1147. {
  1148. // error message matches language code
  1149. if( isset( $this->validatorErrorCodes[$lang][$code] ) )
  1150. {
  1151. $error = array( "element" => $element, "code" => $code, "message" => '<i18n:text>'.$this->validatorErrorCodes[$lang][$code].'</i18n:text>' );
  1152. break;
  1153. }
  1154. // no message found and no fallback-langauage available
  1155. else if ( $lang == "C" )
  1156. {
  1157. break;
  1158. }
  1159. $lang_old = $lang;
  1160. // look for other languages
  1161. if( strlen( $lang ) > 5 )
  1162. {
  1163. list( $lang, $trash ) = explode( ".", $lang );
  1164. }
  1165. else if( strlen( $lang ) > 2 )
  1166. {
  1167. list( $lang, $trash ) = explode( "_", $lang );
  1168. }
  1169. else
  1170. {
  1171. $lang = "C";
  1172. }
  1173. // inform developer about missing language
  1174. patErrorManager::raiseNotice(
  1175. PATFORMS_ELEMENT_ERROR_VALIDATOR_ERROR_LOCALE_UNDEFINED,
  1176. "Required Validation Error-Code for language: $lang_old not available. Now trying language: $lang",
  1177. "Add language definition in used element or choose other language"
  1178. );
  1179. }
  1180. // get default Error!
  1181. if( !$error )
  1182. {
  1183. patErrorManager::raiseWarning(
  1184. PATFORMS_ELEMENT_ERROR_VALIDATOR_ERROR_UNDEFINED,
  1185. "No Error Message for this validation Error was defined",
  1186. "Review the error-definition for validation-errors in your element '$element'."
  1187. );
  1188. $error = array( "element" => $element, "code" => 0, "message" => "Unknown validation Error" );
  1189. }
  1190. // insert values to placeholders
  1191. if( !empty( $vars ) )
  1192. {
  1193. foreach( $vars as $key => $value )
  1194. {
  1195. $error["message"] = str_replace( "[". strtoupper( $key ) ."]", $value, $error["message"] );
  1196. }
  1197. }
  1198. array_push( $this->validationErrors, $error );
  1199. $this->valid = false;
  1200. return true;
  1201. }
  1202. /**
  1203. * applies the specified modifiers to an attribute value, as set in the attribute definition.
  1204. *
  1205. * @access private
  1206. * @param mixed $attributeValue The value of the attribute to modify
  1207. * @param array $modifiers Array containing the list of modifiers and their options to apply.
  1208. * @return mixed $attributeValue The modified attribute value.
  1209. * @see createAttributes()
  1210. */
  1211. function _applyModifiers( $attributeValue, $modifiers )
  1212. {
  1213. if( !is_array( $modifiers ) )
  1214. {
  1215. return patErrorManager::raiseError(
  1216. PATFORMS_ELEMENT_ERROR_MODIFIER_NOT_AN_ARRAY,
  1217. "Modifiers are not an array"
  1218. );
  1219. }
  1220. foreach( $modifiers as $modifier => $modifierOptions )
  1221. {
  1222. // compute method name for this definition and check if it exists
  1223. $modifierMethod = "_modifier".ucfirst( $modifier );
  1224. if( !method_exists( $this, $modifierMethod ) )
  1225. {
  1226. return patErrorManager::raiseError(
  1227. PATFORMS_ELEMENT_ERROR_METHOD_FOR_MODIFIER_NOT_FOUND,
  1228. "Method not found for modifier '" . $modifier . "' (".$modifierMethod.") in class '" . get_class( $this ) . "'"
  1229. );
  1230. }
  1231. $modifiedValue = $this->$modifierMethod( $attributeValue );
  1232. if( $modifiedValue === false )
  1233. {
  1234. return patErrorManager::raiseError(
  1235. PATFORMS_ELEMENT_ERROR_MODIFIER_RETURNED_ERROR,
  1236. "Modifier '".$modifier."' returned an error."
  1237. );
  1238. }
  1239. $attributeValue = $modifiedValue;
  1240. }
  1241. return $attributeValue;
  1242. }
  1243. /**
  1244. * insertSpecials attribute value modifier
  1245. *
  1246. * you can use special placeholders to insert dynamic values into the attribute values.
  1247. * This method inserts the correct information for each placeholder in the given string.
  1248. *
  1249. * @access private
  1250. * @param string $string The string to insert the specials in
  1251. * @return string $string The string with all needed replacements
  1252. * @see _applyModifiers()
  1253. * @todo Maybe make this configurable
  1254. * @todo Add any other relevant information
  1255. */
  1256. function _modifierInsertSpecials( $modifyValue, $options = array() )
  1257. {
  1258. if( is_array( $modifyValue ) || is_object( $modifyValue ) || is_array( $this->value ) )
  1259. return $modifyValue;
  1260. // go through each attribute in the attribute definition and replace the strings
  1261. // with the corresponding attribute values.
  1262. foreach( $this->attributeDefinition as $attributeName => $attributeDef )
  1263. {
  1264. // if attribute was not set, strip the variable by setting it to empty.
  1265. $attributeValue = "";
  1266. // retrieve real attribute value if it was set
  1267. if( isset( $this->attributes[$attributeName] ) && is_string( $this->attributes[$attributeName] ) )
  1268. {
  1269. $attributeValue = $this->attributes[$attributeName];
  1270. }
  1271. $search = $this->modifierStart."ELEMENT_".strtoupper( $attributeName ).$this->modifierEnd;
  1272. // make the replacement
  1273. $modifyValue = str_replace( $search, $attributeValue, $modifyValue );
  1274. }
  1275. // the element's value is special...
  1276. $modifyValue = str_replace( $this->modifierStart."ELEMENT_VALUE".$this->modifierEnd, $this->value, $modifyValue );
  1277. return $modifyValue;
  1278. }
  1279. /**
  1280. * checks the format of an attribute value according to the given format.
  1281. *
  1282. * @access private
  1283. * @param mixed $attributeValue The attribute value to check
  1284. * @param string $format The format to check the attribute value against
  1285. * @return bool $result True if format check succeeded, false otherwise.
  1286. * @see createAttributes()
  1287. * @todo Implement this method sometime
  1288. */
  1289. function _checkAttributeFormat( $attributeValue, $format )
  1290. {
  1291. return true;
  1292. }
  1293. /**
  1294. * validates the current attribute collection according to the attributes definition
  1295. * and the given output format, and returns the list of valid attributes.
  1296. *
  1297. * @access private
  1298. * @param string $format The output format to retrieve the attributes for.
  1299. * @return mixed $attributes The list of attributes, or false if failed.
  1300. */
  1301. function getAttributesFor( $format )
  1302. {
  1303. $attributes = array();
  1304. foreach( $this->attributeDefinition as $attributeName => $attributeDef )
  1305. {
  1306. if( !isset( $this->attributes[$attributeName] ) )
  1307. {
  1308. if( $attributeDef["required"] )
  1309. {
  1310. return patErrorManager::raiseError(
  1311. PATFORMS_ELEMENT_ERROR_ATTRIBUTE_REQUIRED,
  1312. 'The element "'.$this->getElementName().'" needs the attribute "'.$attributeName.'" to be set.',
  1313. 'See the attribute definition of the element class "'.get_class( $this ).'"'
  1314. );
  1315. }
  1316. continue;
  1317. }
  1318. $attributeValue = $this->attributes[$attributeName];
  1319. // special case disabled attribute: skip this if it is not set to yes
  1320. // to avoid generating a disabled field anyway (empty HTML attribute)
  1321. if( $attributeName == 'disabled' && $attributeValue != 'yes' )
  1322. {
  1323. continue;
  1324. }
  1325. if( isset( $attributeDef["modifiers"] ) && !empty( $attributeDef["modifiers"] ) )
  1326. {
  1327. $modifiedValue = $this->_applyModifiers( $attributeValue, $attributeDef["modifiers"] );
  1328. if( $modifiedValue === false )
  1329. {
  1330. return patErrorManager::raiseError(
  1331. PATFORMS_ELEMENT_ERROR_UNABLE_TO_APPLY_MODIFIER_TO_ATTRIBUTE,
  1332. "Could not apply modifier to attribute '".$attributeName."' (value:'".$attributeValue."')"
  1333. );
  1334. }
  1335. $attributeValue = $modifiedValue;
  1336. // store this for later use too
  1337. $this->attributes[$attributeName] = $attributeValue;
  1338. }
  1339. if( !in_array( $format, $attributeDef["outputFormats"] ) )
  1340. {
  1341. continue;
  1342. }
  1343. if( isset( $attributeDef["format"] ) )
  1344. {
  1345. if( !$this->_checkAttributeFormat( $attributeValue, $attributeDef["format"] ) )
  1346. {
  1347. return patErrorManager::raiseError(
  1348. PATFORMS_ELEMENT_ERROR_CAN_NOT_VERIFY_FORMAT,
  1349. "Format '".$attributeDef["format"]."' could not be verified for attribute '".$attributeName."' => '".$attributeValue."'"
  1350. );
  1351. }
  1352. }
  1353. $attributes[$attributeName] = $attributeValue;
  1354. }
  1355. return $attributes;
  1356. }
  1357. /**
  1358. * [helper method] wrapper for the {@link createTag()} method which automates the tag
  1359. * creation by creating the tag from the current attribute collection and element type.
  1360. *
  1361. * @access protected
  1362. * @return mixed $result The created tag, or false if failed.
  1363. * @see elementType
  1364. * @see attributes
  1365. * @see createTag()
  1366. */
  1367. function toHtml()
  1368. {
  1369. $attributes = $this->getAttributesFor( $this->getFormat() );
  1370. if( patErrorManager::isError( $attributes ) )
  1371. {
  1372. return $attributes;
  1373. }
  1374. // escape xml entities
  1375. foreach( $attributes as $key => $value ) {
  1376. $attributes[$key] = htmlspecialchars($value);
  1377. }
  1378. return $this->createTag( $this->elementType[$this->getFormat()], "full", $attributes );
  1379. }
  1380. /**
  1381. * [helper method] create a hidden field with the given value. Retrieves all other needed
  1382. * attributes from the attributes collection.
  1383. * @access public
  1384. */
  1385. function createHiddenTag( $value )
  1386. {
  1387. $attribs = array( 'type' => 'hidden',
  1388. 'name' => $this->attributes['name'],
  1389. 'value' => $value,
  1390. 'id' => $this->attributes['id'],
  1391. );
  1392. return $this->createTag( "input", "full", $attribs );
  1393. }
  1394. /**
  1395. * [helper method] creates a hidden field with the given value. Used for the
  1396. * display=no attribute, and is the same as the createHiddenTag() method, only
  1397. * that the attributes collection is initialized to ensure that any variables
  1398. * in the element's attributes get replaced.
  1399. *
  1400. * @access private
  1401. * @param mixed $value The value of the element
  1402. * @return string $element The serialized hidden tag
  1403. * @see createHiddenTag()
  1404. */
  1405. function createDisplaylessTag( $value )
  1406. {
  1407. // call this to initialize all attributes. This is needed
  1408. // here to make sure that if there are
  1409. $this->getAttributesFor( $this->getFormat() );
  1410. return $this->createHiddenTag( $value );
  1411. }
  1412. /**
  1413. * [helper method] create an element HTML source from its attribute collection and
  1414. * returns it.
  1415. *
  1416. * @static
  1417. * @access protected
  1418. * @param string $tagname The name of the element / tag
  1419. * @param string $type Optional: the type of element to generate. Valid parameters are full|opening|closing|empty. Defaults to "full".
  1420. * @param mixed $value The value of the element
  1421. * @return string $element The HTML source of the element
  1422. */
  1423. function createTag( $tagname, $type = "full", $attributes = array(), $value = false )
  1424. {
  1425. switch( $type )
  1426. {
  1427. case "closing":
  1428. return "</$tagname>";
  1429. break;
  1430. case "empty":
  1431. case "opening":
  1432. $tag = "<".$tagname;
  1433. // create attribute collection
  1434. foreach( $attributes as $attributeName => $attributeValue )
  1435. {
  1436. $tag = $tag . " ".$attributeName."=\"". (string)$attributeValue ."\"";
  1437. }
  1438. // empty tag?
  1439. if( $type == "empty" )
  1440. {
  1441. $tag = $tag . " />";
  1442. return $tag;
  1443. }
  1444. $tag = $tag . ">";
  1445. return $tag;
  1446. break;
  1447. case "full":
  1448. if( $value === false )
  1449. {
  1450. return patForms_Element::createTag( $tagname, "empty", $attributes );
  1451. }
  1452. return patForms_Element::createTag( $tagname, "opening", $attributes ).htmlspecialchars( $value ).patForms_Element::createTag( $tagname, "closing" );
  1453. break;
  1454. }
  1455. }
  1456. /**
  1457. * create XML representation of the element
  1458. *
  1459. * This can be used when you need to store the structure
  1460. * of your form in flat files or create form templates that can
  1461. * be read by patForms_Parser at a later point.
  1462. *
  1463. * @access public
  1464. * @param string namespace
  1465. * @uses getElementName()
  1466. * @see patForms_Parser
  1467. */
  1468. function toXML( $namespace = null )
  1469. {
  1470. $tagName = $this->getElementName();
  1471. // prepend Namespace
  1472. if( $namespace != null )
  1473. {
  1474. $tagName = $namespace.':'.$tagName;
  1475. }
  1476. // get all attributes
  1477. $attributes = $this->getAttributes();
  1478. // create valid XML attributes
  1479. foreach( $attributes as $key => $value )
  1480. {
  1481. $attributes[$key] = strtr( $value, $this->xmlEntities );
  1482. }
  1483. $value = strtr( $this->getValue(), $this->xmlEntities );
  1484. if( $value != false )
  1485. {
  1486. return $this->createTag( $tagName, "full", $attributes, $value );
  1487. }
  1488. return $this->createTag( $tagName, "empty", $attributes );
  1489. }
  1490. /**
  1491. * apply a filter
  1492. *
  1493. * This is still in alpha state!
  1494. *
  1495. * @access public
  1496. * @param object patForms_Filter
  1497. * @todo add error management and docs
  1498. */
  1499. function applyFilter( &$filter, $outFunc = null )
  1500. {
  1501. $this->filters[] = &$filter;
  1502. return true;
  1503. }
  1504. /**
  1505. * apply a simple filter
  1506. *
  1507. * This is still in alpha state!
  1508. *
  1509. * @access public
  1510. * @param object patForms_Filter
  1511. * @todo add error management and docs
  1512. */
  1513. function applySimpleFilter( $inFunc, $outFunc = null )
  1514. {
  1515. $filter = &patForms::createFilter('Function');
  1516. $filter->setInFunction($inFunc);
  1517. $filter->setOutFunction($outFunc);
  1518. return $this->applyFilter($filter);
  1519. }
  1520. /**
  1521. * Get the name of the element, as stored in the elementName property.
  1522. *
  1523. * This is used when serializing an element to XML to
  1524. * create a now form template.
  1525. *
  1526. * This method checks for the $elementName property and if it
  1527. * is set to null, it will extract the element name from the class name
  1528. *
  1529. * @access public
  1530. * @return string tag name
  1531. */
  1532. function getElementName()
  1533. {
  1534. if( $this->elementName != null )
  1535. {
  1536. return $this->elementName;
  1537. }
  1538. $class = get_class( $this );
  1539. $name = substr( strrchr( $class, "_" ), 1 );
  1540. return ucfirst( $name );
  1541. }
  1542. /**
  1543. * checks wheter sessions are used or switch session usage on or of
  1544. *
  1545. * If switch argument is missing, this function just reports if sessions
  1546. * will be used or not
  1547. *
  1548. * @access protected
  1549. * @param string $switch switch sessions on ("yes") or off ("yes")
  1550. * @return boolean $result true if sessions will be used, false otherwise
  1551. * @see setSessionValue()
  1552. * @see getSessionValue()
  1553. * @see unsetSessionValue()
  1554. * @todo destroy session variables if sessions won't be usead any further
  1555. */
  1556. function useSession( $switch = null )
  1557. {
  1558. // switch sessions on or off
  1559. if( $switch == "yes" )
  1560. {
  1561. $this->attributes["usesession"] = "yes";
  1562. }
  1563. else if( $switch == "no" )
  1564. {
  1565. $this->attributes["usesession"] = "no";
  1566. return false;
  1567. }
  1568. if( isset( $this->attributes["usesession"] ) && $this->attributes["usesession"] == "yes" )
  1569. {
  1570. if( !$this->sessionVar )
  1571. {
  1572. if( !defined( "SID" ) )
  1573. {
  1574. session_start();
  1575. }
  1576. $name = $this->attributes["name"];
  1577. if( !isset( $_SESSION["_patforms_element"][$name] ) )
  1578. {
  1579. $_SESSION["_patforms_element"][$name] = array();
  1580. }
  1581. $this->sessionVar =& $_SESSION["_patforms_element"][$name];
  1582. }
  1583. return true;
  1584. }
  1585. return false;
  1586. }
  1587. /**
  1588. * save a variable to the session
  1589. *
  1590. * @access protected
  1591. * @param string $name name to identify the variable
  1592. * @param mixed $value
  1593. * @return boolean $result true on success
  1594. * @see getSessionValue()
  1595. * @see unsetSessionValue()
  1596. */
  1597. function setSessionValue( $name, $value )
  1598. {
  1599. if( !$this->useSession() )
  1600. {
  1601. return false;
  1602. }
  1603. $this->sessionVar[$name] = $value;
  1604. return true;
  1605. }
  1606. /**
  1607. * get a variable from session
  1608. *
  1609. * @access protected
  1610. * @param string $name name to identify the variable
  1611. * @return mixed $result false if no sessions are used, null if variable is not set or the value of the variable
  1612. * @see getSessionValue()
  1613. * @see unsetSessionValue()
  1614. */
  1615. function getSessionValue( $name )
  1616. {
  1617. if( !$this->useSession() )
  1618. {
  1619. return false;
  1620. }
  1621. if( isset( $this->sessionVar[$name] ) )
  1622. {
  1623. return $this->sessionVar[$name];
  1624. }
  1625. return null;
  1626. }
  1627. /**
  1628. * remove a variable from session
  1629. *
  1630. * @access protected
  1631. * @param string $name name to identify the variable
  1632. * @return mixed $result false if no sessions are used, null if variable is not set or the value of the variable
  1633. * @see getSessionValue()
  1634. * @see setSessionValue)
  1635. */
  1636. function unsetSessionValue( $name )
  1637. {
  1638. if( !$this->useSession() )
  1639. {
  1640. return false;
  1641. }
  1642. $value = null;
  1643. if( isset( $this->sessionVar[$name] ) )
  1644. {
  1645. $value = $this->sessionVar[$name];
  1646. unset( $this->sessionVar[$name] );
  1647. }
  1648. return $value;
  1649. }
  1650. /**
  1651. * get the global javascript of the element
  1652. *
  1653. * @access public
  1654. * @return string
  1655. */
  1656. function getGlobalJavascript()
  1657. {
  1658. if( !isset( $this->globalJavascript[$this->format] ) )
  1659. {
  1660. $script = '';
  1661. }
  1662. else
  1663. {
  1664. $script = $this->globalJavascript[$this->format];
  1665. }
  1666. $cnt = count( $this->_rules );
  1667. for( $i = 0; $i < $cnt; $i++ )
  1668. {
  1669. $tmp = $this->_rules[$i]['rule']->getGlobalJavascript();
  1670. if( $tmp === false )
  1671. continue;
  1672. $script .= $tmp;
  1673. }
  1674. return $script;
  1675. }
  1676. /**
  1677. * get the instance javascript of the element
  1678. *
  1679. * @access public
  1680. * @return string javascript for this instance
  1681. */
  1682. function getInstanceJavascript()
  1683. {
  1684. if( !isset( $this->instanceJavascript[$this->format] ) )
  1685. {
  1686. $script = '';
  1687. }
  1688. else
  1689. {
  1690. $script = $this->instanceJavascript[$this->format];
  1691. $script = str_replace( '[ELEMENT::NAME]', $this->getName(), $script );
  1692. $script = str_replace( '[ELEMENT::ID]', $this->getId(), $script );
  1693. }
  1694. $cnt = count( $this->_rules );
  1695. for( $i = 0; $i < $cnt; $i++ )
  1696. {
  1697. $tmp = $this->_rules[$i]['rule']->getInstanceJavascript();
  1698. if( $tmp === false )
  1699. continue;
  1700. $script .= $tmp;
  1701. }
  1702. return $script;
  1703. }
  1704. /**
  1705. * retrieves the element's current submitted state.
  1706. *
  1707. * @access public
  1708. * @return bool $state True if it has been submitted, false otherwise.
  1709. * @see submitted
  1710. */
  1711. function isSubmitted()
  1712. {
  1713. if( $this->submitted === true ) {
  1714. return true;
  1715. }
  1716. return false;
  1717. }
  1718. /**
  1719. * returns the locale that is currently set for the form.
  1720. *
  1721. * @access public
  1722. * @return string $locale The locale.
  1723. * @see setLocale()
  1724. * @see $locale
  1725. */
  1726. function getLocale()
  1727. {
  1728. return $this->locale;
  1729. }
  1730. /**
  1731. * anounce a change in the element to all observers
  1732. *
  1733. * @access private
  1734. * @param string property that changed
  1735. * @param mixed new value of the property
  1736. */
  1737. function _announce( $property, $value )
  1738. {
  1739. $cnt = count( $this->observers );
  1740. for( $i = 0; $i < $cnt; $i++ )
  1741. {
  1742. $this->observers[$i]->notify( $this, $property, $value );
  1743. }
  1744. return true;
  1745. }
  1746. /**
  1747. * filter a value that has been passed via GET or POST
  1748. *
  1749. * This method checks the magic_quotes_gpc setting and
  1750. * applies all filters that had been set.
  1751. *
  1752. * @access protected
  1753. * @return boolean
  1754. */
  1755. function _filterHttpValue()
  1756. {
  1757. if (ini_get('magic_quotes_gpc')) {
  1758. $this->value = $this->rStripSlashes( $this->value );
  1759. }
  1760. $this->value = $this->_applyFilters( $this->value, 'in', PATFORMS_FILTER_TYPE_HTTP );
  1761. return true;
  1762. }
  1763. }
  1764. ?>