JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
metaform: merge ckeditor settings from cms
[wfpl.git] / encode.php
1 <?php
2
3 #  Copyright (C) 2005 Jason Woofenden
4 #
5 #  This program is free software: you can redistribute it and/or modify
6 #  it under the terms of the GNU General Public License as published by
7 #  the Free Software Foundation, either version 3 of the License, or
8 #  (at your option) any later version.
9 #  
10 #  This program is distributed in the hope that it will be useful,
11 #  but WITHOUT ANY WARRANTY; without even the implied warranty of
12 #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 #  GNU General Public License for more details.
14 #  
15 #  You should have received a copy of the GNU General Public License
16 #  along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
18
19 # This file contains basic encodings. These are used by the encoder. You can
20 # specify any template tag to be encoded with this syntax: ~variable encoding~
21 #
22 # this example: <p>~foo html~</p>
23 # will encode foo (using enc_html()) before displaying it, so that characters
24 # such as < will display properly.
25
26 function enc_cap($str) {
27         $str = ucfirst($str);
28         return $str;
29 }
30
31 # quote for placing between single quotes in php
32 function enc_phpsq($str) {
33         $str = str_replace("\\", "\\\\", $str);
34         $str = str_replace("'", "\\'", $str);
35         return $str;
36 }
37
38 function enc_jsdq($str) {
39         $str = enc_sql($str);
40         $str = str_replace("\n", "\\n", $str);
41         $str = str_replace("\r", "\\r", $str);
42         return $str;
43 }
44
45 # encode for putting within double-quotes in SQL
46 function enc_sql($str) {
47         $str = str_replace("\\", "\\\\", $str);
48         $str = str_replace('"', "\\\"", $str);
49         return $str;
50 }
51
52 # Encode for output in html. does nothing with whitespace
53 #
54 # Example: <p>~foo html~</p>
55 function enc_html($str) {
56         $str = str_replace('&', '&amp;', $str);
57         $str = str_replace('<', '&lt;', $str);
58         $str = str_replace('>', '&gt;', $str);
59         return $str;
60 }
61
62 # Encode for output in html. Convert newlines to <br>
63 #
64 # Example: <p>~foo htmlbr~</p>
65 function enc_htmlbr($str) {
66         $str = enc_html($str);
67         $str = str_replace("\n", "<br>\n", $str);
68         return $str;
69 }
70
71 # Encode for output in html. Preserves newlines and indentation by converting
72 # newlines to <br> and spaces/tabs at the begining of lines to &nbsp;s
73 #
74 # Example: <p>~foo htmlbrtab~</p>
75 function enc_htmlbrtab($str) {
76         $str = enc_htmlbr($str);
77         $whitespace_to_nbsp = create_function('$matches', '$count = 0; $chars = str_split($matches[0]); foreach ($chars as $c) { if ($c == " ") { $count += 2; } else if ($c == "\t") { $count += 8; } } return str_repeat("&nbsp;", $count);');
78         $str = preg_replace_callback("|^[ \t]+|m", $whitespace_to_nbsp, $str);
79         return $str;
80 }
81
82 # Encode for output in html. Spaces converted to &nbsp; and \n to <br>
83 #
84 # Example: <option value="12">~foo htmlbrnbsp~</option>
85 function enc_htmlbrnbsp($str) {
86         $str = enc_htmlbr($str);
87         $str = str_replace(' ', '&nbsp;', $str);
88         return $str;
89 }
90
91 # Encode for output in html. Spaces converted to &nbsp;
92 #
93 # Example: <option value="12">~foo htmlnbsp~</option>
94 function enc_htmlnbsp($str) {
95         $str = enc_html($str);
96         $str = str_replace(' ', '&nbsp;', $str);
97         return $str;
98 }
99
100
101 # HTML attribute.
102 #
103 # Example: <input name="foo" value="~foo attr~">
104 function enc_attr($str) {
105         $str = str_replace('&', '&amp;', $str);
106         $str = str_replace('"', '&quot;', $str);
107         return $str;
108 }
109
110 # URI agument value.
111 #
112 # Example:  <a href="http://example.com?foo=~foo url_val attr~">http://example.com?foo=~foo url_val~</a>
113 function enc_url_val($str) {
114         return rawurlencode($str);
115 }
116
117 # FIXME
118 function enc_url_path($str) {
119         $str = rawurlencode($str);
120         $str = str_replace('%2F', '/', $str);
121         return $str;
122 }
123
124
125 # This is a hack to work around html's stupid syntax for checkboxes.
126 #
127 # Place the template marker just before a " somewhere.
128 #
129 # Example: <input type="checkbox" name="foo~foo checked~">
130 function enc_checked($str) {
131         if($str && $str !== 'No' && $str !== 'False' && $str !== 'false') {
132                 return '" checked="checked';
133         } else {
134                 return '';
135         }
136 }
137
138 # normally, checkboxes values from get/post to 0 or 1, and stored in the database this way. enc_yesno() can be used in your templates to display this as "Yes" or "No".
139 # Example template:  Subscribe to mailing list?: ~subscribe yesno~
140 function enc_yesno($str) {
141         if($str && $str !== 'No' && $str !== 'False' && $str !== 'false') {
142                 return 'Yes';
143         } else {
144                 return 'No';
145         }
146 }
147
148
149 # add a tab at the begining of each line
150 function enc_tab($str) {
151         if('' . $str === '') {
152                 return '';
153         }
154         return "\t" . implode("\n\t", explode("\n", $str));
155 }
156
157 function enc_uppercase($str) {
158         return strtoupper($str);
159 }
160 function enc_upper($str) { # depricated
161         return enc_uppercase($str);
162 }
163
164 function enc_lowercase($str) {
165         return strtolower($str);
166 }
167
168 # pass date in the form 2008-05-23
169 # ercodes date as 05/23/2008
170 function enc_mmddyyyy($yyyy_mm_dd) {
171         if($yyyy_mm_dd == '') {
172                 return '';
173         }
174         if(strlen($yyyy_mm_dd) != 10) {
175                 return date('m/d/Y');
176         }
177         return substr($yyyy_mm_dd, 5, 2) . '/' . substr($yyyy_mm_dd, 8, 2) . '/' . substr($yyyy_mm_dd, 0, 4);
178 }
179
180 # depricated. call enc_mmddyyyy() instead
181 function enc_mdy($str) {
182         return enc_mmddyyyy($str);
183 }
184
185 # pass unix timestamp or "2012-12-20 22:23:34"
186 function enc_mmddyyyyhhmm($str) {
187         if(is_numeric($str)) {
188                 return date('m/d/Y g:ia', (int)$str);
189         } else {
190                 return enc_mmddyyyy(substr($str, 0, 10)) . substr($str, 10, 6);
191         }
192 }
193
194 # takes decimal number of hours
195 # returns hh:mm
196 function enc_hhmm($str) {
197         if(strlen($str) == 0) {
198                 return '';
199         }
200         $hours = floor($str);
201         $minutes = round(($str - $hours) * 60);
202         $str = sprintf("%d:%02d", $hours, $minutes);
203         return $str;
204 }
205
206 # takes decimal number of hours
207 # returns hh:mm followed by "am" or "pm" with no space
208 function enc_12hr($str) {
209         if(strlen($str) == 0) {
210                 return '';
211         }
212         $hours = floor($str);
213         $minutes = round(($str - $hours) * 60);
214         $suffix = 'am';
215         if($hours >= 12.0) {
216                 $suffix = 'pm';
217                 if($hours > 12.0) {
218                         $hours -= 12.0;
219                 }
220         }
221         $str = sprintf("%d:%02d", $hours, $minutes);
222         $str .= $suffix;
223         return $str;
224 }
225
226
227
228 # These are depricated! All but PULLDOWN_HASH still work, but you should update your code.
229 define('PULLDOWN_AUTO', 0); define('PULLDOWN_ARRAY', 1); define('PULLDOWN_HASH', 2); define('PULLDOWN_2D', 3);
230
231
232 # call this function before you run() the template so enc_options() knows what
233 # to do
234 #
235 # Parameters:
236 #
237 #   name: the name of the html control
238 #
239 #   options: an array of options to display in the pulldown/selectbox. Each
240 #   element can be either a string, or an array with two elements (first the
241 #   value to post, and second the value to display in the pulldown)
242 #
243 #   multiple: UNTESTED set to true for multiple-select boxes. 
244
245 function pulldown($name, $in_options, $multiple = false) {
246         if($multiple === PULLDOWN_HASH) {
247                 die('Webmaster error: PULLDOWN_HASH is depricated. Pass array(a,b) not a=>b');
248         }
249         if($multiple !== true) {
250                 # Probably due to API change (removing 3rd argument) but don't bother
251                 # emitting a warning, because the above warning handles the only
252                 # important case.
253                 $multiple = false;
254         }
255         $options = array();
256         foreach($in_options as $option) {
257                 if(is_array($option)) {
258                         $options[] = $option;
259                 } else {
260                         $options[] = array($option, $option);
261                 }
262         }
263         $GLOBALS[$name . '_options'] = array(
264                 'options' => $options,
265                 'multiple' => $multiple);
266 }
267
268 # output a bunch of <option> tags
269 function enc_options($values, $name) {
270         if(!isset($GLOBALS[$name . '_options'])) {
271                 die("pulldown('$name') must be called before this template can be run. See wfpl/encode.php");
272         }
273         if($GLOBALS[$name . '_options']['multiple']) { # FIXME test this
274                 $values = explode(', ', $values);
275         }
276         return encode_options($values, $GLOBALS[$name . '_options']['options']);
277 }
278
279 # for radios and pulldowns:
280 # pass posted value
281 # returns what the user sees in the pulldown or on the radio button caption
282 function enc_pulled($str, $name) {
283         if(!isset($GLOBALS[$name . '_options'])) {
284                 die("pulldown('$name') must be called before this template can be run. See wfpl/encode.php");
285         }
286         foreach($GLOBALS[$name . '_options']['options'] as &$kv) {
287                 if($kv[0] == $str) {
288                         return $kv[1];
289                 }
290         }
291         return $str;
292 }
293
294 function enc_radio_n($str, $name, $n) {
295         if(!isset($GLOBALS[$name . '_options'])) {
296                 die("pulldown('$name') must be called before this template can be run. See wfpl/encode.php");
297         }
298
299         if(!isset($GLOBALS[$name . '_options']['options'][$n])) {
300                 die("Template error: pulldown('$name') does not have element # $n");
301         }
302
303         $value = enc_attr($GLOBALS[$name . '_options']['options'][$n][0]);
304
305         if($str === $value) {
306                 $value .= '" checked="checked';
307         }
308
309         return $value;
310 }
311 function enc_radio_0($str, $name) { return enc_radio_n($str, $name, 0); }
312 function enc_radio_1($str, $name) { return enc_radio_n($str, $name, 1); }
313 function enc_radio_2($str, $name) { return enc_radio_n($str, $name, 2); }
314 function enc_radio_3($str, $name) { return enc_radio_n($str, $name, 3); }
315 function enc_radio_4($str, $name) { return enc_radio_n($str, $name, 4); }
316 function enc_radio_5($str, $name) { return enc_radio_n($str, $name, 5); }
317 function enc_radio_6($str, $name) { return enc_radio_n($str, $name, 6); }
318 function enc_radio_7($str, $name) { return enc_radio_n($str, $name, 7); }
319 function enc_radio_8($str, $name) { return enc_radio_n($str, $name, 8); }
320 function enc_radio_9($str, $name) { return enc_radio_n($str, $name, 9); }
321 function enc_radio_10($str, $name) { return enc_radio_n($str, $name, 10); }
322 function enc_radio_11($str, $name) { return enc_radio_n($str, $name, 11); }
323 function enc_radio_12($str, $name) { return enc_radio_n($str, $name, 12); }
324 function enc_radio_13($str, $name) { return enc_radio_n($str, $name, 13); }
325 function enc_radio_14($str, $name) { return enc_radio_n($str, $name, 14); }
326 function enc_radio_15($str, $name) { return enc_radio_n($str, $name, 15); }
327 function enc_radio_16($str, $name) { return enc_radio_n($str, $name, 16); }
328 function enc_radio_17($str, $name) { return enc_radio_n($str, $name, 17); }
329 function enc_radio_18($str, $name) { return enc_radio_n($str, $name, 18); }
330 function enc_radio_19($str, $name) { return enc_radio_n($str, $name, 19); }
331 function enc_radio_20($str, $name) { return enc_radio_n($str, $name, 20); }
332
333
334 function enc_radio_caption_n($str, $name, $n) {
335         if(!isset($GLOBALS[$name . '_options'])) {
336                 die("pulldown('$name') must be called before this template can be run. See wfpl/encode.php");
337         }
338
339         if(!isset($GLOBALS[$name . '_options']['options'][$n])) {
340                 die("Template error: pulldown('$name') does not have element #$n");
341         }
342
343         return $GLOBALS[$name . '_options']['options'][$n][1];
344 }
345 function enc_radio_caption_0($str, $name) { return enc_radio_caption_n($str, $name, 0); }
346 function enc_radio_caption_1($str, $name) { return enc_radio_caption_n($str, $name, 1); }
347 function enc_radio_caption_2($str, $name) { return enc_radio_caption_n($str, $name, 2); }
348 function enc_radio_caption_3($str, $name) { return enc_radio_caption_n($str, $name, 3); }
349 function enc_radio_caption_4($str, $name) { return enc_radio_caption_n($str, $name, 4); }
350 function enc_radio_caption_5($str, $name) { return enc_radio_caption_n($str, $name, 5); }
351 function enc_radio_caption_6($str, $name) { return enc_radio_caption_n($str, $name, 6); }
352 function enc_radio_caption_7($str, $name) { return enc_radio_caption_n($str, $name, 7); }
353 function enc_radio_caption_8($str, $name) { return enc_radio_caption_n($str, $name, 8); }
354 function enc_radio_caption_9($str, $name) { return enc_radio_caption_n($str, $name, 9); }
355 function enc_radio_caption_10($str, $name) { return enc_radio_caption_n($str, $name, 10); }
356 function enc_radio_caption_11($str, $name) { return enc_radio_caption_n($str, $name, 11); }
357 function enc_radio_caption_12($str, $name) { return enc_radio_caption_n($str, $name, 12); }
358 function enc_radio_caption_13($str, $name) { return enc_radio_caption_n($str, $name, 13); }
359 function enc_radio_caption_14($str, $name) { return enc_radio_caption_n($str, $name, 14); }
360 function enc_radio_caption_15($str, $name) { return enc_radio_caption_n($str, $name, 15); }
361 function enc_radio_caption_16($str, $name) { return enc_radio_caption_n($str, $name, 16); }
362 function enc_radio_caption_17($str, $name) { return enc_radio_caption_n($str, $name, 17); }
363 function enc_radio_caption_18($str, $name) { return enc_radio_caption_n($str, $name, 18); }
364 function enc_radio_caption_19($str, $name) { return enc_radio_caption_n($str, $name, 19); }
365 function enc_radio_caption_20($str, $name) { return enc_radio_caption_n($str, $name, 20); }
366
367
368 # use this function along with a special template to generate the html for pulldowns and multiple select boxes.
369 #
370 # Parameters:
371 #
372 #    selected: can be a string or (for multiple-selects) an array
373 #
374 #    options: see documentation for pulldown() above
375 function encode_options($selected, $options) {
376         if(!is_array($selected)) {
377                 $selected = array($selected);
378         }
379
380         $out = '';
381         foreach($options as $option) {
382                 list($value, $display) = $option;
383                 $out .= '<option';
384
385                 if(isset($option[2]) && $option[2] == 'disabled') {
386                         $out .= ' disabled';
387                 } elseif(in_array($value, $selected)) {
388                         $out .= ' selected';
389                 }
390
391                 if($value !== $display || strpos($value, ' ') !== false) {
392                         $out .= ' value="';
393                         $out .= enc_attr($value);
394                         $out .= '"';
395                 }
396                         
397                 $out .= '>';
398
399                 $out .= enc_htmlnbsp($display);
400
401                 $out .= "</option>\n";
402         }
403
404         return $out;
405 }
406
407 $GLOBALS['wfpl_states_assoc'] = array(array("AL", "Alabama"), array("AK", "Alaska"), array("AZ", "Arizona"), array("AR", "Arkansas"), array("CA", "California"), array("CO", "Colorado"), array("CT", "Connecticut"), array("DE", "Delaware"), array("FL", "Florida"), array("GA", "Georgia"), array("HI", "Hawaii"), array("ID", "Idaho"), array("IL", "Illinois"), array("IN", "Indiana"), array("IA", "Iowa"), array("KS", "Kansas"), array("KY", "Kentucky"), array("LA", "Louisiana"), array("ME", "Maine"), array("MD", "Maryland"), array("MA", "Massachusetts"), array("MI", "Michigan"), array("MN", "Minnesota"), array("MS", "Mississippi"), array("MO", "Missouri"), array("MT", "Montana"), array("NE", "Nebraska"), array("NV", "Nevada"), array("NH", "New Hampshire"), array("NJ", "New Jersey"), array("NM", "New Mexico"), array("NY", "New York"), array("NC", "North Carolina"), array("ND", "North Dakota"), array("OH", "Ohio"), array("OK", "Oklahoma"), array("OR", "Oregon"), array("PA", "Pennsylvania"), array("RI", "Rhode Island"), array("SC", "South Carolina"), array("SD", "South Dakota"), array("TN", "Tennessee"), array("TX", "Texas"), array("UT", "Utah"), array("VT", "Vermont"), array("VA", "Virginia"), array("WA", "Washington"), array("DC", "Washington, DC"), array("WV", "West Virginia"), array("WI", "Wisconsin"), array("WY", "Wyoming"));
408
409 # display <option>s
410 function enc_states($str) {
411         $ret = '';
412
413         return encode_options($str, $GLOBALS['wfpl_states_assoc']);
414 }
415
416 $GLOBALS['wfpl_provinces_assoc'] = array(array("AB", "Alberta"), array("BC", "British Columbia"), array("MB", "Manitoba"), array("NF", "Newfoundland"), array("NB", "New Brunswick"), array("NS", "Nova Scotia"), array("NT", "Northwest Territories"), array("NU", "Nunavut"), array("ON", "Ontario"), array("PE", "Prince Edward Island"), array("QC", "Quebec"), array("SK", "Saskatchewan"), array("YT", "Yukon Territory"));
417
418 # display <option>s
419 function enc_provinces($str) {
420         $ret = '';
421
422         return encode_options($str, $GLOBALS['wfpl_provinces_assoc']);
423 }
424
425 # returns "odd", then "even", then "odd" etc.
426 function enc_evenodd($values, $name) {
427         if(!isset($GLOBALS['wfpl_even_odds'])) {
428                 $GLOBALS['wfpl_even_odds'] = array();
429         }
430
431         if($GLOBALS['wfpl_even_odds'][$name]) {
432                 $GLOBALS['wfpl_even_odds'][$name] = false;
433                 return 'even';
434         } else {
435                 $GLOBALS['wfpl_even_odds'][$name] = true;
436                 return 'odd';
437         }
438 }
439
440 function wfpl_nth_word($str, $n) {
441         $a = explode(' ', $str);
442         return isset($a[$n]) ? $a[$n] : null;
443 }
444
445 # encoding is a space separated list of:
446 # image_filename width height thumb_filename thumb_width thumb_height
447 function enc_image_src($str) { return wfpl_nth_word($str, 0); }
448 function enc_image_width($str) { return wfpl_nth_word($str, 1); }
449 function enc_image_height($str) { return wfpl_nth_word($str, 2); }
450 function enc_thumb_src($str) { return wfpl_nth_word($str, 3); }
451 function enc_thumb_width($str) { return wfpl_nth_word($str, 4); }
452 function enc_thumb_height($str) { return wfpl_nth_word($str, 5); }
453
454 # example template: Length: ~length html~ day~length s~
455 function enc_s($str) {
456         if($str == '1') {
457                 return '';
458         }
459
460         return 's';
461 }
462
463 # turn http/ftp (s) urls into html links (and encode everything for html)
464 # does not encode without protocol (eg "www.foo.com")
465 # does not linkify email addresses
466 function enc_linkify($str) {
467         $ret = '';
468         $even = true;
469         $pieces = preg_split("/((?:ht|f)tps?:\/\/[^ \,\"\n\r\t<]+)/is", $str, null, PREG_SPLIT_DELIM_CAPTURE);
470         foreach($pieces as $piece) {
471                 if($even) {
472                         $ret .= enc_html($piece);
473                 } else {
474                         $ret .= '<a href="' . enc_attr($piece) . '">' . enc_html($piece) . '</a>';
475                 }
476                 $even = !$even;
477         }
478         return $ret;
479 }
480
481 # turns a filename into the unix timestamp of that files modification date
482 function enc_mtime($dummy, $filename) {
483         $stat = stat($filename);
484         if ($stat === false) {
485                 return '';
486         }
487         return '' . $stat['mtime'];
488 }