OSDN Git Service

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