/** * Parse une chaine XML donnée et retourne un tableau. * * @see spip_xml_aplatit() pour l'inverse * * @param string $texte * Texte XML * @param bool $strict * true pour râler si une balise n'est pas correctement fermée, false sinon. * @param bool $clean ? * @param int $profondeur ? * @return array|bool * - array : l'arbre XML, * - false si l'arbre xml ne peut être créé ou est vide **/ function spip_xml_parse(&$texte, $strict = true, $clean = true, $profondeur = -1) { $out = array(); // enlever les commentaires $charset = 'AUTO'; if ($clean === true) { if (preg_match(",<\\?xml\\s(.*?)encoding=['\"]?(.*?)['\"]?(\\s(.*))?\\?>,im", $texte, $regs)) { $charset = $regs[2]; } $texte = preg_replace(',<!--(.*?)-->,is', '', $texte); $texte = preg_replace(',<\\?(.*?)\\?>,is', '', $texte); include_spip('inc/charsets'); $clean = $charset; //$texte = importer_charset($texte,$charset); } if (is_string($clean)) { $charset = $clean; } $txt = $texte; // tant qu'il y a des tags $chars = preg_split(_SPIP_XML_TAG_SPLIT, $txt, 2, PREG_SPLIT_DELIM_CAPTURE); while (count($chars) >= 2) { // tag ouvrant //$chars = preg_split("{<([^>]*?)>}s",$txt,2,PREG_SPLIT_DELIM_CAPTURE); // $before doit etre vide ou des espaces uniquements! $before = trim($chars[0]); if (strlen($before) > 0) { return importer_charset($texte, $charset); } //$texte; // before non vide, donc on est dans du texte $tag = rtrim($chars[1]); $txt = $chars[2]; if (strncmp($tag, '![CDATA[', 8) == 0) { return importer_charset($texte, $charset); } //$texte; if (substr($tag, -1) == '/') { // self closing tag $tag = rtrim(substr($tag, 0, strlen($tag) - 1)); $out[$tag][] = ""; } else { $closing_tag = preg_split(",\\s|\t|\n|\r,", trim($tag)); $closing_tag = reset($closing_tag); // tag fermant $ncclos = strlen("</{$closing_tag}>"); $p = strpos($txt, "</{$closing_tag}>"); if ($p !== false and strpos($txt, "<") < $p) { $nclose = 0; $nopen = 0; $d = 0; while ($p !== false and $morceau = substr($txt, $d, $p - $d) and ($nopen += preg_match_all("{<" . preg_quote($closing_tag) . "(\\s*>|\\s[^>]*[^/>]>)}is", $morceau, $matches, PREG_SET_ORDER)) > $nclose) { $nclose++; $d = $p + $ncclos; $p = strpos($txt, "</{$closing_tag}>", $d); } } if ($p === false) { if ($strict) { $out[$tag][] = "erreur : tag fermant {$tag} manquant::{$txt}"; return $out; } else { return importer_charset($texte, $charset); } //$texte // un tag qui constitue du texte a reporter dans $before } $content = substr($txt, 0, $p); $txt = substr($txt, $p + $ncclos); if ($profondeur == 0 or strpos($content, "<") === false) { $out[$tag][] = importer_charset($content, $charset); } else { $out[$tag][] = spip_xml_parse($content, $strict, $clean, $profondeur - 1); } } $chars = preg_split(_SPIP_XML_TAG_SPLIT, $txt, 2, PREG_SPLIT_DELIM_CAPTURE); } if (count($out) && strlen(trim($txt)) == 0) { return $out; } else { return importer_charset($texte, $charset); } //$texte; }
function plugins_infos_plugin($desc, $plug = '', $dir_plugins = _DIR_PLUGINS) { include_spip('inc/xml'); $arbre = spip_xml_parse($desc); $verifie_conformite = charger_fonction('verifie_conformite', 'plugins'); $verifie_conformite($plug, $arbre, $dir_plugins); include_spip('inc/charsets'); // On renvoie la DTD utilisee $ret['dtd'] = "plugin"; if (isset($arbre['categorie'])) { $ret['categorie'] = trim(spip_xml_aplatit($arbre['categorie'])); } if (isset($arbre['nom'])) { $ret['nom'] = charset2unicode(spip_xml_aplatit($arbre['nom'])); } if (isset($arbre['icon'])) { $ret['logo'] = trim(spip_xml_aplatit($arbre['icon'])); } if (isset($arbre['auteur'])) { $ret['auteur'][] = trim(spip_xml_aplatit($arbre['auteur'])); } // garder le 1er niveau en tableau mais traiter le multi possible if (isset($arbre['licence'])) { $ret['licence'][] = trim(spip_xml_aplatit($arbre['licence'])); } if (isset($arbre['version'])) { $ret['version'] = trim(spip_xml_aplatit($arbre['version'])); } if (isset($arbre['version_base'])) { $ret['schema'] = trim(spip_xml_aplatit($arbre['version_base'])); } if (isset($arbre['etat'])) { $ret['etat'] = trim(spip_xml_aplatit($arbre['etat'])); } $ret['description'] = $ret['slogan'] = ""; if (isset($arbre['slogan'])) { $ret['slogan'] = trim(spip_xml_aplatit($arbre['slogan'])); } if (isset($arbre['description'])) { $ret['description'] = trim(spip_xml_aplatit($arbre['description'])); } if (isset($arbre['lien'])) { $ret['documentation'] = trim(join(' ', $arbre['lien'])); if ($ret['documentation']) { // le lien de doc doit etre une url et c'est tout if (!preg_match(',^https?://,iS', $ret['documentation'])) { $ret['documentation'] = ""; } } } if (isset($arbre['options'])) { $ret['options'] = $arbre['options']; } if (isset($arbre['fonctions'])) { $ret['fonctions'] = $arbre['fonctions']; } if (isset($arbre['prefix'][0])) { $ret['prefix'] = trim(array_pop($arbre['prefix'])); } if (isset($arbre['install'])) { $ret['install'] = $arbre['install']; } if (isset($arbre['meta'])) { $ret['meta'] = trim(spip_xml_aplatit($arbre['meta'])); } $necessite = info_plugin_normalise_necessite($arbre['necessite']); $ret['compatibilite'] = isset($necessite['compatible']) ? $necessite['compatible'] : ''; $ret['necessite'] = $necessite['necessite']; $ret['lib'] = $necessite['lib']; $ret['utilise'] = info_plugin_normalise_utilise($arbre['utilise']); $ret['procure'] = info_plugin_normalise_procure($arbre['procure']); $ret['chemin'] = info_plugin_normalise_chemin($arbre['path']); if (isset($arbre['pipeline'])) { $ret['pipeline'] = $arbre['pipeline']; } $extraire_boutons = charger_fonction('extraire_boutons', 'plugins'); $les_boutons = $extraire_boutons($arbre); $ret['menu'] = $les_boutons['bouton']; $ret['onglet'] = $les_boutons['onglet']; $ret['traduire'] = $arbre['traduire']; if (isset($arbre['config'])) { $ret['config'] = spip_xml_aplatit($arbre['config']); } if (isset($arbre['noisette'])) { $ret['noisette'] = $arbre['noisette']; } if (isset($arbre['erreur'])) { $ret['erreur'] = $arbre['erreur']; if ($plug) { spip_log("infos_plugin {$plug} " . @join(' ', $arbre['erreur'])); } } return $ret; }
/** * Phrase le contenu d'une balise <traductions> en un tableau plus * facilement utilisable * * @param string $contenu * Contenu XML de la balise <traductions> * @return array * Tableau complexe avec pour index les noms des modules de langue et pour * valeur leur description. Chaque description contient dedans 3 index : * - reference : la langue de référence * - gestionnaire : quel logiciel à servi à gérer les traductions * - langues : tableau classé par langue puis par traducteurs, qui indique * l'ensemble des traducteurs pour chacune des langues présentes */ function svp_phraser_traductions($contenu) { $traductions = array(); if (is_array($arbre = spip_xml_parse($contenu))) { foreach ($arbre as $_tag => $_langues) { // On commence par les balises <traduction> et leurs attributs list($tag, $attributs_traduction) = spip_xml_decompose_tag($_tag); $traductions[$attributs_traduction['module']]['reference'] = $attributs_traduction['reference']; $traductions[$attributs_traduction['module']]['gestionnaire'] = isset($attributs_traduction['gestionnaire']) ? $attributs_traduction['gestionnaire'] : ''; // On continue par les balises <langue> qui donnent le code en attribut // et les balises <traducteur> qui donnent uniquement le nom en attribut if (is_array($_langues[0])) { foreach ($_langues[0] as $_tag => $_traducteurs) { list($tag, $attributs_langue) = spip_xml_decompose_tag($_tag); $traducteurs = array(); if (is_array($_traducteurs[0])) { foreach ($_traducteurs[0] as $_tag => $_vide) { list($tag, $attributs_traducteur) = spip_xml_decompose_tag($_tag); $traducteurs[] = $attributs_traducteur; } } $traductions[$attributs_traduction['module']]['langues'][$attributs_langue['code']] = $traducteurs; } } } } return $traductions; }