OSDN Git Service

22ae474177b20f383522179ed1a3d77b1f1db0d2
[pukiwiki/pukiwiki_sandbox.git] / spam / spam_util.php
1 <?php
2 // $Id: spam_util.php,v 1.5 2011/01/25 13:16:35 henoheno Exp $
3 // Copyright (C) 2006-2009, 2011 PukiWiki Developers Team
4 // License: GPL v2 or (at your option) any later version
5 //
6 // Functions for Concept-work of spam-uri metrics
7
8
9 // ---------------------
10 // Compat etc
11
12 // (PHP 4 >= 4.2.0): var_export(): mail-reporting and dump related
13 if (! function_exists('var_export')) {
14         function var_export() {
15                 return 'var_export() is not found on this server' . "\n";
16         }
17 }
18
19 // (PHP 4 >= 4.2.0): preg_grep() enables invert option
20 function preg_grep_invert($pattern = '//', $input = array())
21 {
22         static $invert;
23         if (! isset($invert)) $invert = defined('PREG_GREP_INVERT');
24
25         if ($invert) {
26                 return preg_grep($pattern, $input, PREG_GREP_INVERT);
27         } else {
28                 $result = preg_grep($pattern, $input);
29                 if ($result) {
30                         return array_diff($input, preg_grep($pattern, $input));
31                 } else {
32                         return $input;
33                 }
34         }
35 }
36
37
38 // ---------------------
39 // Utilities
40
41
42 if (! function_exists('htmlsc')) {
43         // Interface with PukiWiki
44         //if (! defined('CONTENT_CHARSET')) define('CONTENT_CHARSET', 'ISO-8859-1');
45
46         // Sugar with default settings
47         function htmlsc($string = '', $flags = ENT_QUOTES, $charset = CONTENT_CHARSET)
48         {
49                 return htmlspecialchars($string, $flags, $charset);     // htmlsc()
50         }
51 }
52
53 // Very roughly, shrink the lines of var_export()
54 // NOTE: If the same data exists, it must be corrupted.
55 function var_export_shrink($expression, $return = FALSE, $ignore_numeric_keys = FALSE)
56 {
57         $result = var_export($expression, TRUE);
58
59         $result = preg_replace(
60                 // Remove a newline and spaces
61                 '# => \n *array \(#', ' => array (',
62                 $result
63         );
64
65         if ($ignore_numeric_keys) {
66                 $result =preg_replace(
67                         // Remove numeric keys
68                         '#^( *)[0-9]+ => #m', '$1',
69                         $result
70                 );
71         }
72
73         if ($return) {
74                 return $result;
75         } else {
76                 echo   $result;
77                 return NULL;
78         }
79 }
80
81 // Data structure: Create an array they _refer_only_one_ value
82 function one_value_array($num = 0, $value = NULL)
83 {
84         $num   = max(0, intval($num));
85         $array = array();
86
87         for ($i = 0; $i < $num; $i++) {
88                 $array[] = & $value;
89         }
90
91         return $array;
92 }
93
94 // Reverse $string with specified delimiter
95 function delimiter_reverse($string = 'foo.bar.example.com', $from_delim = '.', $to_delim = NULL)
96 {
97         $to_null = ($to_delim === NULL);
98
99         if (! is_string($from_delim) || (! $to_null && ! is_string($to_delim))) {
100                 return FALSE;
101         }
102         if (is_array($string)) {
103                 // Map, Recurse
104                 $count = count($string);
105                 $from  = one_value_array($count, $from_delim);
106                 if ($to_null) {
107                         // Note: array_map() vanishes all keys
108                         return array_map('delimiter_reverse', $string, $from);
109                 } else {
110                         $to = one_value_array($count, $to_delim);
111                         // Note: array_map() vanishes all keys
112                         return array_map('delimiter_reverse', $string, $from, $to);
113                 }
114         }
115         if (! is_string($string)) {
116                 return FALSE;
117         }
118
119         // Returns com.example.bar.foo
120         if ($to_null) $to_delim = & $from_delim;
121         return implode($to_delim, array_reverse(explode($from_delim, $string)));
122 }
123
124 // ksort() by domain
125 function ksort_by_domain(& $array)
126 {
127         $sort = array();
128         foreach(array_keys($array) as $key) {
129                 $reversed = delimiter_reverse($key);
130                 if ($reversed !== FALSE) {
131                         $sort[$reversed] = $key;
132                 }
133         }
134         ksort($sort, SORT_STRING);
135
136         $result = array();
137         foreach($sort as $key) {
138                 $result[$key] = & $array[$key];
139         }
140
141         $array = $result;
142 }
143
144 // Roughly strings(1) using PCRE
145 // This function is useful to:
146 //   * Reduce the size of data, from removing unprintable binary data
147 //   * Detect _bare_strings_ from binary data
148 // References:
149 //   http://www.freebsd.org/cgi/man.cgi?query=strings (Man-page of GNU strings)
150 //   http://www.pcre.org/pcre.txt
151 // Note: mb_ereg_replace() is one of mbstring extension's functions
152 //   and need to init its encoding.
153 function strings($binary = '', $min_len = 4, $ignore_space = FALSE, $multibyte = FALSE)
154 {
155         // String only
156         $binary = (is_array($binary) || $binary === TRUE) ? '' : strval($binary);
157
158         $regex = $ignore_space ?
159                 '[^[:graph:] \t\n]+' :          // Remove "\0" etc, and readable spaces
160                 '[^[:graph:][:space:]]+';       // Preserve readable spaces if possible
161
162         $binary = $multibyte ?
163                 mb_ereg_replace($regex,           "\n",  $binary) :
164                 preg_replace('/' . $regex . '/s', "\n",  $binary);
165
166         if ($ignore_space) {
167                 $binary = preg_replace(
168                         array(
169                                 '/[ \t]{2,}/',
170                                 '/^[ \t]/m',
171                                 '/[ \t]$/m',
172                         ),
173                         array(
174                                 ' ',
175                                 '',
176                                 ''
177                         ),
178                          $binary);
179         }
180
181         if ($min_len > 1) {
182                 // The last character seems "\n" or not
183                 $br = (! empty($binary) && $binary[strlen($binary) - 1] == "\n") ? "\n" : '';
184
185                 $min_len = min(1024, intval($min_len));
186                 $regex = '/^.{' . $min_len . ',}/S';
187                 $binary = implode("\n", preg_grep($regex, explode("\n", $binary))) . $br;
188         }
189
190         return $binary;
191 }
192
193
194 // ---------------------
195 // Utilities: Arrays
196
197 // Count leaves (A leaf = value that is not an array, or an empty array)
198 function array_count_leaves($array = array(), $count_empty = FALSE)
199 {
200         if (! is_array($array) || (empty($array) && $count_empty)) return 1;
201
202         // Recurse
203         $count = 0;
204         foreach ($array as $part) {
205                 $count += array_count_leaves($part, $count_empty);
206         }
207         return $count;
208 }
209
210 // Merge two leaves
211 // Similar to PHP array_merge_leaves(), except strictly preserving keys as string
212 function array_merge_leaves($array1, $array2, $sort_keys = TRUE)
213 {
214         // Array(s) only 
215         $is_array1 = is_array($array1);
216         $is_array2 = is_array($array2);
217         if ($is_array1) {
218                 if ($is_array2) {
219                         ;       // Pass
220                 } else {
221                         return $array1;
222                 }
223         } else if ($is_array2) {
224                 return $array2;
225         } else {
226                 return $array2; // Not array ($array1 is overwritten)
227         }
228
229         $keys_all = array_merge(array_keys($array1), array_keys($array2));
230         if ($sort_keys) sort($keys_all, SORT_STRING);
231
232         $result = array();
233         foreach($keys_all as $key) {
234                 $isset1 = isset($array1[$key]);
235                 $isset2 = isset($array2[$key]);
236                 if ($isset1 && $isset2) {
237                         // Recurse
238                         $result[$key] = array_merge_leaves($array1[$key], $array2[$key], $sort_keys);
239                 } else if ($isset1) {
240                         $result[$key] = & $array1[$key];
241                 } else {
242                         $result[$key] = & $array2[$key];
243                 }
244         }
245         return $result;
246 }
247
248 // An array-leaves to a flat array
249 function array_flat_leaves($array, $unique = TRUE)
250 {
251         if (! is_array($array)) return $array;
252
253         $tmp = array();
254         foreach(array_keys($array) as $key) {
255                 if (is_array($array[$key])) {
256                         // Recurse
257                         foreach(array_flat_leaves($array[$key]) as $_value) {
258                                 $tmp[] = $_value;
259                         }
260                 } else {
261                         $tmp[] = & $array[$key];
262                 }
263         }
264
265         return $unique ? array_values(array_unique($tmp)) : $tmp;
266 }
267
268 // $array['something'] => $array['wanted']
269 function array_rename_keys(& $array, $keys = array('from' => 'to'), $force = FALSE, $default = '')
270 {
271         if (! is_array($array) || ! is_array($keys)) return FALSE;
272
273         // Nondestructive test
274         if (! $force) {
275                 foreach(array_keys($keys) as $from) {
276                         if (! isset($array[$from])) {
277                                 return FALSE;
278                         }
279                 }
280         }
281
282         foreach($keys as $from => $to) {
283                 if ($from === $to) continue;
284                 if (! $force || isset($array[$from])) {
285                         $array[$to] = & $array[$from];
286                         unset($array[$from]);
287                 } else  {
288                         $array[$to] = $default;
289                 }
290         }
291
292         return TRUE;
293 }
294
295 // Remove redundant values from array()
296 function array_unique_recursive($array = array())
297 {
298         if (! is_array($array)) return $array;
299
300         $tmp = array();
301         foreach($array as $key => $value){
302                 if (is_array($value)) {
303                         $array[$key] = array_unique_recursive($value);
304                 } else {
305                         if (isset($tmp[$value])) {
306                                 unset($array[$key]);
307                         } else {
308                                 $tmp[$value] = TRUE;
309                         }
310                 }
311         }
312
313         return $array;
314 }
315
316 ?>