Element.class.php 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713
  1. <?php
  2. /**
  3. * The root element class. All other form elements must inherit from this class.
  4. *
  5. * @author Ironpilot
  6. * @copyright Copywrite (c) 2011, STAPLE CODE
  7. *
  8. * This file is part of the STAPLE Framework.
  9. *
  10. * The STAPLE Framework is free software: you can redistribute it and/or modify
  11. * it under the terms of the GNU Lesser General Public License as published by the
  12. * Free Software Foundation, either version 3 of the License, or (at your option)
  13. * any later version.
  14. *
  15. * The STAPLE Framework is distributed in the hope that it will be useful,
  16. * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  17. * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
  18. * more details.
  19. *
  20. * You should have received a copy of the GNU Lesser General Public License
  21. * along with the STAPLE Framework. If not, see <http://www.gnu.org/licenses/>.
  22. */
  23. abstract class Staple_Form_Element
  24. {
  25. /**
  26. * Name of the field on the form.
  27. * @var string
  28. */
  29. protected $name;
  30. /**
  31. * Form field's label.
  32. * @var string
  33. */
  34. protected $label;
  35. /**
  36. * The field's current value.
  37. * @var string
  38. */
  39. protected $value;
  40. /**
  41. * An array of HTML classes for the form field.
  42. * @var array
  43. */
  44. protected $classes = array();
  45. /**
  46. * Form field ID, uses the form name if the ID is not specified.
  47. * @var string
  48. */
  49. protected $id;
  50. /**
  51. * Holds instructions for completing the form field.
  52. * @var string
  53. */
  54. protected $instructions;
  55. /**
  56. * An array that holds extra HTML attributes.
  57. * @var array
  58. */
  59. protected $attrib = array();
  60. /**
  61. * Sets the field to be required.
  62. * @var boolean
  63. */
  64. protected $required = false;
  65. /**
  66. * Holds the true|false readOnly value.
  67. * @var boolean
  68. */
  69. protected $readOnly = false;
  70. /**
  71. * Hold the true|false disabled value.
  72. * @var boolean
  73. */
  74. protected $disabled = false;
  75. /**
  76. * An array of filters that will be applied to any form values.
  77. * @var array
  78. */
  79. protected $filters = array();
  80. /**
  81. * An array that holds the validator objects assigned to the form field.
  82. * @var array
  83. */
  84. protected $validators = array();
  85. /**
  86. * An array that holds the validation error messages.
  87. * @var array
  88. */
  89. protected $errors = array();
  90. /**
  91. * Form field constructor. Requires a name, has an optional label, id and attribute array.
  92. *
  93. * @param string $name
  94. * @param string $label
  95. * @param string $id
  96. * @param array $attrib
  97. */
  98. public function __construct($name, $label = NULL, $id = NULL, array $attrib = array())
  99. {
  100. $this->setName($name); //Name for the form field
  101. $this->setLabel($label); //Label that the user sees
  102. if(isset($id)) //ID for the form field
  103. {
  104. $this->setId($id);
  105. }
  106. else
  107. {
  108. $this->setId($name);
  109. }
  110. foreach($attrib as $key=>$value) //Additional HTML Attributes
  111. {
  112. $this->addAttrib($key, $value);
  113. }
  114. }
  115. /**
  116. * Class overload either calls a getter for a protected value or gets the value from the attribute array.
  117. *
  118. * @param string $name
  119. * @return null|string
  120. */
  121. public function __get($name)
  122. {
  123. $method = 'get'.$name;
  124. if(method_exists(get_class($this), $method))
  125. {
  126. return $this->$method();
  127. }
  128. else
  129. {
  130. if(array_key_exists($name,$this->attrib))
  131. {
  132. return $this->attrib[$name];
  133. }
  134. else
  135. {
  136. return NULL;
  137. }
  138. }
  139. }
  140. /**
  141. * Class overload either calls a setter for a protected value or sets that value within the attributes array.
  142. *
  143. * @param string $name
  144. * @param string $value
  145. */
  146. public function __set($name, $value)
  147. {
  148. $method = 'set'.$name;
  149. if(method_exists(get_class($this), $method))
  150. {
  151. $this->$method($value);
  152. }
  153. else
  154. {
  155. $this->attrib[$name] = $value;
  156. }
  157. }
  158. /**
  159. * Calls the field->build() function.
  160. */
  161. public function __toString()
  162. {
  163. try{
  164. return $this->build();
  165. }
  166. catch (Exception $e)
  167. {
  168. return '<p>Field Error...</p>';
  169. }
  170. }
  171. /**
  172. * Clone validators and filters so that they don't overlap;
  173. */
  174. public function __clone()
  175. {
  176. $vals = array();
  177. foreach($this->validators as $key=>$val)
  178. {
  179. $vals[$key] = clone $val;
  180. }
  181. $this->validators = $vals;
  182. $filts = array();
  183. foreach($this->filters as $key=>$fil)
  184. {
  185. $filts[$key] = clone $fil;
  186. }
  187. $this->filters = $filts;
  188. }
  189. /**
  190. * Returns a string with all html entities replaced.
  191. * @param string $text
  192. * @return string
  193. */
  194. protected function escape($text)
  195. {
  196. return htmlentities($text);
  197. }
  198. /**
  199. * A factory function to create form fields.
  200. *
  201. * @param string $name
  202. * @param string $label
  203. * @param string $id
  204. * @param array $attrib
  205. * @return Staple_Form_Element
  206. */
  207. public static function Create($name, $label = NULL, $id = NULL, array $attrib = array())
  208. {
  209. return new static($name, $label, $id, $attrib);
  210. }
  211. /*
  212. * -------------------------------------VALIDATION FUNCTIONS-------------------------------------
  213. */
  214. /**
  215. * Adds a field filter to the form field.
  216. * @param Staple_Form_Filter $filter
  217. * @return $this
  218. */
  219. public function addFilter(Staple_Form_Filter $filter)
  220. {
  221. $this->filters[$filter->getName()] = $filter;
  222. return $this;
  223. }
  224. /**
  225. * Adds a field validator to the form field.
  226. * @param Staple_Form_Validator $validator
  227. * @return $this
  228. */
  229. public function addValidator(Staple_Form_Validator $validator)
  230. {
  231. $this->validators[] = $validator;
  232. return $this;
  233. }
  234. /**
  235. * Removes all validators from a form field.
  236. */
  237. public function clearValidators()
  238. {
  239. $this->validators = array();
  240. return $this;
  241. }
  242. /**
  243. * Sets the field to be required to be completed to be valid. The optional parameter also allows you
  244. * to set required to false using this function.
  245. * @param bool $bool
  246. * @return Staple_Form_Element
  247. */
  248. public function setRequired($bool = true)
  249. {
  250. $this->required = (bool)$bool;
  251. if($bool === true)
  252. {
  253. $this->addClass('form_required');
  254. }
  255. return $this;
  256. }
  257. /**
  258. * Sets the field to not be required.
  259. * @return Staple_Form_Element
  260. */
  261. public function setNotRequired()
  262. {
  263. $this->required = false;
  264. return $this;
  265. }
  266. /**
  267. * Returns a boolean value of whether the field is required.
  268. * @return bool
  269. */
  270. public function isRequired()
  271. {
  272. return (bool)$this->required;
  273. }
  274. /**
  275. * Adds a custom error errors array for a specific field.
  276. * @param array $err
  277. */
  278. public function addError($err = NULL)
  279. {
  280. if(isset($err))
  281. {
  282. $this->errors[] = $err;
  283. }
  284. else
  285. {
  286. $this->errors[] = static::DEFAULT_ERROR;
  287. }
  288. }
  289. /**
  290. * Returns an array of the errors that occurred during form validation.
  291. * @return array
  292. */
  293. public function getErrors()
  294. {
  295. return $this->errors;
  296. }
  297. /**
  298. * Checks the form field against any validators to confirm valid data was entered into the form.
  299. * If no validators are associated with the field, it is assumed that no validation is required
  300. * and the field will always return valid. If the field is required then a value must be filled
  301. * into the field for it to be valid, even with no validators.
  302. *
  303. * @return boolean
  304. * @throws Exception
  305. */
  306. public function isValid()
  307. {
  308. foreach($this->validators as $val)
  309. {
  310. if($val instanceof Staple_Form_Validator)
  311. {
  312. $val->clearErrors();
  313. if(!$val->check($this->Value))
  314. {
  315. $this->errors[$val->getName()] = $val->getErrors();
  316. }
  317. }
  318. else
  319. {
  320. throw new Exception('Validation Error', Staple_Error::VALIDATION_ERROR);
  321. }
  322. }
  323. //@todo check for field content if not validators present.
  324. if(count($this->errors) == 0)
  325. {
  326. if($this->isRequired() && $this->getValue() !== NULL && $this->getValue() !== '')
  327. {
  328. return true;
  329. }
  330. else
  331. {
  332. if(!$this->isRequired())
  333. {
  334. return true;
  335. }
  336. else
  337. {
  338. return false;
  339. }
  340. }
  341. }
  342. else
  343. {
  344. return false;
  345. }
  346. }
  347. /**
  348. * This function queries all of the validators for javascript to verify their data.
  349. * @return string
  350. */
  351. public function clientJQuery()
  352. {
  353. $script = '';
  354. foreach ($this->validators as $val)
  355. {
  356. if($val instanceof Staple_Form_Validator)
  357. {
  358. $script .= $val->clientJQuery(get_class($this), $this);
  359. }
  360. else
  361. {
  362. throw new Exception('Form Error', Staple_Error::FORM_ERROR);
  363. }
  364. }
  365. return $script;
  366. }
  367. /**
  368. * This function queries all of the validators for javascript to verify their data.
  369. * @throws Exception
  370. * @return string
  371. */
  372. public function clientJS()
  373. {
  374. $script = '';
  375. foreach ($this->validators as $val)
  376. {
  377. if($val instanceof Staple_Form_Validator)
  378. {
  379. $script .= $val->clientJS(get_class($this), $this->id);
  380. }
  381. else
  382. {
  383. throw new Exception('Form Error', Staple_Error::FORM_ERROR);
  384. }
  385. }
  386. return $script;
  387. }
  388. /*
  389. * -------------------------------------SET/GET FUNCTIONS-------------------------------------
  390. */
  391. /**
  392. * Sets the name.
  393. * @param string $insert
  394. * @return Staple_Form_Element
  395. */
  396. public function setName($insert)
  397. {
  398. $this->name = $insert;
  399. return $this;
  400. }
  401. /**
  402. * Gets the name.
  403. */
  404. public function getName()
  405. {
  406. return $this->name;
  407. }
  408. /**
  409. * Sets the field label.
  410. * @param string $insert
  411. * @param bool $noescape
  412. * @return $this
  413. */
  414. public function setLabel($insert, $noescape = FALSE)
  415. {
  416. if($noescape === true)
  417. {
  418. $this->label = $insert;
  419. }
  420. else
  421. {
  422. $this->label = $this->escape($insert);
  423. }
  424. return $this;
  425. }
  426. /**
  427. * Gets the field label.
  428. */
  429. public function getLabel()
  430. {
  431. return $this->label;
  432. }
  433. /**
  434. * Sets the field value, if field is not read only.
  435. * @param string $insert
  436. * @throws Exception
  437. * @return Staple_Form_Element
  438. */
  439. public function setValue($insert)
  440. {
  441. if(!$this->isReadOnly())
  442. {
  443. //Process Filters
  444. foreach($this->filters as $name=>$filter)
  445. {
  446. if($filter instanceof Staple_Form_Filter)
  447. {
  448. $insert = $filter->filter($insert);
  449. }
  450. else
  451. {
  452. throw new Exception('Filter Error', Staple_Error::FORM_ERROR);
  453. }
  454. }
  455. $this->value = $insert;
  456. }
  457. return $this;
  458. }
  459. /**
  460. * Gets the form fields value.
  461. */
  462. public function getValue()
  463. {
  464. return $this->value;
  465. }
  466. /**
  467. * @return string $id
  468. */
  469. public function getId()
  470. {
  471. return $this->id;
  472. }
  473. /**
  474. * @param string $id
  475. * @return $this
  476. */
  477. public function setId($id)
  478. {
  479. $this->id = $id;
  480. return $this;
  481. }
  482. /**
  483. * @return string $instructions
  484. */
  485. public function getInstructions()
  486. {
  487. return $this->instructions;
  488. }
  489. /**
  490. * @param string $instructions
  491. * @return $this
  492. */
  493. public function setInstructions($instructions)
  494. {
  495. $this->instructions = $instructions;
  496. return $this;
  497. }
  498. /**
  499. * Sets $readOnly to true
  500. * @return Staple_Form_Element
  501. */
  502. public function setReadOnly()
  503. {
  504. $this->readOnly = true;
  505. return $this;
  506. }
  507. /**
  508. * Returns the readOnly value.
  509. * @return boolean
  510. */
  511. public function isReadOnly()
  512. {
  513. return $this->readOnly;
  514. }
  515. /**
  516. * @return bool $disabled
  517. */
  518. public function isDisabled()
  519. {
  520. return $this->disabled;
  521. }
  522. /**
  523. * @param boolean $disabled
  524. * @return $this
  525. */
  526. public function setDisabled($disabled = true)
  527. {
  528. $this->disabled = (bool)$disabled;
  529. return $this;
  530. }
  531. /**
  532. *
  533. * Adds an attribute to the attributes array. $attrib is the key or attribute name, and $value is its value.
  534. * @param string $attrib
  535. * @param string $value
  536. * @return $this
  537. */
  538. public function addAttrib($attrib, $value)
  539. {
  540. $this->attrib[$attrib] = $value;
  541. return $this;
  542. }
  543. /**
  544. * Add a CSS class to the Element
  545. * @param string $class
  546. * @return Staple_Form_Element
  547. */
  548. public function addClass($class)
  549. {
  550. if(in_array($class, $this->classes) === false)
  551. {
  552. $this->classes[] = $class;
  553. }
  554. return $this;
  555. }
  556. /**
  557. * Remove a class from the Element
  558. * @param string $class
  559. * @return Staple_Form_Element
  560. */
  561. public function removeClass($class)
  562. {
  563. if(($key = array_search($class, $this->classes)) !== false)
  564. {
  565. unset($this->classes[$key]);
  566. }
  567. return $this;
  568. }
  569. /**
  570. * Returns the classes array as a string
  571. * @return string
  572. */
  573. public function getClassString()
  574. {
  575. if(count($this->classes) >= 1)
  576. {
  577. $ctemp = ' class="';
  578. foreach($this->classes as $class)
  579. {
  580. $ctemp .= $this->escape($class).' ';
  581. }
  582. $ctemp = substr($ctemp, 0, strlen($ctemp)-1).'"';
  583. return $ctemp;
  584. }
  585. else
  586. {
  587. return '';
  588. }
  589. }
  590. /**
  591. * Returns the classes array.
  592. * @return array[string]
  593. */
  594. public function getCSSClasses()
  595. {
  596. return $this->classes;
  597. }
  598. /**
  599. * Returns all the attributes formatted as and HTML string.
  600. * @return string
  601. */
  602. public function getAttribString()
  603. {
  604. $attribs = '';
  605. if($this->isDisabled())
  606. {
  607. $attribs .= ' disabled';
  608. }
  609. if($this->isReadOnly())
  610. {
  611. $attribs .= ' readOnly';
  612. }
  613. $attribs .= $this->getClassString();
  614. foreach($this->attrib as $key=>$value)
  615. {
  616. $attribs .= ' '.$this->escape($key).'="'.$this->escape($value).'"';
  617. }
  618. return $attribs;
  619. }
  620. /*
  621. * -------------------------------------FORM FUNCTIONS-------------------------------------
  622. */
  623. /**
  624. * Build the field instructions
  625. */
  626. public function instructions()
  627. {
  628. if(strlen($this->instructions) > 0)
  629. {
  630. return ' <p class="field_instructions">'.$this->escape($this->instructions).'</p>';
  631. }
  632. else
  633. {
  634. return '';
  635. }
  636. }
  637. /**
  638. * Build the field label
  639. */
  640. abstract public function label();
  641. /**
  642. * Build the field itself
  643. */
  644. abstract public function field();
  645. /**
  646. * Build the field using a layout, or with the default build.
  647. */
  648. abstract public function build();
  649. /*----------------------------------------Helpers----------------------------------------*/
  650. /**
  651. *
  652. * If an array is supplied, a link is created to a controller/action. If a string is
  653. * supplied, a file link is specified.
  654. * @param string | array $link
  655. * @param array $get
  656. * @return string
  657. */
  658. public function link($link,array $get = array())
  659. {
  660. return Staple_Main::get()->link($link,$get);
  661. }
  662. }