1 | <?php |
---|
2 | |
---|
3 | /***************************************************************************\ |
---|
4 | * SPIP, Systeme de publication pour l'internet * |
---|
5 | * * |
---|
6 | * Copyright (c) 2001-2011 * |
---|
7 | * Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James * |
---|
8 | * * |
---|
9 | * Ce programme est un logiciel libre distribue sous licence GNU/GPL. * |
---|
10 | * Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne. * |
---|
11 | \***************************************************************************/ |
---|
12 | |
---|
13 | if (!defined('_ECRIRE_INC_VERSION')) return; |
---|
14 | |
---|
15 | include_spip('iterateur/iterateur'); |
---|
16 | |
---|
17 | |
---|
18 | /** |
---|
19 | * creer une boucle sur un iterateur DATA |
---|
20 | * annonce au compilo les "champs" disponibles |
---|
21 | * |
---|
22 | * @param $b |
---|
23 | * @return |
---|
24 | */ |
---|
25 | function iterateur_DATA_dist($b) { |
---|
26 | $b->iterateur = 'DATA'; # designe la classe d'iterateur |
---|
27 | $b->show = array( |
---|
28 | 'field' => array( |
---|
29 | 'cle' => 'STRING', |
---|
30 | 'valeur' => 'STRING', |
---|
31 | '*' => 'ALL' // Champ joker * |
---|
32 | ) |
---|
33 | ); |
---|
34 | $b->select[] = '.valeur'; |
---|
35 | return $b; |
---|
36 | } |
---|
37 | |
---|
38 | |
---|
39 | /** |
---|
40 | * IterateurDATA pour iterer sur des donnees |
---|
41 | */ |
---|
42 | class IterateurDATA implements Iterator { |
---|
43 | /** |
---|
44 | * tableau de donnees |
---|
45 | * @var array |
---|
46 | */ |
---|
47 | protected $tableau = array(); |
---|
48 | |
---|
49 | /** |
---|
50 | * Conditions de filtrage |
---|
51 | * ie criteres de selection |
---|
52 | * @var array |
---|
53 | */ |
---|
54 | protected $filtre = array(); |
---|
55 | |
---|
56 | |
---|
57 | /** |
---|
58 | * Cle courante |
---|
59 | * @var null |
---|
60 | */ |
---|
61 | protected $cle = null; |
---|
62 | |
---|
63 | /** |
---|
64 | * Valeur courante |
---|
65 | * @var null |
---|
66 | */ |
---|
67 | protected $valeur = null; |
---|
68 | |
---|
69 | /** |
---|
70 | * Constructeur |
---|
71 | * |
---|
72 | * @param $command |
---|
73 | * @param array $info |
---|
74 | */ |
---|
75 | public function __construct($command, $info=array()) { |
---|
76 | $this->type='DATA'; |
---|
77 | $this->command = $command; |
---|
78 | $this->info = $info; |
---|
79 | |
---|
80 | $this->select($command); |
---|
81 | } |
---|
82 | |
---|
83 | /** |
---|
84 | * Revenir au depart |
---|
85 | * @return void |
---|
86 | */ |
---|
87 | public function rewind() { |
---|
88 | reset($this->tableau); |
---|
89 | list($this->cle, $this->valeur) = each($this->tableau); |
---|
90 | } |
---|
91 | |
---|
92 | /** |
---|
93 | * Declarer les criteres exceptions |
---|
94 | * @return array |
---|
95 | */ |
---|
96 | public function exception_des_criteres() { |
---|
97 | return array('tableau'); |
---|
98 | } |
---|
99 | |
---|
100 | /** |
---|
101 | * Recuperer depuis le cache si possible |
---|
102 | * @param $cle |
---|
103 | * @return |
---|
104 | */ |
---|
105 | protected function cache_get($cle) { |
---|
106 | if (!$cle) return; |
---|
107 | # utiliser memoization si dispo |
---|
108 | include_spip('inc/memoization'); |
---|
109 | if (!function_exists('cache_get')) return; |
---|
110 | return cache_get($cle); |
---|
111 | } |
---|
112 | |
---|
113 | /** |
---|
114 | * Srtocker en cache si possible |
---|
115 | * @param $cle |
---|
116 | * @param $ttl |
---|
117 | * @return |
---|
118 | */ |
---|
119 | protected function cache_set($cle, $ttl) { |
---|
120 | if (!$cle) return; |
---|
121 | # utiliser memoization si dispo |
---|
122 | include_spip('inc/memoization'); |
---|
123 | if (!function_exists('cache_set')) return; |
---|
124 | return cache_set($cle, |
---|
125 | array( |
---|
126 | 'data' => $this->tableau, |
---|
127 | 'time' => time(), |
---|
128 | 'ttl' => $ttl |
---|
129 | ), |
---|
130 | 3600 + $ttl); |
---|
131 | # conserver le cache 1h deplus que la validite demandee, |
---|
132 | # pour le cas ou le serveur distant ne repond plus |
---|
133 | } |
---|
134 | |
---|
135 | /** |
---|
136 | * Aller chercher les donnees de la boucle DATA |
---|
137 | * |
---|
138 | * @throws Exception |
---|
139 | * @param $command |
---|
140 | * @return void |
---|
141 | */ |
---|
142 | protected function select($command) { |
---|
143 | |
---|
144 | // l'iterateur DATA peut etre appele en passant (data:type) |
---|
145 | // le type se retrouve dans la commande 'from' |
---|
146 | // dans ce cas la le critere {source} n'a pas besoin du 1er argument |
---|
147 | if (isset($this->command['from'][0])) { |
---|
148 | array_unshift($this->command['source'], $this->command['sourcemode']); |
---|
149 | $this->command['sourcemode'] = $this->command['from'][0]; |
---|
150 | } |
---|
151 | |
---|
152 | // les commandes connues pour l'iterateur DATA |
---|
153 | // sont : {tableau #ARRAY} ; {cle=...} ; {valeur=...} |
---|
154 | // {source format, [URL], [arg2]...} |
---|
155 | |
---|
156 | if (isset($this->command['source']) |
---|
157 | AND isset($this->command['sourcemode'])) { |
---|
158 | |
---|
159 | # un peu crado : avant de charger le cache il faut charger |
---|
160 | # les class indispensables, sinon PHP ne saura pas gerer |
---|
161 | # l'objet en cache ; cf plugins/icalendar |
---|
162 | # perf : pas de fonction table_to_array ! (table est deja un array) |
---|
163 | if (isset($this->command['sourcemode']) |
---|
164 | AND !in_array($this->command['sourcemode'],array('table', 'array', 'tableau'))) |
---|
165 | charger_fonction($this->command['sourcemode'] . '_to_array', 'inc', true); |
---|
166 | |
---|
167 | # le premier argument peut etre un array, une URL etc. |
---|
168 | $src = $this->command['source'][0]; |
---|
169 | |
---|
170 | # avons-nous un cache dispo ? |
---|
171 | if (is_string($src)) |
---|
172 | $cle = 'datasource_'.md5($this->command['sourcemode'].':'.var_export($this->command['source'],true)); |
---|
173 | |
---|
174 | $cache = $this->cache_get($cle); |
---|
175 | if (isset($this->command['datacache'])) |
---|
176 | $ttl = intval($this->command['datacache']); |
---|
177 | if ($cache |
---|
178 | AND ($cache['time'] + (isset($ttl) ? $ttl : $cache['ttl']) |
---|
179 | > time()) |
---|
180 | AND !(_request('var_mode') === 'recalcul' |
---|
181 | AND include_spip('inc/autoriser') |
---|
182 | AND autoriser('recalcul') |
---|
183 | )) { |
---|
184 | $this->tableau = $cache['data']; |
---|
185 | } |
---|
186 | else try { |
---|
187 | # dommage que ca ne soit pas une option de yql_to_array... |
---|
188 | if ($this->command['sourcemode'] == 'yql') |
---|
189 | if (!isset($ttl)) $ttl = 3600; |
---|
190 | |
---|
191 | if (isset($this->command['sourcemode']) |
---|
192 | AND in_array($this->command['sourcemode'], |
---|
193 | array('table', 'array', 'tableau')) |
---|
194 | ) { |
---|
195 | if (is_array($a = $src) |
---|
196 | OR (is_string($a) |
---|
197 | AND $a = str_replace('"', '"', $a) # fragile! |
---|
198 | AND is_array($a = @unserialize($a))) |
---|
199 | ) |
---|
200 | $this->tableau = $a; |
---|
201 | } |
---|
202 | else { |
---|
203 | if (preg_match(',^https?://,', $src)) { |
---|
204 | include_spip('inc/distant'); |
---|
205 | $u = recuperer_page($src); |
---|
206 | if (!$u) |
---|
207 | throw new Exception("404"); |
---|
208 | if (!isset($ttl)) $ttl = 24*3600; |
---|
209 | } else if (@is_dir($src)) { |
---|
210 | $u = $src; |
---|
211 | if (!isset($ttl)) $ttl = 10; |
---|
212 | } else if (@is_readable($src) && @is_file($src)) { |
---|
213 | $u = spip_file_get_contents($src); |
---|
214 | if (!isset($ttl)) $ttl = 10; |
---|
215 | } else { |
---|
216 | $u = $src; |
---|
217 | if (!isset($ttl)) $ttl = 10; |
---|
218 | } |
---|
219 | if (!$this->err |
---|
220 | AND $g = charger_fonction($this->command['sourcemode'] . '_to_array', 'inc', true)) { |
---|
221 | $args = $this->command['source']; |
---|
222 | $args[0] = $u; |
---|
223 | if (is_array($a = call_user_func_array($g,$args))) { |
---|
224 | $this->tableau = $a; |
---|
225 | } |
---|
226 | } |
---|
227 | } |
---|
228 | |
---|
229 | if (!is_array($this->tableau)) |
---|
230 | $this->err = true; |
---|
231 | |
---|
232 | if (!$this->err AND $ttl>0) |
---|
233 | $this->cache_set($cle, $ttl); |
---|
234 | |
---|
235 | } |
---|
236 | catch (Exception $e) { |
---|
237 | $e = $e->getMessage(); |
---|
238 | $err = sprintf("[%s, %s] $e", |
---|
239 | $src, |
---|
240 | $this->command['sourcemode']); |
---|
241 | erreur_squelette(array($err, array())); |
---|
242 | $this->err = true; |
---|
243 | } |
---|
244 | |
---|
245 | # en cas d'erreur, utiliser le cache si encore dispo |
---|
246 | if ($this->err |
---|
247 | AND $cache) { |
---|
248 | $this->tableau = $cache['data']; |
---|
249 | $this->err = false; |
---|
250 | } |
---|
251 | |
---|
252 | } |
---|
253 | |
---|
254 | // Critere {liste X1, X2, X3} |
---|
255 | if (isset($this->command['liste'])) { |
---|
256 | # s'il n'y a qu'une valeur dans la liste, sans doute une #BALISE |
---|
257 | if (!isset($this->command['liste'][1])) { |
---|
258 | $this->command['liste'] = explode(',', $this->command['liste'][0]); |
---|
259 | } |
---|
260 | $this->tableau = $this->command['liste']; |
---|
261 | } |
---|
262 | |
---|
263 | // Si a ce stade on n'a pas de table, il y a un bug |
---|
264 | if (!is_array($this->tableau)) { |
---|
265 | $this->err = true; |
---|
266 | spip_log("erreur datasource ".$src); |
---|
267 | } |
---|
268 | |
---|
269 | |
---|
270 | // {datapath query.results} |
---|
271 | // extraire le chemin "query.results" du tableau de donnees |
---|
272 | if (!$this->err |
---|
273 | AND is_array($this->command['datapath'])) { |
---|
274 | list(,$base) = each($this->command['datapath']); |
---|
275 | if (strlen($base = trim($base))) { |
---|
276 | $this->tableau = Iterateurs_table_valeur($this->tableau, $base); |
---|
277 | if (!is_array($this->tableau)) { |
---|
278 | $this->tableau = array(); |
---|
279 | $this->err = true; |
---|
280 | spip_log("datapath '$base' absent"); |
---|
281 | } |
---|
282 | } |
---|
283 | } |
---|
284 | |
---|
285 | // tri {par x} |
---|
286 | if ($this->command['orderby']) { |
---|
287 | $sortfunc = ''; |
---|
288 | $aleas = 0; |
---|
289 | foreach($this->command['orderby'] as $tri) { |
---|
290 | if (preg_match(',^\.?([/\w]+)( DESC)?$,iS', $tri, $r)) { |
---|
291 | // tri par cle |
---|
292 | if ($r[1] == 'cle'){ |
---|
293 | if ($r[2]) |
---|
294 | krsort($this->tableau); |
---|
295 | else |
---|
296 | ksort($this->tableau); |
---|
297 | } |
---|
298 | # {par hasard} |
---|
299 | else if ($r[1] == 'alea') { |
---|
300 | $k = array_keys($this->tableau); |
---|
301 | shuffle($k); |
---|
302 | $v = array(); |
---|
303 | foreach($k as $cle) |
---|
304 | $v[$cle] = $this->tableau[$cle]; |
---|
305 | $this->tableau = $v; |
---|
306 | } |
---|
307 | else { |
---|
308 | # {par valeur} |
---|
309 | if ($r[1] == 'valeur') |
---|
310 | $tv = '%s'; |
---|
311 | # {par valeur/xx/yy} ?? |
---|
312 | else |
---|
313 | $tv = 'Iterateurs_table_valeur(%s, '.var_export($r[1],true).')'; |
---|
314 | $sortfunc .= ' |
---|
315 | $a = '.sprintf($tv,'$aa').'; |
---|
316 | $b = '.sprintf($tv,'$bb').'; |
---|
317 | if ($a <> $b) |
---|
318 | return ($a ' . ($r[2] ? '>' : '<').' $b) ? -1 : 1;'; |
---|
319 | } |
---|
320 | } |
---|
321 | } |
---|
322 | |
---|
323 | if ($sortfunc) { |
---|
324 | uasort($this->tableau, create_function('$aa,$bb', |
---|
325 | $sortfunc.' |
---|
326 | return 0;' |
---|
327 | )); |
---|
328 | } |
---|
329 | } |
---|
330 | |
---|
331 | // grouper les resultats {fusion /x/y/z} ; |
---|
332 | if ($this->command['groupby'] |
---|
333 | AND strlen($fusion = $this->command['groupby'][0])) { |
---|
334 | $vu = array(); |
---|
335 | foreach($this->tableau as $k => $v) { |
---|
336 | $val = Iterateurs_table_valeur($v, $fusion); |
---|
337 | if (isset($vu[$val])) |
---|
338 | unset($this->tableau[$k]); |
---|
339 | else |
---|
340 | $vu[$val] = true; |
---|
341 | } |
---|
342 | } |
---|
343 | |
---|
344 | $this->rewind(); |
---|
345 | #var_dump($this->tableau); |
---|
346 | } |
---|
347 | |
---|
348 | |
---|
349 | /** |
---|
350 | * L'iterateur est-il encore valide ? |
---|
351 | * @return bool |
---|
352 | */ |
---|
353 | public function valid(){ |
---|
354 | return !is_null($this->cle); |
---|
355 | } |
---|
356 | |
---|
357 | /** |
---|
358 | * Retourner la valeur |
---|
359 | * @return null |
---|
360 | */ |
---|
361 | public function current() { |
---|
362 | return $this->valeur; |
---|
363 | } |
---|
364 | |
---|
365 | /** |
---|
366 | * Retourner la cle |
---|
367 | * @return null |
---|
368 | */ |
---|
369 | public function key() { |
---|
370 | return $this->cle; |
---|
371 | } |
---|
372 | |
---|
373 | /** |
---|
374 | * Passer a la valeur suivante |
---|
375 | * @return void |
---|
376 | */ |
---|
377 | public function next(){ |
---|
378 | if ($this->valid()) |
---|
379 | list($this->cle, $this->valeur) = each($this->tableau); |
---|
380 | } |
---|
381 | |
---|
382 | /** |
---|
383 | * Compter le nombre total de resultats |
---|
384 | * @return int |
---|
385 | */ |
---|
386 | public function count() { |
---|
387 | if (is_null($this->total)) |
---|
388 | $this->total = count($this->tableau); |
---|
389 | return $this->total; |
---|
390 | } |
---|
391 | } |
---|
392 | |
---|
393 | /* |
---|
394 | * Fonctions de transformation donnee => tableau |
---|
395 | */ |
---|
396 | |
---|
397 | /** |
---|
398 | * file -> tableau |
---|
399 | * |
---|
400 | * @param string $u |
---|
401 | * @return array |
---|
402 | */ |
---|
403 | function inc_file_to_array_dist($u) { |
---|
404 | return preg_split('/\r?\n/', $u); |
---|
405 | } |
---|
406 | |
---|
407 | /** |
---|
408 | * plugins -> tableau |
---|
409 | * @return unknown |
---|
410 | */ |
---|
411 | function inc_plugins_to_array_dist() { |
---|
412 | include_spip('inc/plugin'); |
---|
413 | return liste_chemin_plugin_actifs(); |
---|
414 | } |
---|
415 | |
---|
416 | /** |
---|
417 | * xml -> tableau |
---|
418 | * @param string $u |
---|
419 | * @return array |
---|
420 | */ |
---|
421 | function inc_xml_to_array_dist($u) { |
---|
422 | return @XMLObjectToArray(new SimpleXmlIterator($u)); |
---|
423 | } |
---|
424 | /** |
---|
425 | * |
---|
426 | * object -> tableau |
---|
427 | * |
---|
428 | * @param object $object The object to convert |
---|
429 | * @return array |
---|
430 | * |
---|
431 | */ |
---|
432 | function inc_object_to_array( $object ) { |
---|
433 | if( !is_object( $object ) && !is_array( $object ) ) { |
---|
434 | return $object; |
---|
435 | } |
---|
436 | if( is_object( $object ) ) { |
---|
437 | $object = get_object_vars( $object ); |
---|
438 | } |
---|
439 | return array_map( 'inc_object_to_array', $object ); |
---|
440 | } |
---|
441 | |
---|
442 | /** |
---|
443 | * yql -> tableau |
---|
444 | * @throws Exception |
---|
445 | * @param string $u |
---|
446 | * @return array|bool |
---|
447 | */ |
---|
448 | function inc_yql_to_array_dist($u) { |
---|
449 | define('_YQL_ENDPOINT', 'http://query.yahooapis.com/v1/public/yql?&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys&q='); |
---|
450 | $v = recuperer_page($url = _YQL_ENDPOINT.urlencode($u).'&format=json'); |
---|
451 | $w = json_decode($v); |
---|
452 | if (!$w) { |
---|
453 | throw new Exception('YQL: réponse vide ou mal formée'); |
---|
454 | return false; |
---|
455 | } |
---|
456 | return inc_object_to_array($w); |
---|
457 | } |
---|
458 | |
---|
459 | /** |
---|
460 | * sql -> tableau |
---|
461 | * @param string $u |
---|
462 | * @return array|bool |
---|
463 | */ |
---|
464 | function inc_sql_to_array_dist($u) { |
---|
465 | # sortir le connecteur de $u |
---|
466 | preg_match(',^(?:(\w+):)?(.*)$,S', $u, $v); |
---|
467 | $serveur = (string) $v[1]; |
---|
468 | $req = trim($v[2]); |
---|
469 | if ($s = sql_query($req, $serveur)) { |
---|
470 | $r = array(); |
---|
471 | while ($t = sql_fetch($s)) |
---|
472 | $r[] = $t; |
---|
473 | return $r; |
---|
474 | } |
---|
475 | return false; |
---|
476 | } |
---|
477 | |
---|
478 | /** |
---|
479 | * json -> tableau |
---|
480 | * @param string $u |
---|
481 | * @return array|bool |
---|
482 | */ |
---|
483 | function inc_json_to_array_dist($u) { |
---|
484 | if (is_array($json = json_decode($u)) |
---|
485 | OR is_object($json)) |
---|
486 | return (array) $json; |
---|
487 | } |
---|
488 | |
---|
489 | /** |
---|
490 | * csv -> tableau |
---|
491 | * @param string $u |
---|
492 | * @return array|bool |
---|
493 | */ |
---|
494 | function inc_csv_to_array_dist($u) { |
---|
495 | include_spip('inc/csv'); |
---|
496 | list($entete,$csv) = analyse_csv($u); |
---|
497 | array_unshift($csv,$entete); |
---|
498 | |
---|
499 | include_spip('inc/charsets'); |
---|
500 | $i = 1 ; |
---|
501 | foreach ($entete as $k => $v) { |
---|
502 | if (trim($v) == "") $v = "col".$i ; // reperer des eventuelles cases vides |
---|
503 | if (is_numeric($v) and $v < 0) $v = "__".$v; // ne pas risquer d'ecraser une cle numerique |
---|
504 | if (is_numeric($v)) $v = "_".$v; // ne pas risquer d'ecraser une cle numerique |
---|
505 | $v = strtolower(preg_replace(',\W+,', '_', translitteration($v))); |
---|
506 | foreach ($csv as &$item) |
---|
507 | $item[$v] = &$item[$k]; |
---|
508 | $i++; |
---|
509 | } |
---|
510 | return $csv; |
---|
511 | } |
---|
512 | |
---|
513 | /** |
---|
514 | * RSS -> tableau |
---|
515 | * @param string $u |
---|
516 | * @return array|bool |
---|
517 | */ |
---|
518 | function inc_rss_to_array_dist($u) { |
---|
519 | include_spip('inc/syndic'); |
---|
520 | if (is_array($rss = analyser_backend($u))) |
---|
521 | $tableau = $rss; |
---|
522 | return $tableau; |
---|
523 | } |
---|
524 | |
---|
525 | /** |
---|
526 | * atom, alias de rss -> tableau |
---|
527 | * @param string $u |
---|
528 | * @return array|bool |
---|
529 | */ |
---|
530 | function inc_atom_to_array_dist($u) { |
---|
531 | $g = charger_fonction('rss_to_array', 'inc'); |
---|
532 | return $g($u); |
---|
533 | } |
---|
534 | |
---|
535 | /** |
---|
536 | * glob -> tableau |
---|
537 | * lister des fichiers selon un masque, pour la syntaxe cf php.net/glob |
---|
538 | * @param string $u |
---|
539 | * @return array|bool |
---|
540 | */ |
---|
541 | function inc_glob_to_array_dist($u) { |
---|
542 | $a = glob($u, |
---|
543 | GLOB_MARK | GLOB_NOSORT | GLOB_BRACE |
---|
544 | ); |
---|
545 | return $a ? $a : array(); |
---|
546 | } |
---|
547 | |
---|
548 | /** |
---|
549 | * pregfiles -> tableau |
---|
550 | * lister des fichiers a partir d'un dossier de base et selon une regexp. |
---|
551 | * pour la syntaxe cf la fonction spip preg_files |
---|
552 | * @param string $dir |
---|
553 | * @param string $regexp |
---|
554 | * @param int $limit |
---|
555 | * @return array|bool |
---|
556 | */ |
---|
557 | function inc_pregfiles_to_array_dist($dir, $regexp=-1, $limit=10000) { |
---|
558 | return (array) preg_files($dir, $regexp, $limit); |
---|
559 | } |
---|
560 | |
---|
561 | /** |
---|
562 | * ls -> tableau |
---|
563 | * ls : lister des fichiers selon un masque glob |
---|
564 | * et renvoyer aussi leurs donnees php.net/stat |
---|
565 | * @param string $u |
---|
566 | * @return array|bool |
---|
567 | */ |
---|
568 | function inc_ls_to_array_dist($u) { |
---|
569 | $glob = charger_fonction('glob_to_array', 'inc'); |
---|
570 | $a = $glob($u); |
---|
571 | foreach ($a as &$v) { |
---|
572 | $b = (array) @stat($v); |
---|
573 | foreach ($b as $k => $ignore) |
---|
574 | if (is_numeric($k)) unset($b[$k]); |
---|
575 | $b['file'] = preg_replace('`/$`','',$v) ; |
---|
576 | $v = array_merge( |
---|
577 | pathinfo($v), |
---|
578 | $b |
---|
579 | ); |
---|
580 | } |
---|
581 | return $a; |
---|
582 | } |
---|
583 | |
---|
584 | /** |
---|
585 | * Object -> tableau |
---|
586 | * @param Object $object |
---|
587 | * @return array|bool |
---|
588 | */ |
---|
589 | function XMLObjectToArray($object){ |
---|
590 | $xml_array = array(); |
---|
591 | for( $object->rewind(); $object->valid(); $object->next() ) { |
---|
592 | if(array_key_exists($key = $object->key(), $xml_array)){ |
---|
593 | $key .= '-'.uniqid(); |
---|
594 | } |
---|
595 | $vars = get_object_vars($object->current()); |
---|
596 | if (isset($vars['@attributes'])) |
---|
597 | foreach($vars['@attributes'] as $k => $v) |
---|
598 | $xml_array[$key][$k] = $v; |
---|
599 | if($object->hasChildren()){ |
---|
600 | $xml_array[$key][] = XMLObjectToArray( |
---|
601 | $object->current()); |
---|
602 | } |
---|
603 | else{ |
---|
604 | $xml_array[$key][] = strval($object->current()); |
---|
605 | } |
---|
606 | } |
---|
607 | return $xml_array; |
---|
608 | } |
---|
609 | |
---|
610 | /** |
---|
611 | * xml -> tableau |
---|
612 | * @param string $u |
---|
613 | * @return array |
---|
614 | * from cerdic et marcimat sur https://contrib.spip.net/Les-Iterateurs-pour-SPIP-2-1#forum457898 |
---|
615 | */ |
---|
616 | |
---|
617 | function inc_simplexml_to_array_dist($u){ |
---|
618 | return array('root'=>@xmlObjToArr(simplexml_load_string($u))); |
---|
619 | } |
---|
620 | |
---|
621 | // http://www.php.net/manual/pt_BR/book.simplexml.php#108688 (17 mai 2012) |
---|
622 | function xmlObjToArr($obj) { |
---|
623 | # Cette fonction getDocNamespaces est tres gourmande sur de gros fichiers |
---|
624 | # $namespace = $obj->getDocNamespaces(true); |
---|
625 | |
---|
626 | $namespace[NULL] = NULL; |
---|
627 | |
---|
628 | $children = array(); |
---|
629 | $attributes = array(); |
---|
630 | $name = strtolower((string)$obj->getName()); |
---|
631 | |
---|
632 | $text = trim((string)$obj); |
---|
633 | if( strlen($text) <= 0 ) { |
---|
634 | $text = NULL; |
---|
635 | } |
---|
636 | |
---|
637 | // get info for all namespaces |
---|
638 | if(is_object($obj)) { |
---|
639 | foreach( $namespace as $ns=>$nsUrl ) { |
---|
640 | // atributes |
---|
641 | $objAttributes = $obj->attributes($ns, true); |
---|
642 | foreach( $objAttributes as $attributeName => $attributeValue ) { |
---|
643 | $attribName = strtolower(trim((string)$attributeName)); |
---|
644 | $attribVal = trim((string)$attributeValue); |
---|
645 | if (!empty($ns)) { |
---|
646 | $attribName = $ns . ':' . $attribName; |
---|
647 | } |
---|
648 | $attributes[$attribName] = $attribVal; |
---|
649 | } |
---|
650 | |
---|
651 | // children |
---|
652 | $objChildren = $obj->children($ns, true); |
---|
653 | foreach( $objChildren as $childName=>$child ) { |
---|
654 | $childName = strtolower((string)$childName); |
---|
655 | if( !empty($ns) ) { |
---|
656 | $childName = $ns.':'.$childName; |
---|
657 | } |
---|
658 | $children[$childName][] = xmlObjToArr($child); |
---|
659 | } |
---|
660 | } |
---|
661 | } |
---|
662 | |
---|
663 | return array( |
---|
664 | 'name'=>$name, |
---|
665 | 'text'=>$text, |
---|
666 | 'attributes'=>$attributes, |
---|
667 | 'children'=>$children |
---|
668 | ); |
---|
669 | } |
---|
670 | ?> |
---|