/library/spoon/form/text.php

https://github.com/zakgrant/forkcms · PHP · 755 lines · 348 code · 123 blank · 284 comment · 114 complexity · aea8bc0c317702bd5c52a8be22fcf32f MD5 · raw file

  1. <?php
  2. /**
  3. * Spoon Library
  4. *
  5. * This source file is part of the Spoon Library. More information,
  6. * documentation and tutorials can be found @ http://www.spoon-library.com
  7. *
  8. * @package spoon
  9. * @subpackage form
  10. *
  11. *
  12. * @author Davy Hellemans <davy@spoon-library.com>
  13. * @since 0.1.1
  14. */
  15. /**
  16. * Create a form textfield.
  17. *
  18. * @package spoon
  19. * @subpackage form
  20. *
  21. *
  22. * @author Davy Hellemans <davy@spoon-library.com>
  23. * @since 0.1.1
  24. */
  25. class SpoonFormText extends SpoonFormInput
  26. {
  27. /**
  28. * Is the content of this field html?
  29. *
  30. * @var bool
  31. */
  32. private $isHTML = false;
  33. /**
  34. * Overrule the reserverd attributes
  35. *
  36. * @var array
  37. */
  38. protected $reservedAttributes = array('name', 'value');
  39. /**
  40. * Class constructor.
  41. *
  42. * @param string $name The name.
  43. * @param string[optional] $value The initial value.
  44. * @param int[optional] $maxlength The maximum-length the value can be.
  45. * @param string[optional] $class The CSS-class to be used.
  46. * @param string[optional] $classError The CSS-class to be used when there is an error.
  47. * @param bool[optional] $HTML Is HTML allowed?
  48. */
  49. public function __construct($name, $value = null, $maxlength = null, $class = 'inputText', $classError = 'inputTextError', $HTML = false)
  50. {
  51. // obligated fields
  52. $this->attributes['id'] = SpoonFilter::toCamelCase($name, '_', true);
  53. $this->attributes['name'] = (string) $name;
  54. // custom optional fields
  55. if($value !== null) $this->value = (string) $value;
  56. if($maxlength !== null) $this->attributes['maxlength'] = (int) $maxlength;
  57. $this->attributes['type'] = 'text';
  58. $this->attributes['class'] = (string) $class;
  59. if($classError !== null) $this->classError = (string) $classError;
  60. $this->isHTML = (bool) $HTML;
  61. }
  62. /**
  63. * Retrieve the initial or submitted value.
  64. *
  65. * @return string
  66. * @param bool[optional] $allowHTML Is HTML allowed?
  67. */
  68. public function getValue($allowHTML = null)
  69. {
  70. // redefine html & default value
  71. $allowHTML = ($allowHTML !== null) ? (bool) $allowHTML : $this->isHTML;
  72. $value = $this->value;
  73. // contains html
  74. if($this->isHTML)
  75. {
  76. // set value
  77. $value = (SPOON_CHARSET == 'utf-8') ? SpoonFilter::htmlspecialchars($value) : SpoonFilter::htmlentities($value);
  78. }
  79. // form submitted
  80. if($this->isSubmitted())
  81. {
  82. // post/get data
  83. $data = $this->getMethod(true);
  84. // submitted by post (may be empty)
  85. if(isset($data[$this->getName()]))
  86. {
  87. // value
  88. $value = $data[$this->attributes['name']];
  89. // maximum length?
  90. if(isset($this->attributes['maxlength']) && $this->attributes['maxlength'] > 0) $value = mb_substr($value, 0, (int) $this->attributes['maxlength'], SPOON_CHARSET);
  91. // html allowed?
  92. if(!$allowHTML) $value = (SPOON_CHARSET == 'utf-8') ? SpoonFilter::htmlspecialchars($value) : SpoonFilter::htmlentities($value);
  93. }
  94. }
  95. return $value;
  96. }
  97. /**
  98. * Checks if this field contains only letters a-z and A-Z.
  99. *
  100. * @return bool
  101. * @param string[optional] $error The error message to set.
  102. */
  103. public function isAlphabetical($error = null)
  104. {
  105. // filled
  106. if($this->isFilled())
  107. {
  108. // post/get data
  109. $data = $this->getMethod(true);
  110. // validate
  111. if(!isset($data[$this->attributes['name']]) || !SpoonFilter::isAlphabetical($data[$this->attributes['name']]))
  112. {
  113. if($error !== null) $this->setError($error);
  114. return false;
  115. }
  116. return true;
  117. }
  118. // not submitted
  119. if($error !== null) $this->setError($error);
  120. return false;
  121. }
  122. /**
  123. * Checks if this field only contains letters & numbers (without spaces).
  124. *
  125. * @return bool
  126. * @param string[optional] $error The error message to set.
  127. */
  128. public function isAlphaNumeric($error = null)
  129. {
  130. // filled
  131. if($this->isFilled())
  132. {
  133. // post/get data
  134. $data = $this->getMethod(true);
  135. // validate
  136. if(!isset($data[$this->attributes['name']]) || !SpoonFilter::isAlphaNumeric($data[$this->attributes['name']]))
  137. {
  138. if($error !== null) $this->setError($error);
  139. return false;
  140. }
  141. return true;
  142. }
  143. // not submitted
  144. if($error !== null) $this->setError($error);
  145. return false;
  146. }
  147. /**
  148. * Checks if the field is between a given minimum and maximum (includes min & max).
  149. *
  150. * @return bool
  151. * @param int $minimum The minimum.
  152. * @param int $maximum The maximum.
  153. * @param string[optional] $error The error message to set.
  154. */
  155. public function isBetween($minimum, $maximum, $error = null)
  156. {
  157. // filled
  158. if($this->isFilled())
  159. {
  160. // post/get data
  161. $data = $this->getMethod(true);
  162. // validate
  163. if(!isset($data[$this->attributes['name']]) || !SpoonFilter::isBetween($minimum, $maximum, $data[$this->attributes['name']]))
  164. {
  165. if($error !== null) $this->setError($error);
  166. return false;
  167. }
  168. return true;
  169. }
  170. // not submitted
  171. if($error !== null) $this->setError($error);
  172. return false;
  173. }
  174. /**
  175. * Checks this field for a boolean (true/false | 0/1).
  176. *
  177. * @return bool
  178. * @param string[optional] $error The error message to set.
  179. */
  180. public function isBool($error = null)
  181. {
  182. // filled
  183. if($this->isFilled())
  184. {
  185. // post/get data
  186. $data = $this->getMethod(true);
  187. // validate
  188. if(!isset($data[$this->attributes['name']]) || !SpoonFilter::isBool($data[$this->attributes['name']]))
  189. {
  190. if($error !== null) $this->setError($error);
  191. return false;
  192. }
  193. return true;
  194. }
  195. // not submitted
  196. if($error !== null) $this->setError($error);
  197. return false;
  198. }
  199. /**
  200. * Checks if this field only contains numbers 0-9.
  201. *
  202. * @return bool
  203. * @param string[optional] $error The error message to set.
  204. */
  205. public function isDigital($error = null)
  206. {
  207. // filled
  208. if($this->isFilled())
  209. {
  210. // post/get data
  211. $data = $this->getMethod(true);
  212. // validate
  213. if(!isset($data[$this->attributes['name']]) || !SpoonFilter::isDigital($data[$this->attributes['name']]))
  214. {
  215. if($error !== null) $this->setError($error);
  216. return false;
  217. }
  218. return true;
  219. }
  220. // not submitted
  221. if($error !== null) $this->setError($error);
  222. return false;
  223. }
  224. /**
  225. * Checks this field for a valid e-mail address.
  226. *
  227. * @return bool
  228. * @param string[optional] $error The error message to set.
  229. */
  230. public function isEmail($error = null)
  231. {
  232. // filled
  233. if($this->isFilled())
  234. {
  235. // post/get data
  236. $data = $this->getMethod(true);
  237. // validate
  238. if(!isset($data[$this->attributes['name']]) || !SpoonFilter::isEmail($data[$this->attributes['name']]))
  239. {
  240. if($error !== null) $this->setError($error);
  241. return false;
  242. }
  243. return true;
  244. }
  245. // has error
  246. if($error !== null) $this->setError($error);
  247. return false;
  248. }
  249. /**
  250. * Checks for a valid file name (including dots but no slashes and other forbidden characters).
  251. *
  252. * @return bool
  253. * @param string[optional] $error The error message to set.
  254. */
  255. public function isFilename($error = null)
  256. {
  257. // filled
  258. if($this->isFilled())
  259. {
  260. // post/get data
  261. $data = $this->getMethod(true);
  262. // validate
  263. if(!isset($data[$this->attributes['name']]) || !SpoonFilter::isFilename($data[$this->attributes['name']]))
  264. {
  265. if($error !== null) $this->setError($error);
  266. return false;
  267. }
  268. return true;
  269. }
  270. // has error
  271. if($error !== null) $this->setError($error);
  272. return false;
  273. }
  274. /**
  275. * Checks if this field was submitted & filled.
  276. *
  277. * @return bool
  278. * @param string[optional] $error The error message to set.
  279. */
  280. public function isFilled($error = null)
  281. {
  282. // post/get data
  283. $data = $this->getMethod(true);
  284. // validate
  285. if(!(isset($data[$this->attributes['name']]) && trim($data[$this->attributes['name']]) != ''))
  286. {
  287. if($error !== null) $this->setError($error);
  288. return false;
  289. }
  290. return true;
  291. }
  292. /**
  293. * Checks this field for numbers 0-9 and an optional - (minus) sign (in the beginning only).
  294. *
  295. * @return bool
  296. * @param string[optional] $error The error message to set.
  297. * @param bool[optional] $allowCommas Do you want to use commas as a decimal separator?
  298. */
  299. public function isFloat($error = null, $allowCommas = false)
  300. {
  301. // filled
  302. if($this->isFilled())
  303. {
  304. // post/get data
  305. $data = $this->getMethod(true);
  306. // validate
  307. if(!isset($data[$this->attributes['name']]) || !SpoonFilter::isFloat($data[$this->attributes['name']], $allowCommas))
  308. {
  309. if($error !== null) $this->setError($error);
  310. return false;
  311. }
  312. return true;
  313. }
  314. // not submitted
  315. if($error !== null) $this->setError($error);
  316. return false;
  317. }
  318. /**
  319. * Checks if this field is greater than another value.
  320. *
  321. * @return bool
  322. * @param int $minimum The minimum.
  323. * @param string[optional] $error The error message to set.
  324. */
  325. public function isGreaterThan($minimum, $error = null)
  326. {
  327. // filled
  328. if($this->isFilled())
  329. {
  330. // post/get data
  331. $data = $this->getMethod(true);
  332. // validate
  333. if(!isset($data[$this->attributes['name']]) || !SpoonFilter::isGreaterThan($minimum, $data[$this->attributes['name']]))
  334. {
  335. if($error !== null) $this->setError($error);
  336. return false;
  337. }
  338. return true;
  339. }
  340. // not submitted
  341. if($error !== null) $this->setError($error);
  342. return false;
  343. }
  344. /**
  345. * Checks this field for numbers 0-9 and an optional - (minus) sign (in the beginning only).
  346. *
  347. * @return bool
  348. * @param string[optional] $error The error message to set.
  349. */
  350. public function isInteger($error = null)
  351. {
  352. // filled
  353. if($this->isFilled())
  354. {
  355. // post/get data
  356. $data = $this->getMethod(true);
  357. // validate
  358. if(!isset($data[$this->attributes['name']]) || !SpoonFilter::isInteger($data[$this->attributes['name']]))
  359. {
  360. if($error !== null) $this->setError($error);
  361. return false;
  362. }
  363. return true;
  364. }
  365. // not submitted
  366. if($error !== null) $this->setError($error);
  367. return false;
  368. }
  369. /**
  370. * Checks if this field is a proper ip address.
  371. *
  372. * @return bool
  373. * @param string[optional] $error The error message to set.
  374. */
  375. public function isIp($error = null)
  376. {
  377. // filled
  378. if($this->isFilled())
  379. {
  380. // post/get data
  381. $data = $this->getMethod(true);
  382. // validate
  383. if(!isset($data[$this->attributes['name']]) || !SpoonFilter::isIp($data[$this->attributes['name']]))
  384. {
  385. if($error !== null) $this->setError($error);
  386. return false;
  387. }
  388. return true;
  389. }
  390. // not submitted
  391. if($error !== null) $this->setError($error);
  392. return false;
  393. }
  394. /**
  395. * Checks if this field does not exceed the given maximum.
  396. *
  397. * @return bool
  398. * @param int $maximum The maximum.
  399. * @param int[optional] $error The error message to set.
  400. */
  401. public function isMaximum($maximum, $error = null)
  402. {
  403. // filled
  404. if($this->isFilled())
  405. {
  406. // post/get data
  407. $data = $this->getMethod(true);
  408. // validate
  409. if(!isset($data[$this->attributes['name']]) || !SpoonFilter::isMaximum($maximum, $data[$this->attributes['name']]))
  410. {
  411. if($error !== null) $this->setError($error);
  412. return false;
  413. }
  414. return true;
  415. }
  416. // not submitted
  417. if($error !== null) $this->setError($error);
  418. return false;
  419. }
  420. /**
  421. * Checks if this field's length is less (or equal) than the given maximum.
  422. *
  423. * @return bool
  424. * @param int $maximum The maximum number of characters.
  425. * @param string[optional] $error The error message to set.
  426. */
  427. public function isMaximumCharacters($maximum, $error = null)
  428. {
  429. // filled
  430. if($this->isFilled())
  431. {
  432. // post/get data
  433. $data = $this->getMethod(true);
  434. // validate
  435. if(!isset($data[$this->attributes['name']]) || !SpoonFilter::isMaximumCharacters($maximum, $data[$this->attributes['name']]))
  436. {
  437. if($error !== null) $this->setError($error);
  438. return false;
  439. }
  440. return true;
  441. }
  442. // not submitted
  443. if($error !== null) $this->setError($error);
  444. return false;
  445. }
  446. /**
  447. * Checks if this field is at least a given minimum.
  448. *
  449. * @return bool
  450. * @param int $minimum The minimum.
  451. * @param string[optional] $error The error message to set.
  452. */
  453. public function isMinimum($minimum, $error = null)
  454. {
  455. // filled
  456. if($this->isFilled())
  457. {
  458. // post/get data
  459. $data = $this->getMethod(true);
  460. // validate
  461. if(!isset($data[$this->attributes['name']]) || !SpoonFilter::isMinimum($minimum, $data[$this->attributes['name']]))
  462. {
  463. if($error !== null) $this->setError($error);
  464. return false;
  465. }
  466. return true;
  467. }
  468. // not submitted
  469. if($error !== null) $this->setError($error);
  470. return false;
  471. }
  472. /**
  473. * Checks if this field's length is more (or equal) than the given minimum.
  474. *
  475. * @return bool
  476. * @param int $minimum The minimum number of characters.
  477. * @param string[optional] $error The error message to set.
  478. */
  479. public function isMinimumCharacters($minimum, $error = null)
  480. {
  481. // filled
  482. if($this->isFilled())
  483. {
  484. // post/get data
  485. $data = $this->getMethod(true);
  486. // validate
  487. if(!isset($data[$this->attributes['name']]) || !SpoonFilter::isMinimumCharacters($minimum, $data[$this->attributes['name']]))
  488. {
  489. if($error !== null) $this->setError($error);
  490. return false;
  491. }
  492. return true;
  493. }
  494. // not submitted
  495. if($error !== null) $this->setError($error);
  496. return false;
  497. }
  498. /**
  499. * Alias for isDigital (Field may only contain numbers 0-9).
  500. *
  501. * @return bool
  502. * @param string[optional] $error The error message to set.
  503. */
  504. public function isNumeric($error = null)
  505. {
  506. return $this->isDigital($error);
  507. }
  508. /**
  509. * Checks if the field is smaller than a given maximum.
  510. *
  511. * @return bool
  512. * @param int $maximum The maximum.
  513. * @param string[optional] $error The error message to set.
  514. */
  515. public function isSmallerThan($maximum, $error = null)
  516. {
  517. // filled
  518. if($this->isFilled())
  519. {
  520. // post/get data
  521. $data = $this->getMethod(true);
  522. // validate
  523. if(!isset($data[$this->attributes['name']]) || !SpoonFilter::isSmallerThan($maximum, $data[$this->attributes['name']]))
  524. {
  525. if($error !== null) $this->setError($error);
  526. return false;
  527. }
  528. return true;
  529. }
  530. // not submitted
  531. if($error !== null) $this->setError($error);
  532. return false;
  533. }
  534. /**
  535. * Checks if this field contains any string that doesn't have control characters (ASCII 0 - 31) but spaces are allowed.
  536. *
  537. * @return bool
  538. * @param string[optional] $error The error message to set.
  539. */
  540. public function isString($error = null)
  541. {
  542. // filled
  543. if($this->isFilled())
  544. {
  545. // post/get data
  546. $data = $this->getMethod(true);
  547. // validate
  548. if(!isset($data[$this->attributes['name']]) || !SpoonFilter::isString($data[$this->attributes['name']]))
  549. {
  550. if($error !== null) $this->setError($error);
  551. return false;
  552. }
  553. return true;
  554. }
  555. // not submitted
  556. if($error !== null) $this->setError($error);
  557. return false;
  558. }
  559. /**
  560. * Checks this field for a valid url.
  561. *
  562. * @return bool
  563. * @param string[optional] $error The error message to set.
  564. */
  565. public function isURL($error = null)
  566. {
  567. // filled
  568. if($this->isFilled())
  569. {
  570. // post/get data
  571. $data = $this->getMethod(true);
  572. // validate
  573. if(!isset($data[$this->attributes['name']]) || !SpoonFilter::isURL($data[$this->attributes['name']]))
  574. {
  575. if($error !== null) $this->setError($error);
  576. return false;
  577. }
  578. return true;
  579. }
  580. // not submitted
  581. if($error !== null) $this->setError($error);
  582. return false;
  583. }
  584. /**
  585. * Checks if the field validates against the regexp.
  586. *
  587. * @return bool
  588. * @param string $regexp The regular expresion to test the value.
  589. * @param string[optional] $error The error message to set.
  590. */
  591. public function isValidAgainstRegexp($regexp, $error = null)
  592. {
  593. // filled
  594. if($this->isFilled())
  595. {
  596. // post/get data
  597. $data = $this->getMethod(true);
  598. // validate
  599. if(!isset($data[$this->attributes['name']]) || !SpoonFilter::isValidAgainstRegexp((string) $regexp, $data[$this->attributes['name']]))
  600. {
  601. if($error !== null) $this->setError($error);
  602. return false;
  603. }
  604. return true;
  605. }
  606. // not submitted
  607. if($error !== null) $this->setError($error);
  608. return false;
  609. }
  610. /**
  611. * Parses the html for this textfield.
  612. *
  613. * @return string
  614. * @param SpoonTemplate[optional] $template The template to parse the element in.
  615. */
  616. public function parse(SpoonTemplate $template = null)
  617. {
  618. // name is required
  619. if($this->attributes['name'] == '') throw new SpoonFormException('A name is required for a textfield. Please provide a name.');
  620. // start html generation
  621. $output = '<input value="' . str_replace(array('"', '<', '>'), array('&quot;', '&lt;', '&gt;'), $this->getValue()) . '"';
  622. // add attributes
  623. $output .= $this->getAttributesHTML(array('[id]' => $this->attributes['id'], '[name]' => $this->attributes['name'], '[value]' => $this->getValue())) . ' />';
  624. // template
  625. if($template !== null)
  626. {
  627. $template->assign('txt' . SpoonFilter::toCamelCase($this->attributes['name']), $output);
  628. $template->assign('txt' . SpoonFilter::toCamelCase($this->attributes['name']) . 'Error', ($this->errors != '') ? '<span class="formError">' . $this->errors . '</span>' : '');
  629. }
  630. return $output;
  631. }
  632. }