Subversion Repositories PHPX

Rev

Rev 24 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

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