Rev 24 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
25 | PointedEar | 1 | <?php |
2 | |||
3 | /* @section Helper functions */ |
||
4 | |||
2 | PointedEar | 5 | /** |
25 | PointedEar | 6 | * Retrieves the value of an element of an associative array. |
7 | * |
||
8 | * This is designed for $_GET and other HTTP variables but |
||
9 | * also works for common associative arrays. |
||
10 | * |
||
11 | * @param $key: string |
||
12 | * Key identifier. The default is the empty string. |
||
13 | * @param $array: string |
||
14 | * Array identifier. The default is '_GET'. If there is |
||
15 | * no such array, the identifier is prefixed with 'HTTP' |
||
16 | * and suffixed with '_VARS' (to support the deprecated |
||
17 | * HTTP_GET_VARS etc. arrays as of PHP < 4.1). If |
||
18 | * there is still no array with that identifier, return |
||
19 | * the empty string. |
||
20 | * @param $default: string |
||
21 | * Default return value if the element specified with |
||
22 | * $key is not available in the array. The default |
||
23 | * is the empty string. |
||
24 | * @return |
||
25 | * The value of the element of that array with that key or |
||
26 | * the empty string if there is no such element or array. |
||
27 | * @author |
||
28 | * Copyright (C) 2004, 2005 Thomas Lahn <php@PointedEars.de> |
||
29 | */ |
||
30 | function getVars($key = '', $array = '_GET', $default = '', $noEntities = false) |
||
31 | { |
||
32 | global ${$array}; |
||
33 | if (!isset(${'HTTP'.$array.'_VARS'})) global ${'HTTP'.$array.'_VARS'}; |
||
34 | /* |
||
35 | echo "<pre>getVars: \$$array"."['$key']: return '" |
||
36 | .(isset(${$array}) && isset(${$array}[$key]) |
||
37 | ? ${$array}[$key] |
||
38 | : (isset(${'HTTP'.$array.'_VARS'}) && isset(${'HTTP'.$array.'_VARS'}[$key]) |
||
39 | ? ${'HTTP'.$array.'_VARS'}[$key] |
||
40 | : $default)) . "'</pre><br>\n"; |
||
41 | */ |
||
42 | $result = (isset(${$array}) && isset(${$array}[$key]) |
||
43 | ? ${$array}[$key] |
||
44 | : (isset(${'HTTP'.$array.'_VARS'}) && isset(${'HTTP'.$array.'_VARS'}[$key]) |
||
45 | ? ${'HTTP'.$array.'_VARS'}[$key] |
||
46 | : $default)); |
||
47 | |||
48 | // TODO: Escape HTML entities |
||
49 | /* |
||
50 | if (!$noEntities) |
||
51 | { |
||
52 | $result = htmlentities($result); |
||
53 | } |
||
54 | */ |
||
55 | return $result; |
||
56 | } |
||
57 | |||
58 | /** |
||
59 | * Converts the argument to a visible (X)HTML hyperlink |
||
60 | * where its URI target is created from the argument. |
||
61 | * Supported are e-mail addresses, domain names with |
||
62 | * optional paths, and valid URIs. |
||
63 | * |
||
64 | * @param $text |
||
65 | * Argument to be converted. |
||
66 | * @return |
||
67 | * The converted argument if it applies to a supported |
||
68 | * scheme, the unconverted argument otherwise. |
||
69 | * |
||
70 | * @author (C) 2001-04-04T02:03 |
||
71 | * mark.young@vdhinc.com at http://php.net/manual/en/ref.strings.php |
||
72 | * |
||
73 | * Minor correction to my HTMLEncode function. |
||
74 | * |
||
75 | * @author 2002-08-29T09:00 |
||
76 | * Thomas Lahn <PointedEars@selfhtml.de> at localhost |
||
77 | * |
||
78 | * - Added target="_blank" |
||
79 | * - Added support for ftp(s)-URIs: (ht|f) |
||
80 | * - Added support for search strings (?...=...&...=...), either |
||
81 | * with or without HTML entities: \?=(&\w;|&) |
||
82 | * - Removed enclosing nl2br call because of preformatted display |
||
83 | * |
||
84 | * @author 2003-12-30T14:18 |
||
85 | * Thomas Lahn <PointedEars@selfhtml.de> at localhost |
||
86 | * |
||
87 | * - Removed target="_blank". |
||
88 | * - Added PHPdoc. |
||
89 | * |
||
90 | * @author 2004-01-12T12:45 |
||
91 | * Thomas Lahn <PointedEars@selfhtml.de> at localhost |
||
92 | * |
||
93 | * - Added support for #fragment_identifiers in URIs. |
||
94 | * - Added support for bugs and comments. |
||
95 | * |
||
96 | * @author 2004-01-13T01:29 |
||
97 | * Thomas Lahn <PointedEars@selfhtml.de> at localhost |
||
98 | * |
||
99 | * - Added support for bug aliases. |
||
100 | * |
||
101 | * @author 2004-01-26T20:43 |
||
102 | * Thomas Lahn <PointedEars@selfhtml.de> at localhost |
||
103 | * |
||
104 | * - Do not convert URIs in A elements. |
||
105 | * - Do not allow URIs with "&" before search-string. |
||
106 | * - camelCased function identifier. Only classes |
||
107 | * and constructors should start with uppercase. |
||
108 | * |
||
109 | * @author 2004-01-27T14:07 |
||
110 | * Thomas Lahn <PointedEars@selfhtml.de> at localhost |
||
111 | * |
||
112 | * - Allow to convert URIs preceded by ">" but not followed by "</a>". |
||
113 | * - Allow ";" to be part of the search string |
||
114 | * |
||
115 | * @author 2004-01-29T14:10 |
||
116 | * Thomas Lahn <PointedEars@selfhtml.de> at localhost |
||
117 | * |
||
118 | * - Require valid domain name for "bar" on conversion of "foo@bar" and |
||
119 | * "www.bar". |
||
120 | * - Be case-insensitive except of bug aliases |
||
121 | * - Escaped "-" in character classes if not meant as range metacharacter. |
||
122 | * - Corrected year. |
||
123 | * |
||
124 | * @author 2004-02-14T17:37 |
||
125 | * Thomas Lahn <PointedEars@selfhtml.de> at localhost |
||
126 | * |
||
127 | * - Accept only valid Internet domain names |
||
128 | * - Accept "%" within path and query part (to escape ASCII characters) |
||
129 | * |
||
130 | * @author 2004-02-27T19:21 |
||
131 | * Thomas Lahn <PointedEars@selfhtml.de> at localhost |
||
132 | * |
||
133 | * - Allow unescaped ":" in URI components, since it apparently does not |
||
134 | * "conflict with the reserved purpose" (RFC 2396, section 2.2.; here: |
||
135 | * scheme component) |
||
136 | * - Allow slashes, dots and dashes in URI components |
||
137 | * - Removed invalid [...(...|...)...] |
||
138 | * |
||
139 | * @author 2004-03-01T21:48 |
||
140 | * Thomas Lahn <PointedEars@selfhtml.de> at localhost |
||
141 | * |
||
142 | * - Allow IPv4 addresses |
||
143 | * |
||
144 | * @author 2004-03-08T02:20 |
||
145 | * Thomas Lahn <PointedEars@selfhtml.de> at localhost |
||
146 | * |
||
147 | * - Allow "+" and "," in query part |
||
148 | * - Optimized character classes |
||
149 | * |
||
150 | * @author (C) 2004-04-23T10:03 |
||
151 | * Thomas Lahn <PointedEars@selfhtml.de> at localhost |
||
152 | * |
||
153 | * - Rewrite to use RFC 2822 and 2369 syntax |
||
154 | */ |
||
155 | function htmlEncode($text) |
||
156 | { |
||
157 | // see RFC 2822 "Internet Message Format" |
||
158 | $local_part = '[^()<>@,;:\\"\-\[\] \x00-\x1A\x7F]+'; |
||
159 | |||
160 | // see RFC 2396 "Uniform Resource Identifiers (URI): Generic Syntax" |
||
161 | // $digit = '\d'; // 0-9; def. not required |
||
162 | // $hex = '\da-f'; // "hex" for case-insensitive match; def. N/R |
||
163 | $alpha = 'a-z'; // "alpha" for case-insensitive match |
||
164 | $alphanum = $alpha.'\d'; // "alphanum" for case-insensitive match |
||
165 | $mark = "\-_.!~*\'()"; |
||
166 | $reserved = ';/?:@&=+$,'; |
||
167 | $unreserved = $alphanum.$mark; |
||
168 | $escaped = '%[\da-f]'; // contains $hex |
||
169 | |||
170 | // added (?!gt;) to allow "<URI>" |
||
171 | $uric = '(['.$reserved.$alphanum.$mark.'](?!gt;)|'.$escaped.')'; |
||
172 | $uric_no_slash = '(['.$unreserved.';\?:@&=+$,](?!gt;)|'.$escaped.')'; |
||
173 | $pchar = '(['.$unreserved.':@&=+$,](?!gt;)|'.$escaped.')'; |
||
174 | $param = $pchar; |
||
175 | $segment = $pchar.'*(;'.$param.')*'; |
||
176 | $abs_path = '/' . $segment . '(/'.$segment.')*'; |
||
177 | $userinfo = '(['.$unreserved.';:&=+$,](?!gt;)|'.$escaped.')*'; |
||
178 | $domainlabel = '(['.$alphanum.']' |
||
179 | . '|['.$alphanum.'](['.$alphanum.']|-)*['.$alphanum.']' |
||
180 | . ')'; |
||
181 | $toplabel = '(['.$alpha.']' |
||
182 | . '|['.$alpha.'](['.$alphanum.']|-)*['.$alphanum. '])'; |
||
183 | $hostname = '('.$domainlabel. '\.)*' . $toplabel . '\.?'; |
||
184 | $ipv4_address = '\d+\.\d+\.\d+\.\d+'; |
||
185 | $host = '(' . $hostname . '|' . $ipv4_address . ')'; |
||
186 | $port = '\d*'; |
||
187 | $hostport = $host . '(:' . $port . ')?'; |
||
188 | $server_req = '(' . $userinfo . ')?' . $hostport; // server is required |
||
189 | $reg_name = '([' . $unreserved . '$,;:@&=+](?!gt;)|' . $escaped . ')+'; |
||
190 | $authority = '(' . $server_req . '|' . $reg_name . ')'; |
||
191 | $net_path = '//' . $authority . '('.$abs_path.')?'; |
||
192 | $query = $uric.'*'; |
||
193 | $scheme = '(ht|f)tps?'; |
||
194 | $hier_part = '(' . $net_path .'|' . $abs_path . ')(\?' . $query . ')?'; |
||
195 | $opaque_part = $uric_no_slash . $uric.'*'; |
||
196 | $absolute_uri = $scheme . ':(' . $hier_part . '|' . $opaque_part . ')'; |
||
197 | $fragment = $uric.'*'; |
||
198 | |||
199 | // absolute URIs only |
||
200 | $uri_reference = $absolute_uri . '(#' . $fragment . ')?'; |
||
201 | // echo '<br>'.htmlentities($local_part . '@' . $host).'<br>'; |
||
202 | |||
203 | $searcharray = array( |
||
204 | "'(?i)(" . $local_part . '@' . $host . ")'i", |
||
205 | "'(?i)((?:(?!://).{3}|^.{0,2}))(www\." . $hostname |
||
206 | . '|' . $ipv4_address . ")'i", |
||
207 | "'(?i)(?<!href=\")(" . $uri_reference . ")(?!</a>)'i", |
||
208 | "'(((?i)bug)\s+#?([\dA-Z_]+)\s+((?i)comment|Kommentar)\s+#?(\d+))'", |
||
209 | "'(((?i)bug)\s+#?([\dA-Z_]+))'", |
||
210 | "'(((?i)comment|Kommentar)\s+#?(\d+))'" |
||
211 | ); |
||
212 | |||
213 | $replacearray = array( |
||
214 | "<a href=\"mailto:\\1\">\\1</a>", |
||
215 | "\\1http://\\2", |
||
216 | "<a href=\"\\1\">\\1</a>", |
||
217 | "<a href=\"./?bug=\\3#c\\5\">\\1</a>", |
||
218 | "<a href=\"./?bug=\\3#details\">\\1</a>", |
||
219 | "<a href=\"#c\\3\">\\1</a>" |
||
220 | ); |
||
221 | |||
222 | return preg_replace($searcharray, $replacearray, $text); |
||
223 | } |
||
224 | |||
225 | /** |
||
226 | * Converts HTML entities to real characters using the detected |
||
227 | * or specified character encoding. |
||
228 | * |
||
229 | * @param string $s |
||
230 | * @param int[optional] $quote_style |
||
231 | * @return string |
||
232 | */ |
||
233 | function htmlEntityDecode($s, $quote_style=ENT_COMPAT, $encoding=null) |
||
234 | { |
||
235 | $s = (string) $s; |
||
236 | |||
237 | if (is_null($encoding)) |
||
238 | { |
||
239 | $encoding = mb_detect_encoding($s); |
||
240 | if ($encoding === 'ASCII') |
||
241 | { |
||
242 | $encoding = 'ISO-8859-1'; |
||
243 | } |
||
244 | } |
||
245 | |||
246 | return html_entity_decode($s, $quote_style, $encoding); |
||
247 | } |
||
248 | |||
249 | |||
250 | /** |
||
251 | * Converts the argument into a visible (X)HTML hyperlink if a condition |
||
252 | * applies. |
||
253 | * |
||
254 | * @author |
||
255 | * (C) 2003, 2004 Thomas Lahn <selfhtml.de@PointedEars.de> |
||
256 | * @param $s |
||
257 | * Content to be converted. Required. |
||
258 | * @param $sCond |
||
259 | * Condition to be true for the content to be converted. |
||
260 | * The default is <code>true</code>. |
||
261 | * @param $sURI |
||
262 | * Target URI of the hyperlink. The default is the |
||
263 | * value of $s. |
||
264 | * @param $sName |
||
265 | * Value of the <code>name</code> attribute of the |
||
266 | * <code>a</code> element. Unused if not provided |
||
267 | * or empty. |
||
268 | * @param $sTitle |
||
269 | * Value of the <code>title</code> attribute of the |
||
270 | * <code>a</code> element. Unused if not provided |
||
271 | * or empty. |
||
272 | * @param $sClass |
||
273 | * Value of the <code>class</code> attribute of the |
||
274 | * <code>a</code> element. Unused if not provided |
||
275 | * or empty. |
||
276 | * @return |
||
277 | * The converted argument if the condition applies, |
||
278 | * the unconverted argument otherwise. |
||
279 | */ |
||
280 | function makeLinkIf( |
||
281 | $s, |
||
282 | $sCond = true, |
||
283 | $sURI = NULL, |
||
284 | $sTarget = '', |
||
285 | $sName = '', |
||
286 | $sTitle = '', |
||
287 | $sClass = '') |
||
288 | { |
||
289 | return ($sCond || $sName |
||
290 | ? '<a' . ($sCond |
||
291 | ? " href=\"" . (is_null($sURI) ? $s : $sURI) |
||
292 | . "\"".($sTarget ? " target=\"$sTarget\"" : '') |
||
293 | : '' |
||
294 | ) |
||
295 | . ($sName ? " name=\"$sName\"" : '') |
||
296 | . ($sTitle ? " title=\"$sTitle\"" : '') |
||
297 | . ($sClass ? " class=\"$sClass\"" : '') |
||
298 | . '>' |
||
299 | : '' |
||
300 | ) |
||
301 | . $s |
||
302 | . ($sCond || $sName ? '</a>' : ''); |
||
303 | } |
||
304 | |||
305 | /** |
||
306 | * Returns a visible (X)HTML hyperlink that uses the mailto: URI scheme. |
||
307 | * |
||
308 | * @author (C) 2003 Thomas Lahn <selfhtml.de@PointedEars.de> |
||
309 | * |
||
310 | * @author (C) 2003-12-30 Thomas Lahn <selfhtml.de@PointedEars.de> |
||
311 | * - Corrected `$email ($name)'. |
||
312 | * - Now uses rawurlencode(...). |
||
313 | * - Added PHPdoc. |
||
314 | * |
||
315 | * @author (C) 2004-11-30 Thomas Lahn <selfhtml.de@PointedEars.de> |
||
316 | * - Don't rawurlencode(...) parens for comments. |
||
317 | * |
||
318 | * @param $sAddress |
||
319 | * E-mail address. The default is <selfhtml.de@PointedEars.de>. |
||
320 | * @param $sTitle |
||
321 | * Value of the <code>title</code> attribute of the |
||
322 | * <code>a</code> element. Unused if not provided |
||
323 | * or empty. The default is 'PointedEars'. |
||
324 | * @param $sToName |
||
325 | * Name to be used in the To header of the e-mail. |
||
326 | * Note that @link{rawurlencode()} is used to escape |
||
327 | * special characters automatically. |
||
328 | * The default is "Thomas 'PointedEars' Lahn". |
||
329 | * |
||
330 | * @return |
||
331 | * The converted argument if the condition applies, |
||
332 | * the unconverted argument otherwise. |
||
333 | */ |
||
334 | function mailto_link( |
||
335 | $sAddress = 'selfhtml.de@PointedEars.de', |
||
336 | $sTitle = 'PointedEars', |
||
337 | $sToName = "Thomas 'PointedEars' Lahn", |
||
338 | $sSubject = 'SELFbug', |
||
339 | $sImgPath = '../../media/mail.gif' |
||
340 | ) |
||
341 | { |
||
342 | //width="14" height="15" // image size detection not yet implemented |
||
343 | return ($sImgPath != '' |
||
344 | ? '<img src="' . $sImgPath . '" border="0" alt="@"> ' |
||
345 | : '') |
||
346 | . '<a href="mailto:' |
||
347 | . ($sAddress != '' |
||
348 | ? $sAddress |
||
349 | : 'selfhtml.de@PointedEars.de') |
||
350 | . ($sToName != '' |
||
351 | ? ' (' . rawurlencode($sToName) . ')' |
||
352 | : '') |
||
353 | . ($sSubject != '' |
||
354 | ? '?subject=' . rawurlencode($sSubject) |
||
355 | : '') |
||
356 | . '">' . (($sTitle != '') ? $sTitle : $sAddress) . '</a>'; |
||
357 | } |
||
358 | |||
359 | // map bug states to numbers so that they become comparable |
||
360 | function array_values_to_keys($a) |
||
361 | { |
||
362 | $aNew = array(); |
||
363 | foreach ($a as $key => $value) |
||
364 | { |
||
365 | $aNew[$value] = count($aNew); |
||
366 | } |
||
367 | return $aNew; |
||
368 | } |
||
369 | |||
370 | /** |
||
371 | * Maps an array to another array using a callback function. |
||
372 | * |
||
373 | * Unlike array_map(), the callback is called with three parameters: the value |
||
374 | * to be processed, the key of that value, and the array processed. The return |
||
375 | * value of the callback defines the value for the same key of the returned |
||
376 | * array. |
||
377 | * |
||
378 | * Because of the way the callback is called, this method supports processing |
||
379 | * only one array at a time, unlike array_map(). Unlike array_walk(), this |
||
380 | * function does not modify the original array. |
||
381 | * |
||
382 | * @param string|array $callback |
||
383 | * The callback to be used for mapping array values. If an array, the first |
||
384 | * element of the array is supposed to be the class name, and the second |
||
385 | * element the method name of a static method to be used. |
||
386 | * @param array $array |
||
387 | * The array to process |
||
388 | * @return array |
||
389 | * @see array_map() |
||
390 | * @see array_walk() |
||
391 | */ |
||
392 | function array_map2($callback, $array) |
||
393 | { |
||
394 | $a = array(); |
||
395 | |||
396 | if (is_array($callback)) |
||
397 | { |
||
398 | list($class, $method) = $callback; |
||
399 | } |
||
400 | |||
401 | foreach ($array as $key => &$value) |
||
402 | { |
||
403 | if (is_array($callback)) |
||
404 | { |
||
405 | $a[$key] = $class::$method($value, $key, $array); |
||
406 | } |
||
407 | else |
||
408 | { |
||
409 | $a[$key] = $callback($value, $key, $array); |
||
410 | } |
||
411 | } |
||
412 | |||
413 | return $a; |
||
414 | } |
||
415 | |||
416 | /** |
||
2 | PointedEar | 417 | * Converts a string or an array of strings to an associative |
418 | * bitmask array with the string(s) as key(s). |
||
25 | PointedEar | 419 | * |
2 | PointedEar | 420 | * Converts the argument to a bitmask array where each member's |
421 | * value is a power of 2, so that arbitrary member values can be |
||
422 | * added to an integer on which bitwise operations with the member |
||
25 | PointedEar | 423 | * value or a combination of member values are possible. |
424 | * |
||
425 | * @author (c) 2003 Thomas Lahn <SELFbug@PointedEars.de> |
||
426 | * @param $aArray |
||
427 | * String or array of strings to be converted. |
||
428 | */ |
||
429 | function getBitmaskArray($aArray) |
||
430 | { |
||
431 | $a = array(); |
||
432 | |||
433 | if (is_array($aArray)) |
||
434 | { |
||
435 | for ($i = 0; $i < count($aArray); $i++) |
||
436 | { |
||
437 | $a[$aArray[$i]] = pow(2, $i); |
||
438 | } |
||
439 | } |
||
440 | else |
||
441 | $a[$aArray] = 1; |
||
442 | |||
443 | return $a; |
||
444 | } |
||
445 | |||
446 | /** |
||
447 | * Returns the contents of a file as if include() was used. |
||
448 | * |
||
449 | * @param string $filename Path of the file to retrieve |
||
450 | * @return string File contents |
||
451 | */ |
||
452 | function get_include_content($filename) |
||
453 | { |
||
454 | if (is_file($filename)) |
||
455 | { |
||
456 | ob_start(); |
||
457 | include $filename; |
||
458 | $contents = ob_get_contents(); |
||
459 | ob_end_clean(); |
||
460 | return $contents; |
||
461 | } |
||
462 | |||
463 | return ''; |
||
464 | } |
||
465 | |||
466 | /** |
||
467 | * Replaces each group of expressions in a string with the same |
||
468 | * corresponding string. |
||
469 | * |
||
470 | * @param Array[Array[string] | string, string] $map |
||
471 | * @param string $subject |
||
472 | * @return string |
||
473 | * A copy of $subject with the provided mapping applied. |
||
474 | */ |
||
475 | function preg_replace_group($map = array(), $subject = '') |
||
476 | { |
||
477 | if ($subject) |
||
478 | { |
||
479 | for ($i = 0, $len = count($map); $i < $len; $i++) |
||
480 | { |
||
481 | $subject = preg_replace($map[$i][0], $map[$i][1], $subject); |
||
482 | } |
||
483 | } |
||
484 | |||
485 | return $subject; |
||
486 | } |
||
487 | |||
488 | /** |
||
489 | * Randomly encodes a string of characters. |
||
490 | * |
||
491 | * @param string $s |
||
492 | * String to be encoded |
||
493 | * @param string $format = 'sgml' |
||
494 | * Encoding format. Currently only SGML-based encoding of |
||
495 | * ASCII characters with character references is supported. |
||
496 | * @return string |
||
497 | */ |
||
498 | function randomEsc($s = '', $format = 'sgml') |
||
499 | { |
||
500 | $f = function_exists('mt_rand') ? 'mt_rand' : 'rand'; |
||
501 | |||
502 | return preg_replace_callback('/[\\x00-\\x7F]/', |
||
503 | create_function('$m', "return $f(0, 1)" . '? $m[0] : "&#" . ord($m[0]) . ";";'), |
||
504 | $s); |
||
505 | } |
||
506 | |||
507 | /** |
||
508 | * Reduces sequences of two or more consecutive white-space characters |
||
509 | * in an input to a single space. |
||
510 | * |
||
511 | * @param string $s |
||
512 | * @return string |
||
513 | */ |
||
514 | function reduceWhitespace($s) |
||
515 | { |
||
516 | return preg_replace('/\s{2,}/', ' ', $s); |
||
517 | } |
||
518 | |||
519 | function debug($x) |
||
520 | { |
||
521 | echo '<pre>'; |
||
522 | |||
523 | // if (is_array($x)) |
||
524 | // { |
||
525 | // print_r($x); |
||
526 | // } |
||
527 | // else |
||
528 | // { |
||
529 | var_dump($x); |
||
530 | // } |
||
531 | |||
532 | echo '</pre>'; |
||
533 | } |