PHPonTrax
[ class tree: PHPonTrax ] [ index: PHPonTrax ] [ all elements ]

Source for file form_helper.php

Documentation is available at form_helper.php

  1. <?php
  2. /**
  3. * File containing the FormHelper class
  4. *
  5. * (PHP 5)
  6. *
  7. * @package PHPonTrax
  8. * @version $Id$
  9. * @copyright (c) 2005 John Peterson
  10. *
  11. * Permission is hereby granted, free of charge, to any person obtaining
  12. * a copy of this software and associated documentation files (the
  13. * "Software"), to deal in the Software without restriction, including
  14. * without limitation the rights to use, copy, modify, merge, publish,
  15. * distribute, sublicense, and/or sell copies of the Software, and to
  16. * permit persons to whom the Software is furnished to do so, subject to
  17. * the following conditions:
  18. *
  19. * The above copyright notice and this permission notice shall be
  20. * included in all copies or substantial portions of the Software.
  21. *
  22. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  23. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  24. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  25. * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  26. * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  27. * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  28. * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  29. */
  30.  
  31. /**
  32. * @todo Document this class
  33. */
  34. class FormHelper extends Helpers {
  35.  
  36. /**
  37. * Default attributes for input fields
  38. * @var string[]
  39. */
  40. private $default_field_options = array();
  41.  
  42. /**
  43. * Default attributes for radio buttons
  44. * @var string[]
  45. */
  46. private $default_radio_options = array();
  47.  
  48. /**
  49. * Default attributes for text areas
  50. * @var string[]
  51. */
  52. private $default_text_area_options = array();
  53.  
  54. /**
  55. * Default attributes for dates
  56. * @var string[]
  57. */
  58. private $default_date_options = array();
  59.  
  60. /**
  61. * @todo Document this method
  62. * @uses default_date_options
  63. * @uses default_field_options
  64. * @uses default_radio_options
  65. * @uses default_text_area_options
  66. */
  67. function __construct($object_name, $attribute_name) {
  68. parent::__construct($object_name, $attribute_name);
  69.  
  70. // Set default attributes for input fields
  71. $this->default_field_options =
  72. array_key_exists('DEFAULT_FIELD_OPTIONS',$GLOBALS)
  73. ? $GLOBALS['DEFAULT_FIELD_OPTIONS']
  74. : array("size" => 30);
  75.  
  76. // Set default attributes for radio buttons
  77. $this->default_radio_options =
  78. array_key_exists('DEFAULT_RADIO_OPTIONS',$GLOBALS)
  79. ? $GLOBALS['DEFAULT_RADIO_OPTIONS']
  80. : array();
  81.  
  82. // Set default attributes for text areas
  83. $this->default_text_area_options =
  84. array_key_exists('DEFAULT_TEXT_AREA_OPTIONS',$GLOBALS)
  85. ? $GLOBALS['DEFAULT_TEXT_AREA_OPTIONS']
  86. : array("cols" => 40, "rows" => 20);
  87.  
  88. // Set default attributes for dates
  89. $this->default_date_options =
  90. array_key_exists('DEFAULT_Date_OPTIONS',$GLOBALS)
  91. ? $GLOBALS['DEFAULT_DATE_OPTIONS']
  92. : array(":discard_type" => true);
  93. }
  94.  
  95. /**
  96. * @todo Document this method
  97. */
  98. function tag_name() {
  99. return "{$this->object_name}[{$this->attribute_name}]";
  100. }
  101.  
  102. /**
  103. * @todo Document this method
  104. */
  105. function tag_name_with_index($index) {
  106. return "{$this->object_name}[{$index}][{$this->attribute_name}]";
  107. }
  108.  
  109. /**
  110. * @todo Document this method
  111. */
  112. function tag_id() {
  113. return "{$this->object_name}_{$this->attribute_name}";
  114. }
  115.  
  116. /**
  117. * @todo Document this method
  118. */
  119. function tag_id_with_index($index) {
  120. return "{$this->object_name}_{$index}_{$this->attribute_name}";
  121. }
  122.  
  123. /**
  124. * @todo Document this method
  125. * @param string[]
  126. * @uses auto_index
  127. * @uses tag_id
  128. * @uses tag_name
  129. * @uses tag_id_with_index()
  130. * @uses tag_name_with_index()
  131. */
  132. function add_default_name_and_id($options) {
  133. if(array_key_exists("index", $options)) {
  134. $options["name"] = array_key_exists("name", $options)
  135. ? $options["name"]
  136. : $this->tag_name_with_index($options["index"]);
  137. $options["id"] = array_key_exists("id", $options)
  138. ? $options["id"]
  139. : $this->tag_id_with_index($options["index"]);
  140. unset($options["index"]);
  141. } elseif($this->auto_index) {
  142. $options["name"] = array_key_exists("name", $options)
  143. ? $options["name"]
  144. : $this->tag_name_with_index($this->auto_index);
  145. $options["id"] = array_key_exists("id", $options)
  146. ? $options["id"]
  147. : $this->tag_id_with_index($this->auto_index);
  148. } else {
  149. $options["name"] = array_key_exists("name", $options)
  150. ? $options["name"]
  151. : $this->tag_name();
  152. $options["id"] = array_key_exists("id", $options)
  153. ? $options["id"]
  154. : $this->tag_id();
  155. }
  156. return $options;
  157. }
  158.  
  159. /**
  160. * Generate an HTML or XML input tag with optional attributes
  161. *
  162. * @param string Type of input field (<samp>'text'</samp>,
  163. * <samp>'password'</samp>, <samp>'hidden'</samp>
  164. * <i>etc.</i>)
  165. * @param string[] Attributes to apply to the input tag:<br>
  166. * <samp>array('attr1' => 'value1'[, 'attr2' => 'value2']...)</samp>
  167. * @return string
  168. * <samp><input type="</samp><i>type</i>
  169. * <samp>" maxlength="</samp><i>maxlength</i><samp>" .../>\n</samp>
  170. * @uses add_default_name_and_id()
  171. * @uses attribute_name
  172. * @uses error_wrapping
  173. * @uses default_field_options
  174. * @uses object()
  175. * @uses tag()
  176. * @uses value()
  177. */
  178. function to_input_field_tag($field_type, $options = array()) {
  179. $default_size = array_key_exists("maxlength", $options)
  180. ? $options["maxlength"] : $this->default_field_options['size'];
  181. $options["size"] = array_key_exists("size", $options)
  182. ? $options["size"]: $default_size;
  183. $options = array_merge($this->default_field_options, $options);
  184. if($field_type == "hidden") {
  185. unset($options["size"]);
  186. }
  187. $options["type"] = $field_type;
  188. if($field_type != "file") {
  189. $options["value"] = array_key_exists("value", $options)
  190. ? $options["value"] : $this->value();
  191. }
  192. $options = $this->add_default_name_and_id($options);
  193. return $this->error_wrapping(
  194. $this->tag("input", $options),
  195. @array_key_exists($this->attribute_name,
  196. $this->object()->errors)
  197. ? true : false);
  198. }
  199.  
  200. /**
  201. * @todo Document this method
  202. * @uses add_default_name_and_id()
  203. */
  204. function to_radio_button_tag($tag_value, $options = array()) {
  205. $options = array_merge($this->default_radio_options, $options);
  206. $options["type"] = "radio";
  207. $options["value"] = $tag_value;
  208. if($this->value() == $tag_value) {
  209. $options["checked"] = "checked";
  210. }
  211. $pretty_tag_value = preg_replace('/\s/', "_", preg_replace('/\W/', "", strtolower($tag_value)));
  212. $options["id"] = $this->auto_index ?
  213. "{$this->object_name}_{$this->auto_index}_{$this->attribute_name}_{$pretty_tag_value}" :
  214. "{$this->object_name}_{$this->attribute_name}_{$pretty_tag_value}";
  215. $options = $this->add_default_name_and_id($options);
  216. return $this->error_wrapping($this->tag("input", $options),$this->object()->errors[$this->attribute_name]);
  217. }
  218.  
  219. /**
  220. * @todo Document this method
  221. * @uses add_default_name_and_id()
  222. */
  223. function to_text_area_tag($options = array()) {
  224. if (array_key_exists("size", $options)) {
  225. $size = explode('x', $options["size"]);
  226. $options["cols"] = reset($size);
  227. $options["rows"] = end($size);
  228. unset($options["size"]);
  229. }
  230. $options = array_merge($this->default_text_area_options, $options);
  231. $options = $this->add_default_name_and_id($options);
  232. return $this->error_wrapping(
  233. $this->content_tag("textarea",
  234. htmlspecialchars($this->value()),
  235. $options),
  236. array_key_exists($this->attribute_name,$this->object()->errors)
  237. ? $this->object()->errors[$this->attribute_name] : false);
  238. }
  239.  
  240. /**
  241. * @todo Document this method
  242. * @uses add_default_name_and_id()
  243. */
  244. function to_check_box_tag($options = array(), $checked_value = "1", $unchecked_value = "0") {
  245. $options["type"] = "checkbox";
  246. $options["value"] = $checked_value;
  247. switch(gettype($this->value())) {
  248. case 'boolean':
  249. $checked = $this->value();
  250. break;
  251. case 'NULL':
  252. $checked = false;
  253. break;
  254. case 'integer':
  255. $checked = ($this->value() != 0);
  256. break;
  257. case 'string':
  258. $checked = ($this->value() == $checked_value);
  259. break;
  260. default:
  261. $checked = ($this->value() != 0);
  262. }
  263.  
  264. if ($checked || $options["checked"] == "checked") {
  265. $options["checked"] = "checked";
  266. } else {
  267. unset($options["checked"]);
  268. }
  269.  
  270. $options = $this->add_default_name_and_id($options);
  271. return $this->error_wrapping($this->tag("input", $options) . $this->tag("input", array("name" => $options["name"], "type" => "hidden", "value" => $unchecked_value)),$this->object()->errors[$this->attribute_name]);
  272. }
  273.  
  274. /**
  275. * @todo Document this method
  276. * @uses add_default_name_and_id()
  277. */
  278. function to_boolean_select_tag($options = array()) {
  279. $options = $this->add_default_name_and_id($options);
  280. $tag_text = "<select ";
  281. $tag_text .= $this->tag_options($options);
  282. $tag_text .= ">\n";
  283. $tag_text .= "<option value=\"0\"";
  284. if($this->value() == false) {
  285. $tag_text .= " selected";
  286. }
  287. $tag_text .= ">False</option>\n";
  288. $tag_text .= "<option value=\"1\"";
  289. if($this->value()) {
  290. $tag_text .= " selected";
  291. }
  292. $tag_text .= ">True</option>\n";
  293. $tag_text .= "</select>\n";
  294. return $this->error_wrapping($tag_text,$this->object()->errors[$this->attribute_name]);;
  295. }
  296. /**
  297. * If this tag has an error, wrap it with a visual indicator
  298. *
  299. * @param string HTML to be wrapped
  300. * @param boolean true=>error, false=>no error
  301. * @return string
  302. */
  303. function error_wrapping($html_tag, $has_error) {
  304. return ($has_error
  305. ? '<span class="fieldWithErrors">' . $html_tag . '</span>'
  306. : $html_tag);
  307. }
  308.  
  309. }
  310.  
  311.  
  312. /**
  313. * Generate HTML/XML for <input type="text" /> in a view file
  314. *
  315. * Example: In the view file, code
  316. * <code><?= text_field("Person", "fname"); ?></code>
  317. * Result: <input id="Person_fname" name="Person[fname]" size="30" type="text" value="$Person->fname" />
  318. * @param string Class name of the object being processed
  319. * @param string Name of attribute in the object being processed
  320. * @param string[] Attributes to apply to the generated input tag as:<br>
  321. * <samp>array('attr1' => 'value1'[, 'attr2' => 'value2']...)</samp>
  322. * @uses FormHelper::to_input_field_tag()
  323. */
  324. function text_field($object, $field, $options = array()) {
  325. $form = new FormHelper($object, $field);
  326. return $form->to_input_field_tag("text", $options);
  327. }
  328.  
  329. /**
  330. * Works just like text_field, but returns a input tag of the "password" type instead.
  331. * Example: password_field("user", "password");
  332. * Result: <input type="password" id="user_password" name="user[password]" value="$user->password" />
  333. * @uses FormHelper::to_input_field_tag()
  334. */
  335. function password_field($object, $field, $options = array()) {
  336. $form = new FormHelper($object, $field);
  337. return $form->to_input_field_tag("password", $options);
  338. }
  339.  
  340. /**
  341. * Works just like text_field, but returns a input tag of the "hidden" type instead.
  342. * Example: hidden_field("post", "title");
  343. * Result: <input type="hidden" id="post_title" name="post[title]" value="$post->title" />
  344. * @uses FormHelper::to_input_field_tag()
  345. */
  346. function hidden_field($object, $field, $options = array()) {
  347. $form = new FormHelper($object, $field);
  348. return $form->to_input_field_tag("hidden", $options);
  349. }
  350.  
  351. /**
  352. * Works just like text_field, but returns a input tag of the "file" type instead, which won't have any default value.
  353. * @uses FormHelper::to_input_field_tag()
  354. */
  355. function file_field($object, $field, $options = array()) {
  356. $form = new FormHelper($object, $field);
  357. return $form->to_input_field_tag("file", $options);
  358. }
  359.  
  360. /**
  361. * Example: text_area("post", "body", array("cols" => 20, "rows" => 40));
  362. * Result: <textarea cols="20" rows="40" id="post_body" name="post[body]">$post->body</textarea>
  363. * @uses FormHelper::to_text_area_tag()
  364. */
  365. function text_area($object, $field, $options = array()) {
  366. $form = new FormHelper($object, $field);
  367. return $form->to_text_area_tag($options);
  368. }
  369.  
  370. /**
  371. * Returns a checkbox tag tailored for accessing a specified attribute (identified by $field) on an object
  372. * assigned to the template (identified by $object). It's intended that $field returns an integer and if that
  373. * integer is above zero, then the checkbox is checked. Additional $options on the input tag can be passed as an
  374. * array with $options. The $checked_value defaults to 1 while the default $unchecked_value
  375. * is set to 0 which is convenient for boolean values. Usually unchecked checkboxes don't post anything.
  376. * We work around this problem by adding a hidden value with the same name as the checkbox.
  377. #
  378. * Example: Imagine that $post->validated is 1:
  379. * check_box("post", "validated");
  380. * Result:
  381. * <input type="checkbox" id="post_validate" name="post[validated] value="1" checked="checked" />
  382. * <input name="post[validated]" type="hidden" value="0" />
  383. #
  384. * Example: Imagine that $puppy->gooddog is no:
  385. * check_box("puppy", "gooddog", array(), "yes", "no");
  386. * Result:
  387. * <input type="checkbox" id="puppy_gooddog" name="puppy[gooddog] value="yes" />
  388. * <input name="puppy[gooddog]" type="hidden" value="no" />
  389. * @uses FormHelper::to_check_box_tag()
  390. */
  391. function check_box($object, $field, $options = array(), $checked_value = "1", $unchecked_value = "0") {
  392. $form = new FormHelper($object, $field);
  393. return $form->to_check_box_tag($options, $checked_value, $unchecked_value);
  394. }
  395.  
  396. /**
  397. * Returns a radio button tag for accessing a specified attribute (identified by $field) on an object
  398. * assigned to the template (identified by $object). If the current value of $field is $tag_value the
  399. * radio button will be checked. Additional $options on the input tag can be passed as a
  400. * hash with $options.
  401. * Example: Imagine that $post->category is "trax":
  402. * radio_button("post", "category", "trax");
  403. * radio_button("post", "category", "java");
  404. * Result:
  405. * <input type="radio" id="post_category" name="post[category] value="trax" checked="checked" />
  406. * <input type="radio" id="post_category" name="post[category] value="java" />
  407. * @uses FormHelper::to_radio_button_tag()
  408. */
  409. function radio_button($object, $field, $tag_value, $options = array()) {
  410. $form = new FormHelper($object, $field);
  411. return $form->to_radio_button_tag($tag_value, $options);
  412. }
  413.  
  414. /**
  415. * Make a new FormHelper object and call its to_boolean_select_tag method
  416. * @uses FormHelper::to_boolean_select_tag()
  417. */
  418. function boolean_select($object, $field, $options = array()) {
  419. $form = new FormHelper($object, $field);
  420. return $form->to_boolean_select_tag($options);
  421. }
  422.  
  423. // -- set Emacs parameters --
  424. // Local variables:
  425. // tab-width: 4
  426. // c-basic-offset: 4
  427. // c-hanging-comment-ender-p: nil
  428. // indent-tabs-mode: nil
  429. // End:

Documentation generated on Thu, 04 May 2006 19:47:41 -0600 by phpDocumentor 1.3.0RC4