Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
226 | daniel-mar | 1 | <?php |
2 | |||
3 | # TODO: |
||
4 | # <oid1> |
||
5 | # ... |
||
6 | # <orphan> |
||
7 | |||
8 | // TODO: {...} = ein link zu einer whois query |
||
9 | |||
10 | // TODO !list auch ohne oidplus: |
||
11 | |||
12 | # todo: auch "oid:" erlauben (ohne beginning dot) |
||
13 | |||
14 | # TODO is_numeric() nicht verwenden bei oidutils... stattdessen [0-9]+ |
||
15 | |||
16 | // TODO: suchen nach eigenschaften, z.b. created:2012-... |
||
17 | # todo: exceptions im frontent oder false results? |
||
18 | # todo: was ist private, was protected? |
||
19 | # todo: ismU ohne m etc |
||
20 | # todo: headless camel notation |
||
21 | # todo: distance funktion: (a,b) und (b,a) syntax nicht eindeutig... mal so mal so. (plugins/*.php und ipv?_functions.php) |
||
22 | |||
23 | # todo: extends ok oder ist es keine oop-erweiterung? |
||
24 | require_once __DIR__ . '/1_VolcanoDB.class.php'; |
||
25 | class OIDPlus extends VolcanoDB { |
||
26 | protected function displayLine($oid) { |
||
27 | $described = $this->oidDescribed($oid); |
||
28 | $identifiers = $this->getIdentifiers($oid); |
||
29 | $oid_attribs = $this->getOIDAttribs($oid); |
||
30 | |||
31 | $out = $oid; |
||
32 | |||
33 | $oidary = explode('.', $oid); |
||
34 | $lastarc = $oidary[count($oidary)-1]; |
||
35 | if (count($identifiers) == 0) { |
||
36 | $out .= " $lastarc"; |
||
37 | } else { |
||
38 | foreach ($identifiers as $n => $i) { |
||
39 | if ($n != 0) $out .= " |"; |
||
40 | $out .= " $i($lastarc)"; |
||
41 | } |
||
42 | } |
||
43 | if (count($oid_attribs) > 0) { |
||
44 | $out .= " [".implode(',',$oid_attribs)."]"; |
||
45 | } |
||
46 | if (!$described) $out .= " [not described]"; |
||
47 | # TODO: '...' anzeigen zwischen einer OID und einer orphan OID? |
||
48 | return $out; |
||
49 | } |
||
50 | |||
51 | protected function rec_show($oid, &$out, $desc='', $levels=-1) { |
||
52 | $x = $this->listAllOIDs($oid, $levels); |
||
53 | foreach ($x as $oid) { |
||
54 | $out .= $desc . $this->displayLine($oid) . "\n"; |
||
55 | } |
||
56 | unset($x); |
||
57 | } |
||
58 | |||
59 | protected function rec_listAllOIDs($oid, &$out, $levels=-1) { |
||
60 | $children = $this->listChildren($oid, $levels); |
||
61 | if ($children === false) { |
||
62 | #echo "...\n"; # TODO problem, es ist ungewiss ob noch was untergeordnet ist! |
||
63 | return; |
||
64 | } |
||
65 | |||
66 | foreach ($children as $num => &$data) { |
||
67 | $dotstop = self::appendDot($oid); |
||
68 | $cur_oid = $dotstop.$num; |
||
69 | $out[] = $cur_oid; |
||
70 | $this->rec_listAllOIDs($cur_oid, $out, $levels-1); |
||
71 | } |
||
72 | unset($data); |
||
73 | } |
||
74 | |||
75 | public function listAllOIDs($oid, $levels=-1) { |
||
76 | $out = array(); |
||
77 | $this->rec_listAllOIDs($oid, $out, $levels); |
||
78 | return $out; |
||
79 | } |
||
80 | |||
81 | /* TODO: das wäre einfacherer, aber das geht nicht mit orphan OIDS !!! |
||
82 | public function listAllOIDs($parent_oid, $depth=-1, $check_auth=true) { |
||
83 | return $this->listOIDs($parent_oid, true, $depth=-1, $check_auth=true); |
||
84 | } |
||
85 | */ |
||
86 | |||
87 | public function count_roots() { |
||
88 | return count($this->findRoots()); |
||
89 | } |
||
90 | |||
91 | public function count_oids() { |
||
92 | $oids = $this->getAllOIDs(); |
||
93 | return count($oids); |
||
94 | } |
||
95 | |||
96 | public function count_indexes() { |
||
97 | $cnt = 0; |
||
98 | $oids = $this->getAllOIDs(); |
||
99 | foreach ($oids as &$oid) { |
||
100 | $arys = $this->getDatasets($oid, 'index'); |
||
101 | if (count($arys) > 0) $cnt++; |
||
102 | } |
||
103 | return $cnt; |
||
104 | } |
||
105 | |||
106 | protected function sc_listIndexes() { |
||
107 | $out = ''; |
||
108 | # TODO: + oid anzeigen? |
||
109 | $oids = $this->getAllOIDs(); |
||
110 | foreach ($oids as &$oid) { |
||
111 | $arys = $this->getDatasets($oid, 'index'); |
||
112 | foreach ($arys as &$ary) { |
||
113 | if (!isset($ary['attrib_params'][0])) { |
||
114 | throw new VolcanoException('index() field without any param', $ary); |
||
115 | } |
||
116 | $nid = $ary['attrib_params'][0]; |
||
117 | $val = $ary['value']; |
||
118 | # TODO: domain mit puny-decoding? |
||
119 | $out .= "index($nid):$val\n"; |
||
120 | } |
||
121 | } |
||
122 | return $out; |
||
123 | } |
||
124 | |||
125 | protected function sc_listRoots() { |
||
126 | $out = ''; |
||
127 | $roots = $this->findRoots(); |
||
128 | foreach ($roots as &$root) { |
||
129 | $out .= "oid:" . $this->displayLine($root) . "\n"; # todo "oid:" mittels maketabs alignen |
||
130 | } |
||
131 | return $out; |
||
132 | } |
||
133 | |||
134 | protected function sc_list($show_complete_tree = false) { |
||
135 | $out = ''; |
||
136 | if ($show_complete_tree) { |
||
137 | $roots = array('.'); |
||
138 | } else { |
||
139 | $roots = $this->findRoots(); |
||
140 | } |
||
141 | $first = true; |
||
142 | foreach ($roots as &$root) { |
||
143 | // Auskommentiert: Abstand zwischen den OIDs von 2 Roots lassen |
||
144 | // if (!$first) echo "\n"; |
||
145 | $first = false; |
||
146 | $out .= "oid:" . $this->displayLine($root) . "\n"; |
||
147 | $this->rec_show($root, $out, "oid:"); |
||
148 | } |
||
149 | |||
150 | $out2 = array(); |
||
151 | $max_len_oid = 0; |
||
152 | $max_dep_oid = 0; |
||
153 | $min_dep_oid = PHP_INT_MAX; |
||
154 | $lines = explode("\n", trim($out)); |
||
155 | foreach ($lines as &$x) { |
||
156 | $m = explode(' ', $x, 2); |
||
157 | $oid = substr($m[0], 4); |
||
158 | $len = strlen($oid); |
||
159 | $dep = oid_len($oid); |
||
160 | $entry = isset($m[1]) ? $m[1] : ''; |
||
161 | $out2[] = array($len, $dep, $oid, $entry); |
||
162 | if ($len > $max_len_oid) $max_len_oid = $len; |
||
163 | if ($dep > $max_dep_oid) $max_dep_oid = $dep; |
||
164 | if ($dep < $min_dep_oid) $min_dep_oid = $dep; |
||
165 | } |
||
166 | |||
167 | $out = ''; |
||
168 | foreach ($out2 as &$data) { |
||
169 | $len = $data[0]; |
||
170 | $dep = $data[1]; |
||
171 | $oid = $data[2]; |
||
172 | $entry = $data[3]; |
||
173 | |||
174 | if (empty($entry)) $entry = '<no identifier>'; |
||
175 | |||
176 | $oid = str_pad($oid, $max_len_oid); |
||
177 | $entry = str_repeat('. ', $dep-$min_dep_oid).$entry; |
||
178 | |||
179 | $out .= "oid:$oid | $entry\n"; |
||
180 | } |
||
181 | |||
182 | unset($root); |
||
183 | return $out; |
||
184 | } |
||
185 | |||
186 | protected static function help() { |
||
187 | // TODO syntax for searching |
||
188 | echo "System commands:\n"; |
||
189 | echo "\thelp\n"; |
||
190 | echo "\toidplus:!list [#<authtoken>[,<authtoken>[,...]]]\n"; |
||
191 | echo "\toidplus:!listRoots [#<authtoken>[,<authtoken>[,...]]]\n"; |
||
192 | echo "\toidplus:!listIndexes [#<authtoken>[,<authtoken>[,...]]]\n"; |
||
193 | # todo: listAll |
||
194 | echo "\toidplus:!help\n"; |
||
195 | echo "\n"; |
||
196 | echo "Seaching for indexed items (index attribute):\n"; |
||
197 | echo "\toidplus:<index> [#<authtoken>[,<authtoken>[,...]]]\n"; |
||
198 | echo "\n"; |
||
199 | echo "Lookup a single OID:\n"; |
||
200 | echo "\toidplus:.2.999 [#<authtoken>[,<authtoken>[,...]]]\n"; |
||
201 | echo "\toidplus:.2.example [#<authtoken>[,<authtoken>[,...]]]\n"; |
||
202 | } |
||
203 | |||
204 | # todo: kein echo sondern string return? |
||
205 | public function query($q) { |
||
206 | $q = trim($q); |
||
207 | |||
208 | # echo "Process query '$q'\n\n"; |
||
209 | |||
210 | $this->clearAuthTokens(); |
||
211 | |||
212 | if ($q == 'help') { |
||
213 | return self::help(); |
||
214 | } |
||
215 | |||
216 | if (!preg_match('@^oidplus:([^#]+)(#([^#]*)){0,1}$@ismU', $q, $m)) { |
||
217 | # return false; |
||
218 | |||
219 | # TODO: eigentlich sollte die syntax nicht willkürlich sein |
||
220 | # lieber "oid:(non-dotted-oid without authToken and no indexes) |
||
221 | # $q = preg_replace('@^oidplus:@isU', '', $q); |
||
222 | # $q = preg_replace('@^(urn:){0,1}oid:@isU', '.', $q); |
||
223 | $q = preg_replace('@^(urn:){0,1}oid:@isU', '', $q); |
||
224 | if (oid_valid_dotnotation($q, true, false) && ($q[0] != '.')) $q = ".$q"; |
||
225 | |||
226 | $q = "oidplus:$q"; |
||
227 | return $this->query($q); |
||
228 | } else { |
||
229 | $q = trim($m[1]); |
||
230 | $pins = (isset($m[3])) ? trim($m[3]) : null; |
||
231 | |||
232 | if (oid_valid_dotnotation($q, true, false) && ($q[0] != '.')) $q = ".$q"; |
||
233 | } |
||
234 | |||
235 | if (!is_null($pins)) { |
||
236 | $pins = explode(',', $pins); |
||
237 | foreach ($pins as &$pin) { |
||
238 | $this->addAuthToken($pin); |
||
239 | } |
||
240 | unset($pin); |
||
241 | } |
||
242 | |||
243 | if ($q[0] == '!') { |
||
244 | $syscommand = trim(substr($q, 1)); |
||
245 | if ($syscommand == 'help') { |
||
246 | return self::help(); |
||
247 | } else if ($syscommand == 'list') { |
||
248 | $out = self::sc_list(); |
||
249 | echo self::make_tabs($out); |
||
250 | return; |
||
251 | } else if ($syscommand == 'listRoots') { |
||
252 | $out = self::sc_listRoots(); |
||
253 | echo self::make_tabs($out); |
||
254 | return; |
||
255 | } else if ($syscommand == 'listIndexes') { |
||
256 | $out = self::sc_listIndexes(); |
||
257 | echo self::make_tabs($out); |
||
258 | return; |
||
259 | } else { |
||
260 | // TODO error |
||
261 | return false; |
||
262 | } |
||
263 | } else if ($q[0] == '.') { |
||
264 | // Single OID |
||
265 | // TODO auch ohne leading dot? |
||
266 | |||
267 | echo self::make_tabs($this->showSingleOID($q)); |
||
268 | return; |
||
269 | } else { |
||
270 | // Indexed name (string, ipv4, ipv6, domain, doi, guid, ...) |
||
271 | |||
272 | $prefix = ''; |
||
273 | $ary = $this->findOID($q); |
||
274 | if ($ary) { |
||
275 | $oid = $ary[0]; |
||
276 | $dist = $ary[1]; |
||
277 | $nid = $ary[2]; |
||
278 | |||
279 | if ($dist > 0) { |
||
280 | $prefix .= "searchterm:$q\n"; |
||
281 | $prefix .= "search-result:Did not find an exact match for the given searchterm, but found a superior node\n"; |
||
282 | $prefix .= "distance($nid):$dist\n"; |
||
283 | $prefix .= "\n"; |
||
284 | } |
||
285 | |||
286 | echo self::make_tabs($this->showSingleOID($oid, $prefix)); |
||
287 | return; |
||
288 | } else { |
||
289 | $prefix .= "searchterm:$q\n"; |
||
290 | # $prefix .= "search-result:Not found\n"; |
||
291 | $prefix .= "search-result:No exact match and no superior node was found\n"; |
||
292 | echo self::make_tabs($prefix); |
||
293 | } |
||
294 | } |
||
295 | } |
||
296 | |||
297 | public static function filterOutput($output, $name, $preg=false, $including_name=true) { |
||
298 | $out = ''; |
||
299 | |||
300 | $lines = explode("\n", $output); |
||
301 | foreach ($lines as $line) { |
||
302 | $line = trim($line); |
||
303 | if ($line == '') continue; |
||
304 | $name_val = explode(':', $line, 2); |
||
305 | if (count($name_val) != 2) continue; |
||
306 | if ($preg) { |
||
307 | $ok = preg_match($name, $name_val[0], $m); |
||
308 | } else { |
||
309 | $ok = $name == trim($name_val[0]); |
||
310 | } |
||
311 | if ($ok) { |
||
312 | if ($including_name) { |
||
313 | $out .= $line."\n"; |
||
314 | } else { |
||
315 | $out .= $name_val[1]."\n"; |
||
316 | } |
||
317 | } |
||
318 | |||
319 | } |
||
320 | |||
321 | return $out; |
||
322 | } |
||
323 | |||
324 | const SEG_OIDINFO = 2; |
||
325 | const SEG_OIDDATA = 4; |
||
326 | const SEG_IDX_BROWSER = 8; |
||
327 | const SEG_OID_BROWSER = 16; |
||
328 | /*protected*/ public function showSingleOID($oid, $prefix='', $segments = self::SEG_OIDINFO+self::SEG_OIDDATA+self::SEG_IDX_BROWSER+self::SEG_OID_BROWSER, $make_tabs=true) { |
||
329 | if (!oid_valid_dotnotation($oid, true, substr($oid,0,1) == '.')) { |
||
330 | throw new VolcanoException("OID '$oid' is invalid"); |
||
331 | } |
||
332 | |||
333 | $out_segs = array(); |
||
334 | |||
335 | $oid = sanitizeOID($oid, substr($oid,0,1) == '.'); |
||
336 | if ($oid === false) return false; |
||
337 | |||
338 | // --- Segment 1 --- |
||
339 | |||
340 | if (($segments & self::SEG_OIDINFO) == self::SEG_OIDINFO) { |
||
341 | $out = "oid:$oid\n"; # TODO: soll das "searchterm" heißen, wenn nur superior node gefunden wurde? |
||
342 | |||
343 | # TODO: nach search-result: verschieben? |
||
344 | foreach (self::$fieldExtenders as $fe) { |
||
345 | $x = array(); |
||
346 | $fe->processOID($oid, $x, $this); |
||
347 | if (count($x) > 0) { |
||
348 | $out .= implode("\n", $x)."\n"; |
||
349 | } |
||
350 | } |
||
351 | |||
352 | if ($this->oidDescribed($oid)) { |
||
353 | $out .= "search-result:Found\n"; |
||
354 | } else { |
||
355 | # TODO: wenn der user eine ungültige oid eingibt, dann keinen "internal error" werfen |
||
356 | $out .= "search-result:Not found\n"; |
||
357 | } |
||
358 | |||
359 | $out_segs[] = $out; |
||
360 | } |
||
361 | |||
362 | // --- Segment 2 --- |
||
363 | |||
364 | if (($segments & self::SEG_OIDDATA) == self::SEG_OIDDATA) { |
||
365 | $out = ''; |
||
366 | $x = $this->getDatasets($oid); |
||
367 | foreach ($x as &$y) { |
||
368 | if ($this->isSpecialInvisibleField($y)) continue; // system fields, like '*read-auth' are invisible |
||
369 | $out .= $y['attrib_name']; |
||
370 | if (count($y['attrib_params']) > 0) $out .= '('.implode(',', $y['attrib_params']).')'; |
||
371 | $out .= ':'.$y['value']."\n"; # todo: +params? TEST. |
||
372 | } |
||
373 | |||
374 | $out_segs[] = $out; |
||
375 | } |
||
376 | |||
377 | # --- Segment 3: Index-Navigation --- |
||
378 | |||
379 | if (($segments & self::SEG_IDX_BROWSER) == self::SEG_IDX_BROWSER) { |
||
380 | $index_browser_ns = ''; |
||
381 | $index_browser_val = ''; |
||
382 | $index_browser_found = false; |
||
383 | if (isset($this->oid_data[$oid])) { |
||
384 | foreach ($this->oid_data[$oid] as $tmp) { |
||
385 | if ($tmp['attrib_name'] == 'index') { |
||
386 | if (!isset($tmp['attrib_params'][0])) continue; # TODO: exception? |
||
387 | $index_browser_ns = $tmp['attrib_params'][0]; |
||
388 | |||
389 | # $index_browser_val = $tmp['value']; |
||
390 | if (($tmp['flag_confidential']) && (!$this->isAuthentificated($oid))) { |
||
391 | if (!$this->isRedactedMessageEnabled()) { |
||
392 | continue; // hide complete line |
||
393 | } else { |
||
394 | $index_browser_val = $this->redactedMessage; |
||
395 | } |
||
396 | } else { |
||
397 | $index_browser_val = $tmp['value']; |
||
398 | } |
||
399 | |||
400 | $index_browser_found = true; |
||
401 | break; |
||
402 | } |
||
403 | } |
||
404 | } |
||
405 | |||
406 | if (($index_browser_found) && ($found_prov = self::findSearchProvider($index_browser_ns))) { |
||
407 | $out = ''; |
||
408 | |||
409 | $nearest_father = array(false, PHP_INT_MAX, ''); |
||
410 | $subs = array(); |
||
411 | |||
412 | $index_ns_root = oid_up($oid); |
||
413 | |||
414 | $cry = $this->listChildren($index_ns_root, 1); |
||
415 | foreach ($cry as $num => $c) { |
||
416 | $oid_2 = $index_ns_root.'.'.$num; |
||
417 | |||
418 | $index_browser_ns_2 = ''; |
||
419 | $index_browser_val_2 = ''; |
||
420 | $index_browser_found_2 = false; |
||
421 | foreach ($this->oid_data[$oid_2] as $tmp_2) { |
||
422 | if ($tmp_2['attrib_name'] == 'index') { |
||
423 | if (!isset($tmp_2['attrib_params'][0])) continue; # TODO: exception? |
||
424 | $index_browser_ns_2 = $tmp_2['attrib_params'][0]; |
||
425 | |||
426 | # $index_browser_val_2 = $tmp_2['value']; |
||
427 | if (($tmp_2['flag_confidential']) && (!$this->isAuthentificated($oid_2))) { |
||
428 | if (!$this->isRedactedMessageEnabled()) { |
||
429 | continue; // hide complete line |
||
430 | } else { |
||
431 | $index_browser_val_2 = $this->redactedMessage; |
||
432 | } |
||
433 | } else { |
||
434 | $index_browser_val_2 = $tmp_2['value']; |
||
435 | } |
||
436 | |||
437 | $index_browser_found_2 = true; |
||
438 | break; |
||
439 | } |
||
440 | } |
||
441 | |||
442 | if ($index_browser_found_2) { |
||
443 | $cur_distance = $found_prov->calcDistance($index_browser_val, $index_browser_val_2); |
||
444 | |||
445 | if ($index_browser_val == $index_browser_val_2) continue; |
||
446 | |||
447 | if ($cur_distance === false) continue; |
||
448 | |||
449 | if ($cur_distance < 0) { |
||
450 | if (abs($cur_distance) < $nearest_father[1]) { |
||
451 | $nearest_father[0] = true; |
||
452 | $nearest_father[1] = abs($cur_distance); |
||
453 | $nearest_father[2] = array($index_browser_val_2); |
||
454 | } else if (abs($cur_distance) == $nearest_father[1]) { |
||
455 | $nearest_father[2][] = $index_browser_val_2; |
||
456 | } |
||
457 | } else if ($cur_distance > 0) { |
||
458 | $subs[] = $index_browser_val_2; |
||
459 | } |
||
460 | } |
||
461 | } |
||
462 | |||
463 | # TODO FUT: brothers (selbe dist zum vater) |
||
464 | |||
465 | // Nur die untergeordneten Knoten anzeigen, zwischen denen kein weiterer Knoten zu unserem Knoten besteht. |
||
466 | // K <-- a <-- a' <-- a'' |
||
467 | // <-- b <-- b' |
||
468 | // <-- c |
||
469 | // => Wähle a, b, c |
||
470 | foreach ($subs as &$sub1) { |
||
471 | foreach ($subs as &$sub2) { |
||
472 | if ($sub1 == $sub2) continue; |
||
473 | |||
474 | $dist = ($found_prov->calcDistance($sub1, $sub2)); |
||
475 | if ($dist === false) continue; |
||
476 | if ($dist > 0) $sub2 = null; |
||
477 | } |
||
478 | } |
||
479 | |||
480 | if ($nearest_father[0]) { |
||
481 | foreach ($nearest_father[2] as $tmp) { |
||
482 | $out .= "father-index($index_browser_ns):$tmp\n"; |
||
483 | } |
||
484 | } |
||
485 | $out .= "self-index($index_browser_ns):$index_browser_val\n"; |
||
486 | foreach ($subs as $tmp) { |
||
487 | if (is_null($tmp)) continue; |
||
488 | $out .= "son-index($index_browser_ns):$tmp\n"; |
||
489 | } |
||
490 | |||
491 | $out_segs[] = $out; |
||
492 | } |
||
493 | } |
||
494 | |||
495 | # --- Segment 4: OID Navigation --- |
||
496 | |||
497 | if (($segments & self::SEG_OID_BROWSER) == self::SEG_OID_BROWSER) { |
||
498 | $out = ''; |
||
499 | |||
500 | // Show father |
||
501 | if ($oid != '.') { |
||
502 | // $out .= "father:" . $this->displayLine(oid_up($oid)) . "\n"; |
||
503 | $i=0; |
||
504 | $cur_oid = $oid; |
||
505 | $father_out = ''; |
||
506 | |||
507 | $tmp_table = array(); |
||
508 | |||
509 | while ($cur_oid != '.') { |
||
510 | $i++; |
||
511 | $cur_oid = oid_up($cur_oid); |
||
512 | $tmp_table[] = array($this->oidDescribed($cur_oid), "superior-node($i):" . $this->displayLine($cur_oid)); |
||
513 | } |
||
514 | |||
515 | $described_once = false; |
||
516 | for ($i=count($tmp_table)-1; $i>=0; $i--) { |
||
517 | $t = $tmp_table[$i]; |
||
518 | |||
519 | $is_desc = $t[0]; |
||
520 | $line = $t[1]; |
||
521 | |||
522 | if ($is_desc) $described_once = true; |
||
523 | |||
524 | if ($is_desc || $described_once ) { |
||
525 | $father_out .= "$line\n"; |
||
526 | } |
||
527 | } |
||
528 | |||
529 | $out .= $father_out; |
||
530 | } |
||
531 | |||
532 | // Show current OID |
||
533 | $out .= "current-node:" . $this->displayLine($oid) . "\n"; |
||
534 | |||
535 | // Show first level children (also undescribed ones) |
||
536 | $x = $this->listChildren($oid, 1); |
||
537 | foreach ($x as $num => &$data) { |
||
538 | $dotstop = self::appendDot($oid); |
||
539 | $cur_oid = $dotstop.$num; |
||
540 | $out .= "child-node:" . $this->displayLine($cur_oid) . "\n"; |
||
541 | } |
||
542 | |||
543 | $out_segs[] = $out; |
||
544 | |||
545 | // Brothers |
||
546 | |||
547 | $out = ''; |
||
548 | |||
549 | $x = $this->listChildren(oid_up($oid), 1); |
||
550 | foreach ($x as $num => &$data) { |
||
551 | $dotstop = self::appendDot(oid_up($oid)); |
||
552 | $cur_oid = $dotstop.$num; |
||
553 | if ($cur_oid != $oid) $out .= "brother:" . $this->displayLine($cur_oid) . "\n"; |
||
554 | } |
||
555 | |||
556 | $out_segs[] = $out; |
||
557 | } |
||
558 | |||
559 | // --- Output --- |
||
560 | |||
561 | $out = $prefix; |
||
562 | $first = true; |
||
563 | foreach ($out_segs as $seg) { |
||
564 | if (!$first) { |
||
565 | $out .= ":----------------------\n"; # TODO: max len of output |
||
566 | } |
||
567 | $out .= $seg; |
||
568 | $first = false; |
||
569 | } |
||
570 | |||
571 | if ($make_tabs) { |
||
572 | $out = self::make_tabs($out); |
||
573 | } |
||
574 | |||
575 | return $out; |
||
576 | } |
||
577 | |||
578 | # http://whois.viathinksoft.de/gwhois_fork/showcode/?fn=package%2Fshare%2Fsubprograms%2Ffunctions.inc.php |
||
579 | # Changed: $abstand default 4->2, oop, +$mindestbreite |
||
580 | protected static function make_tabs($text, $abstand = 2, $mindestbreite = 0) { |
||
581 | $ary = explode("\n", $text); |
||
582 | $longest = 0; |
||
583 | foreach ($ary as &$a) { |
||
584 | $bry = explode(':', $a, 2); |
||
585 | if (count($bry) < 2) continue; |
||
586 | $c = strlen($bry[0]); |
||
587 | if ($c > $longest) $longest = $c; |
||
588 | } |
||
589 | if ($longest < $mindestbreite) $longest = $mindestbreite; |
||
590 | foreach ($ary as $n => &$a) { |
||
591 | $bry = explode(':', $a, 2); |
||
592 | if (count($bry) < 2) continue; |
||
593 | $rep = $longest-strlen($bry[0]) + $abstand; |
||
594 | if ($rep < 1) { |
||
595 | $wh = ''; |
||
596 | } else { |
||
597 | $wh = str_repeat(' ', $rep); |
||
598 | } |
||
599 | $ary[$n] = ($bry[0] != '' ? $bry[0].':' : ' ').$wh.trim($bry[1]); |
||
600 | } |
||
601 | $x = implode("\n", $ary); |
||
602 | return $x; |
||
603 | } |
||
604 | |||
605 | |||
606 | protected static $fieldExtenders = array(); |
||
607 | |||
608 | public static function registerFieldExtender($prov) { |
||
609 | self::$fieldExtenders[] = $prov; |
||
610 | } |
||
611 | |||
612 | } |