a tiny mvc framework for php using php-activerecord
at master 232 lines 7.0 kB view raw
1<?php 2/* 3 build a <form> based on an object 4*/ 5 6namespace HalfMoon; 7 8require_once("form_common.php"); 9 10class FormHelper extends FormTagHelper { 11 public function form_for($obj, $url_or_obj, $options = array(), 12 \Closure $form_content) { 13 if (!$obj) 14 throw new HalfMoonException("invalid object passed to form_for()"); 15 16 $this->form_object = $obj; 17 18 return $this->output_form_around_closure($url_or_obj, $options, 19 $form_content); 20 } 21 22 public function form_content_for($obj, $url_or_obj, $options = array(), 23 \Closure $form_content) { 24 if (!$obj) 25 throw new HalfMoonException("invalid object passed to form_for()"); 26 27 $this->form_object = $obj; 28 29 $html = Utils::to_s($this, $form_content); 30 31 $this->form_object = null; 32 33 return $html; 34 } 35 36 /* the prefix to use for class and id names for fields */ 37 protected function form_prefix() { 38 if (empty($this->form_prefix)) 39 return strtolower(get_class($this->form_object)); 40 else 41 return $this->form_prefix; 42 } 43 44 /* provide an html object id to use for a given field name */ 45 public function prefixed_field_id($field) { 46 return preg_replace("/[^a-z0-9]/", "_", 47 $this->form_prefix() . "_" . $field); 48 } 49 50 /* provide an html object name to use for a given field name */ 51 public function prefixed_field_name($field) { 52 return $this->form_prefix() . "[" . $field . "]"; 53 } 54 55 /* return the value of the particular field for the form object */ 56 protected function value_for_field($field, $options) { 57 /* value is being statically overridden */ 58 if (isset($options["value"])) 59 return $options["value"]; 60 /* if we have an array-looking name of field[var], use an AR getter of 61 * field(var) */ 62 elseif (preg_match("/^(.+)\[([^\]]+)\]$/", $field, $m)) 63 return $this->form_object->{"get_" . $m[1]}($m[2]); 64 else 65 return $this->form_object->$field; 66 } 67 68 /* honor names/ids passed through as options */ 69 private function set_field_id_and_name($field, $options) { 70 if (!isset($options["id"])) 71 $options["id"] = $this->prefixed_field_id($field); 72 73 if (!isset($options["name"])) 74 $options["name"] = $this->prefixed_field_name($field); 75 76 return $options; 77 } 78 79 /* create an <input type="checkbox"> with a hidden input field to detect 80 * when the checkbox has been unchecked (see rails docs for check_box, but 81 * since php presents $_GET and $_POST with the last seen value, we have to 82 * reverse the order of the checkbox and hidden input field) */ 83 public function check_box($field, $options = array(), $checked_value = 1, 84 $unchecked_value = 0) { 85 if (!$this->form_object) 86 throw new HalfMoonException("no form object; you probably wanted " 87 . "check_box_tag"); 88 89 $options = $this->set_field_id_and_name($field, $options); 90 91 return "<input" 92 . " type=\"hidden\" " 93 . " name=\"" . h($options["name"]) . "\"" 94 . " value=\"" . h($unchecked_value) . "\"" 95 . " />" 96 . $this->wrap_field_with_errors($field, 97 $this->check_box_tag($field, $checked_value, 98 (bool)$this->value_for_field($field, $options), $options) 99 ); 100 } 101 102 /* create an <input> file upload field */ 103 public function file_field($field, $options = array()) { 104 if (!$this->form_object) 105 throw new HalfMoonException("no form object; you probably wanted " 106 . "file_field_tag"); 107 108 $options = $this->set_field_id_and_name($field, $options); 109 110 return $this->wrap_field_with_errors($field, 111 $this->file_field_tag($field, $options) 112 ); 113 } 114 115 /* create a hidden <input> field */ 116 public function hidden_field($field, $options = array()) { 117 if (!$this->form_object) 118 throw new HalfMoonException("no form object; you probably wanted " 119 . "hidden_field_tag"); 120 121 $options = $this->set_field_id_and_name($field, $options); 122 123 return $this->hidden_field_tag($field, $this->value_for_field($field, 124 $options), $options); 125 } 126 127 /* create a <label> that references a field */ 128 public function label($field, $caption = null, $options = array()) { 129 if (!$this->form_object) 130 throw new HalfMoonException("no form object; you probably wanted " 131 . "label_tag"); 132 133 if (!isset($options["for"])) 134 $options["for"] = $this->prefixed_field_id($field); 135 136 return $this->label_tag($field, $caption, $options); 137 } 138 139 /* create an <input> password field, *not including any value* */ 140 public function password_field($field, $options = array()) { 141 if (!$this->form_object) 142 throw new HalfMoonException("no form object; you probably wanted " 143 . "password_field_tag"); 144 145 $options = $this->set_field_id_and_name($field, $options); 146 147 return $this->wrap_field_with_errors($field, 148 $this->password_field_tag($field, $value = null, $options) 149 ); 150 } 151 152 /* create an <input> radio button */ 153 public function radio_button($field, $value, $options = array()) { 154 if (!$this->form_object) 155 throw new HalfMoonException("no form object; you probably wanted " 156 . "radio_button_tag"); 157 158 $options = $this->set_field_id_and_name($field, $options); 159 160 return $this->wrap_field_with_errors($field, 161 $this->radio_button_tag($field, $value, 162 ($this->value_for_field($field, $options) == $value), $options) 163 ); 164 } 165 166 /* create a <select> box with options */ 167 public function select($field, $choices, $options = array()) { 168 if (!$this->form_object) 169 throw new HalfMoonException("no form object; you probably wanted " 170 . "select_tag"); 171 172 $options = $this->set_field_id_and_name($field, $options); 173 174 return $this->wrap_field_with_errors($field, 175 $this->select_tag($field, $choices, $this->value_for_field($field, 176 $options), $options) 177 ); 178 } 179 180 /* create an <input> submit button */ 181 public function submit_button($value = "Submit Changes", 182 $options = array()) { 183 if (!isset($options["name"])) 184 $options["name"] = "commit"; 185 186 return $this->submit_tag($value, $options); 187 } 188 189 /* create a <textarea> field */ 190 public function text_area($field, $options = array()) { 191 if (!$this->form_object) 192 throw new HalfMoonException("no form object; you probably wanted " 193 . "text_area_tag"); 194 195 $options = $this->set_field_id_and_name($field, $options); 196 197 return $this->wrap_field_with_errors($field, 198 $this->text_area_tag($field, $this->value_for_field($field, 199 $options), $options) 200 ); 201 } 202 203 /* create an <input> text field */ 204 public function text_field($field, $options = array()) { 205 if (!$this->form_object) 206 throw new HalfMoonException("no form object; you probably wanted " 207 . "text_field_tag"); 208 209 $options = $this->set_field_id_and_name($field, $options); 210 211 return $this->wrap_field_with_errors($field, 212 $this->text_field_tag($field, $this->value_for_field($field, 213 $options), $options) 214 ); 215 } 216 217 /* create a <select> of grouped time zones */ 218 public function time_zone_select($field, $options = array()) { 219 if (!$this->form_object) 220 throw new HalfMoonException("no form object; you probably wanted " 221 . "time_zone_select_tag"); 222 223 $options = $this->set_field_id_and_name($field, $options); 224 225 return $this->wrap_field_with_errors($field, 226 $this->time_zone_select_tag($field, 227 $this->value_for_field($field, $options), $options) 228 ); 229 } 230} 231 232?>