a tiny mvc framework for php using php-activerecord
1<?php
2/*
3 html-related helpers
4*/
5
6namespace HalfMoon;
7
8class HtmlHelper extends Helper {
9 /* like link_to but use a button */
10 public function button_to($text, $obj_or_url, $options = array()) {
11 if (!isset($options["method"]))
12 $options["method"] = "post";
13
14 return "<input type=\"button\" value=\"" . raw_or_h($text) . "\" "
15 . $this->options_for_link($options,
16 $this->link_from_obj_or_string($obj_or_url))
17 . " />";
18 }
19
20 public function button_to_function($label, $options = array()) {
21 if (!is_array($options))
22 $options = array("onclick" => $options);
23
24 if (!isset($options["html_options"]))
25 $options["html_options"] = array();
26
27 if (!isset($options["html_options"]["type"]))
28 $options["html_options"]["type"] = "button";
29
30 return "<input"
31 . " value=\"" . raw_or_h($label) . "\""
32 . " onclick=\"" . raw_or_h($options["onclick"]) . "\""
33 . $this->options_for_link($options["html_options"])
34 . " />";
35 }
36
37 /* summarize errors for an activerecord object */
38 public function error_messages_for($obj, $obj_name = "", $obj_prefix = "") {
39 if ($obj->errors && $obj->errors->size()) {
40 if ($obj_name == "")
41 $obj_name = \ActiveRecord\Utils::singularize(strtolower(
42 get_class($obj)));
43
44 if ($obj_prefix == "") {
45 if (\ActiveRecord\Utils::pluralize_if(2, $obj_name) == "2 "
46 . $obj_name)
47 $obj_prefix = "these";
48 else
49 $obj_prefix = "this";
50 }
51
52 $html = "<p>"
53 . "<div class=\"flash-error\">"
54 . "<strong>" . $obj->errors->size() . " "
55 . h(\ActiveRecord\Utils::pluralize_if($obj->errors->size(),
56 "error"))
57 . " prohibited " . raw_or_h($obj_prefix) . " "
58 . raw_or_h($obj_name) . " from being "
59 . ($obj->is_new_record() ? "created" : "saved")
60 . ":</strong><br />\n";
61
62 foreach ($obj->errors as $err)
63 $html .= raw_or_h($err) . "<br />";
64
65 $html .= "</div>"
66 . "</p>";
67
68 return $html;
69 }
70 }
71
72 /* print the errors stored in the session and then reset the array */
73 public function flash_errors() {
74 $html = "";
75
76 if (isset($_SESSION["flash_errors"]) &&
77 count((array)$_SESSION["flash_errors"])) {
78 $html = "<div class=\"flash-error\">"
79 . implode("<br />\n", array_map(function($e) {
80 return raw_or_h($e); },
81 (array)$_SESSION["flash_errors"]))
82 . "</div>";
83
84 /* clear out for the next view */
85 $_SESSION["flash_errors"] = array();
86 }
87
88 return $html;
89 }
90
91 /* print the notices stored in the session and then reset the array */
92 public function flash_notices() {
93 $html = "";
94
95 if (isset($_SESSION["flash_notices"]) &&
96 count((array)$_SESSION["flash_notices"])) {
97 /* not escaped */
98 $html = "<div class=\"flash-notice\">"
99 . implode("<br />\n", array_map(function($e) {
100 return raw_or_h($e); },
101 (array)$_SESSION["flash_notices"]))
102 . "</div>";
103
104 /* clear out for the next view */
105 $_SESSION["flash_notices"] = array();
106 }
107
108 return $html;
109 }
110
111 /* print the successes stored in the session and then reset the array */
112 public function flash_successes() {
113 $html = "";
114
115 if (isset($_SESSION["flash_successes"]) &&
116 count((array)$_SESSION["flash_successes"])) {
117 $html = "<div class=\"flash-success\">"
118 . implode("<br />\n", array_map(function($e) {
119 return raw_or_h($e); },
120 (array)$_SESSION["flash_successes"]))
121 . "</div>";
122
123 /* clear out for the next view */
124 $_SESSION["flash_successes"] = array();
125 }
126
127 return $html;
128 }
129
130 /* create a link to a javascript file, appending its modification time to
131 * force clients to reload it when it's modified */
132 public function javascript_include_tag($files) {
133 $out = "";
134
135 if (!is_array($files))
136 $files = array($files);
137
138 foreach ($files as $file) {
139 if (preg_match("/^(https?:)?\/\//", $file))
140 $out .= "<script type=\"text/javascript\" src=\"" . $file
141 . "\"></script>\n";
142 else {
143 $file_value = $file;
144
145 if (!strpos($file_value, "?")) {
146 if (!preg_match("/\.js$/i", $file_value))
147 $file_value .= ".js";
148
149 $mtime = 0;
150 if (file_exists(HALFMOON_ROOT . "/public/javascripts/"
151 . $file_value))
152 $file_value .= "?" . filemtime(HALFMOON_ROOT
153 . "/public/javascripts/" . $file_value);
154 }
155
156 $out .= "<script type=\"text/javascript\" src=\""
157 . h("/javascripts/" . $file_value)
158 . "\"></script>\n";
159 }
160 }
161
162 return $out;
163 }
164
165 /* return a url string from an object/array or a url string */
166 public function link_from_obj_or_string($thing) {
167 $link = "";
168
169 /* passed an object, redirect to its show url */
170 if (is_object($thing)) {
171 $class = get_class($thing);
172 $link = "/" . $class::table()->table . "/show/" . $thing->id;
173 }
174
175 /* passed an array, figure out what to do */
176 elseif (is_array($thing)) {
177 $link = "/";
178
179 /* if no controller, assume the current one */
180 if (isset($thing["controller"]))
181 $link .= $thing["controller"];
182 else
183 $link .= strtolower(preg_replace("/Controller$/", "",
184 Utils::current_controller_name()));
185
186 if (isset($thing["action"]))
187 $link .= "/" . $thing["action"];
188
189 if (isset($thing["id"]) && $thing["id"])
190 $link .= "/" . $thing["id"];
191
192 /* anything else in the array is assumed to be passed as get
193 * args */
194 $url_params = "";
195 foreach ($thing as $k => $v) {
196 if (in_array($k, array("controller", "action", "id", "anchor")))
197 continue;
198
199 $url_params .= ($url_params == "" ? "" : "&") . urlencode($k)
200 . "=" . urlencode($v);
201 }
202
203 if ($url_params != "")
204 $link .= "?" . $url_params;
205
206 if (isset($thing["anchor"]))
207 $link .= "#" . h($thing["anchor"]);
208 }
209
210 /* assume we were passed a url */
211 else
212 $link = $thing;
213
214 return $link;
215 }
216
217 /* create an <a href> tag for a given url or object (defaulting to
218 * the (table)/show/(id) */
219 public function link_to($text, $obj_or_url, $options = array()) {
220 return "<a href=\""
221 . raw_or_h($this->link_from_obj_or_string($obj_or_url)) . "\""
222 . $this->options_for_link($options) . ">" . raw_or_h($text)
223 . "</a>";
224 }
225
226 public function options_for_link($options = array(),
227 $button_target = null) {
228 $opts_s = "";
229
230 if (isset($options["confirm"]) && is_bool($options["confirm"]))
231 $options["confirm"] = "Are you sure?";
232
233 if (isset($options["method"])) {
234 $opts_s .= " onclick=\"";
235
236 if (isset($options["confirm"]))
237 $opts_s .= "if (confirm('" . $options["confirm"] . "')) ";
238
239 $opts_s .= "{ var f = document.createElement('form'); "
240 . "f.style.display = 'none'; "
241 . "f.method = '" . $options["method"] . "'; "
242 . "f.action = " . ($button_target ? "'" . $button_target . "'" :
243 "this.href") . "; "
244 . "this.parentNode.appendChild(f); ";
245
246 if (strtolower($options["method"]) != "get")
247 $opts_s .= "var t = document.createElement('input'); "
248 . "t.type = 'hidden'; t.name = 'authenticity_token'; "
249 . "t.value = '" . h(Utils::current_controller()->
250 form_authenticity_token()) . "'; "
251 . "f.appendChild(t); ";
252
253 $opts_s .= "f.submit(); }; return false;\"";
254
255 unset($options["confirm"]);
256 unset($options["method"]);
257 }
258
259 if (isset($options["confirm"])) {
260 $opts_s .= " onclick=\"return confirm('" . $options["confirm"]
261 . "');\"";
262 unset($options["confirm"]);
263 }
264
265 if (isset($options["popup"])) {
266 $opts_s .= " onclick=\"window.open(this.href); return false;\"";
267 unset($options["popup"]);
268 }
269
270 foreach ((array)$options as $k => $v)
271 $opts_s .= " " . $k . "=\"" . $v . "\"";
272
273 return $opts_s;
274 }
275
276 /* create a link to a css file, appending its modification time to force
277 * clients to reload it when it's modified */
278 public function stylesheet_link_tag($files, $options = array()) {
279 $out = "";
280
281 if (!is_array($files))
282 $files = array($files);
283
284 foreach ($files as $file) {
285 if (preg_match("/^(https?:)?\/\//", $file))
286 $out .= "<link href=\"" . $file . "\" media=\"screen\" "
287 . "rel=\"stylesheet\" type=\"text/css\"/>\n";
288 else {
289 $file_value = $file;
290
291 if (!strpos($file_value, "?")) {
292 if (!preg_match("/\.css$/i", $file_value))
293 $file_value .= ".css";
294
295 $mtime = 0;
296 if (file_exists(HALFMOON_ROOT . "/public/stylesheets/"
297 . $file_value))
298 $file_value .= "?" . filemtime(HALFMOON_ROOT
299 . "/public/stylesheets/" . $file_value);
300 }
301
302 if (isset($options["xml"]))
303 $out .= "<?xml-stylesheet type=\"text/css\" "
304 . "href=\"" . h("/stylesheets/" . $file_value)
305 . "\" ?" . ">\n";
306 else
307 $out .= "<link href=\"/" . h("stylesheets/"
308 . $file_value) . "\" media=\"screen\" "
309 . "rel=\"stylesheet\" type=\"text/css\"/>\n";
310 }
311 }
312
313 return $out;
314 }
315}
316
317?>